Communitygithub.com

编码规范

跨项目基线编码约定,涵盖命名、可读性、不变性和代码质量审查。对于特定框架的模式,请使用详细的前端或后端技能。当审查代码质量或命名且无适用的特定框架技能时使用。

编码规范 是什么?

该技能提供了跨项目共享的基线编码约定,作为基础层而非详细的框架指南。它强调可读性、KISS、DRY 和 YAGNI 原则,以及不可变性模式、类型安全和错误处理等核心实践。对于 React、后端架构或 API 设计等特定领域,应使用更专门的技能(如 `frontend-patterns` 或 `backend-patterns`)。该技能通过详细的示例、反例和最佳实践,指导开发者编写清晰、可维护的代码,涵盖从变量命名到文件组织、测试和性能优化的各个方面。它适用于新项目启动、代码审查、重构和贡献者入职等场景。

兼容平台~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/coding-standards

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

编码规范与最佳实践

适用于所有项目的基线编码约定。

此技能是共有的基础,而非详细的框架指南。

  • 使用 frontend-patterns 处理 React、状态、表单、渲染和 UI 架构。
  • 使用 backend-patterns 或 api-design 处理仓库/服务层、端点设计、验证和服务器特定问题。
  • 当需要最简短的可复用规则层而非完整的技能指南时,使用 rules/common/coding-style.md。

何时激活

  • 启动新项目或模块
  • 审查代码质量和可维护性
  • 重构现有代码以遵循约定
  • 强制命名、格式化或结构一致性
  • 设置 linting、格式化或类型检查规则
  • 让新贡献者了解编码约定

范围边界

激活此技能以处理:

  • 描述性命名
  • 默认不可变性
  • 可读性、KISS、DRY 和 YAGNI 原则的强制
  • 错误处理期望和代码异味审查

不要将此技能作为以下方面的主要来源:

  • React 组合、hooks 或渲染模式
  • 后端架构、API 设计或数据库分层
  • 当更具体的 ECC 技能已存在时,针对特定领域的框架指南

代码质量原则

1. 可读性优先

  • 代码被阅读的次数远多于编写的次数
  • 变量和函数名称清晰
  • 优先自文档化代码而非注释
  • 一致的格式化

2. KISS(保持简单和直接)

  • 使用能工作的最简单的解决方案
  • 避免过度工程化
  • 不进行过早优化
  • 易于理解 > 巧妙代码

3. DRY(不要重复自己)

  • 将公共逻辑提取为函数
  • 创建可复用的组件
  • 跨模块共享工具函数
  • 避免复制粘贴编程

4. YAGNI(你不需要它)

  • 不在需要之前构建功能
  • 避免投机性通用性
  • 只在需要时增加复杂性
  • 从简单开始,需要时重构

TypeScript/JavaScript 标准

变量命名

// 通过:好的:描述性名称
const marketSearchQuery = 'election'
const isUserAuthenticated = true
const totalRevenue = 1000

// 失败:差的:不清晰的名称
const q = 'election'
const flag = true
const x = 1000

函数命名

// 通过:好的:动词-名词模式
async function fetchMarketData(marketId: string) { }
function calculateSimilarity(a: number[], b: number[]) { }
function isValidEmail(email: string): boolean { }

// 失败:差的:不清晰或纯名词
async function market(id: string) { }
function similarity(a, b) { }
function email(e) { }

不可变性模式(关键)

// 通过:总是使用展开运算符
const updatedUser = {
  ...user,
  name: 'New Name'
}

const updatedArray = [...items, newItem]

// 失败:绝不直接修改
user.name = 'New Name'  // 不好的
items.push(newItem)     // 不好的

错误处理

// 通过:好的:全面的错误处理
async function fetchData(url: string) {
  try {
    const response = await fetch(url)

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`)
    }

    return await response.json()
  } catch (error) {
    console.error('Fetch failed:', error)
    throw new Error('Failed to fetch data')
  }
}

// 失败:差的:没有错误处理
async function fetchData(url) {
  const response = await fetch(url)
  return response.json()
}

Async/Await 最佳实践

// 通过:好的:可能时并行执行
const [users, markets, stats] = await Promise.all([
  fetchUsers(),
  fetchMarkets(),
  fetchStats()
])

// 失败:差的:非必要时顺序执行
const users = await fetchUsers()
const markets = await fetchMarkets()
const stats = await fetchStats()

类型安全

// 通过:好的:合适的类型
interface Market {
  id: string
  name: string
  status: 'active' | 'resolved' | 'closed'
  created_at: Date
}

function getMarket(id: string): Promise<Market> {
  // 实现
}

// 失败:差的:使用 'any'
function getMarket(id: any): Promise<any> {
  // 实现
}

React 最佳实践

组件结构

// 通过:好的:带有类型的函数式组件
interface ButtonProps {
  children: React.ReactNode
  onClick: () => void
  disabled?: boolean
  variant?: 'primary' | 'secondary'
}

export function Button({
  children,
  onClick,
  disabled = false,
  variant = 'primary'
}: ButtonProps) {
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      className={`btn btn-${variant}`}
    >
      {children}
    </button>
  )
}

// 失败:差的:没有类型,结构不清晰
export function Button(props) {
  return <button onClick={props.onClick}>{props.children}</button>
}

自定义 Hooks

// 通过:好的:可复用的自定义 hook
export function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value)

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value)
    }, delay)

    return () => clearTimeout(handler)
  }, [value, delay])

  return debouncedValue
}

// 用法
const debouncedQuery = useDebounce(searchQuery, 500)

状态管理

// 通过:好的:正确的状态更新
const [count, setCount] = useState(0)

// 基于先前状态使用函数式更新
setCount(prev => prev + 1)

// 失败:差的:直接引用状态
setCount(count + 1)  // 在异步场景中可能过时

条件渲染

// 通过:好的:清晰的条件渲染
{isLoading && <Spinner />}
{error && <ErrorMessage error={error} />}
{data && <DataDisplay data={data} />}

// 失败:差的:三元表达式地狱
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}

API 设计标准

REST API 约定

GET    /api/markets              # 列出所有市场
GET    /api/markets/:id          # 获取特定市场
POST   /api/markets              # 创建新市场
PUT    /api/markets/:id          # 更新市场(完整)
PATCH  /api/markets/:id          # 更新市场(部分)
DELETE /api/markets/:id          # 删除市场

# 筛选的查询参数
GET /api/markets?status=active&limit=10&offset=0

响应格式

// 通过:好的:一致的响应结构
interface ApiResponse<T> {
  success: boolean
  data?: T
  error?: string
  meta?: {
    total: number
    page: number
    limit: number
  }
}

// 成功响应
return NextResponse.json({
  success: true,
  data: markets,
  meta: { total: 100, page: 1, limit: 10 }
})

// 错误响应
return NextResponse.json({
  success: false,
  error: 'Invalid request'
}, { status: 400 })

输入验证

import { z } from 'zod'

// 通过:好的:模式验证
const CreateMarketSchema = z.object({
  name: z.string().min(1).max(200),
  description: z.string().min(1).max(2000),
  endDate: z.string().datetime(),
  categories: z.array(z.string()).min(1)
})

export async function POST(request: Request) {
  const body = await request.json()

  try {
    const validated = CreateMarketSchema.parse(body)
    // 使用验证后的数据继续处理
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json({
        success: false,
        error: 'Validation failed',
        details: error.issues
      }, { status: 400 })
    }
  }
}

文件组织

项目结构

src/
├── app/                    # Next.js App Router
│   ├── api/               # API 路由
│   ├── markets/           # 市场页面
│   └── (auth)/           # 认证页面(路由组)
├── components/            # React 组件
│   ├── ui/               # 通用 UI 组件
│   ├── forms/            # 表单组件
│   └── layouts/          # 布局组件
├── hooks/                # 自定义 React hooks
├── lib/                  # 工具和配置
│   ├── api/             # API 客户端
│   ├── utils/           # 辅助函数
│   └── constants/       # 常量
├── types/                # TypeScript 类型
└── styles/              # 全局样式

文件命名

components/Button.tsx          # 组件使用 PascalCase
hooks/useAuth.ts              # 使用 'use' 前缀的 camelCase
lib/formatDate.ts             # 工具函数使用 camelCase
types/market.types.ts         # 使用 .types 后缀的 camelCase

注释与文档

何时注释

// 通过:好的:解释为什么,而不是什么
// 使用指数退避避免在中断期间淹没 API
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)

// 这里为了大数组的性能而故意使用修改
items.push(newItem)

// 失败:差的:显而易见的事
// 计数器加 1
count++

// 将名称设为用户名称
name = user.name

公共 API 的 JSDoc

/**
 * 使用语义相似性搜索市场。
 *
 * @param query - 自然语言搜索查询
 * @param limit - 最大结果数(默认:10)
 * @returns 按相似度分数排序的市场数组
 * @throws {Error} 如果 OpenAI API 失败或 Redis 不可用
 *
 * @example
 * ```typescript
 * const results = await searchMarkets('election', 5)
 * console.log(results[0].name) // "Trump vs Biden"
 * ```
 */
export async function searchMarkets(
  query: string,
  limit: number = 10
): Promise<Market[]> {
  // 实现
}

性能最佳实践

记忆化

import { useMemo, useCallback } from 'react'

// 通过:好的:记忆化昂贵的计算
// 复制后再排序 - Array.prototype.sort 会修改原数组
const sortedMarkets = useMemo(() => {
  return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets])

// 通过:好的:记忆化回调
const handleSearch = useCallback((query: string) => {
  setSearchQuery(query)
}, [])

懒加载

import { lazy, Suspense } from 'react'

// 通过:好的:懒加载重量级组件
const HeavyChart = lazy(() => import('./HeavyChart'))

export function Dashboard() {
  return (
    <Suspense fallback={<Spinner />}>
      <HeavyChart />
    </Suspense>
  )
}

数据库查询

// 通过:好的:只选择需要的列
const { data } = await supabase
  .from('markets')
  .select('id, name, status')
  .limit(10)

// 失败:差的:选择所有
const { data } = await supabase
  .from('markets')
  .select('*')

测试标准

测试结构(AAA 模式)

test('correctly calculates similarity', () => {
  // Arrange(准备)
  const vector1 = [1, 0, 0]
  const vector2 = [0, 1, 0]

  // Act(执行)
  const similarity = calculateCosineSimilarity(vector1, vector2)

  // Assert(断言)
  expect(similarity).toBe(0)
})

测试命名

// 通过:好的:描述性的测试名称
test('returns empty array when no markets match query', () => { })
test('throws error when OpenAI API key is missing', () => { })
test('falls back to substring search when Redis unavailable', () => { })

// 失败:差的:模糊的测试名称
test('works', () => { })
test('test search', () => { })

代码异味检测

注意这些反模式:

1. 长函数

// 失败:差的:函数超过 50 行
function processMarketData() {
  // 100 行代码
}

// 通过:好的:拆分为更小的函数
function processMarketData() {
  const validated = validateData()
  const transformed = transformData(validated)
  return saveData(transformed)
}

2. 深层嵌套

// 失败:差的:5 层以上的嵌套
if (user) {
  if (user.isAdmin) {
    if (market) {
      if (market.isActive) {
        if (hasPermission) {
          // 做某事
        }
      }
    }
  }
}

// 通过:好的:提前返回
if (!user) return
if (!user.isAdmin) return
if (!market) return
if (!market.isActive) return
if (!hasPermission) return

// 做某事

3. 魔法数字

// 失败:差的:未解释的数字
if (retryCount > 3) { }
setTimeout(callback, 500)

// 通过:好的:命名的常量
const MAX_RETRIES = 3
const DEBOUNCE_DELAY_MS = 500

if (retryCount > MAX_RETRIES) { }
setTimeout(callback, DEBOUNCE_DELAY_MS)

请记住:代码质量不可妥协。清晰、可维护的代码有助于快速开发和自信的重构。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

相关技能