news 2026/9/7 15:20:18

ECC coding-standards 技能详解:TypeScript、React 与 API 设计的跨项目编码规范

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ECC coding-standards 技能详解:TypeScript、React 与 API 设计的跨项目编码规范

ECC coding-standards 技能详解:TypeScript、React 与 API 设计的跨项目编码规范

【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC

ECC(The agent harness performance optimization system)将一套通用的 TypeScript/JavaScript、React 与 Node.js 编码规范封装为 Kiro 平台的按需技能coding-standards,安装到项目后可通过聊天/菜单直接调用,用于代码审查、新模块起步和团队规范落地。本文完整拆解该技能的规范体系——四大质量原则、命名与不可变性准则、React 与 API 设计标准、性能与测试规范、代码坏味道检测清单——并结合 ECC 仓库中的规则层文件与 ESLint 配置,说明这些规范如何在工程中真正被约束和验证。读完后,你既能把这份规范直接套用到自己的 TS/React 项目中,也能理解它在 ECC 分层体系中的定位与配套落地手段。

一、coding-standards 是什么:Kiro 技能机制与激活时机

该技能定义在.kiro/skills/coding-standards/SKILL.md,文件以 YAML frontmatter 声明元数据:

--- name: coding-standards description: > Universal coding standards, best practices, and patterns for TypeScript, JavaScript, React, and Node.js development. metadata: origin: ECC ---

根据.kiro/README.md的说明,.kiro/skills/目录下共安装了 43 个技能,它们是“可经由聊天/菜单按需调用的工作流”(Skills are on-demand workflows invocable via the/menu in chat)。每个技能都是一个包含SKILL.md的目录,frontmatter 中的name决定菜单中的可调用名称,description决定其语义边界。因此开发者在 Kiro 中输入/并选择coding-standards,即可让 Agent 以这份规范为审查/编码基准开展工作。

技能文档同时明确了激活场景(When to Activate),即这份规范适用于以下六类工作:

  • 启动新项目或新模块
  • 以质量与可维护性为目标审查代码
  • 重构既有代码以符合约定
  • 强制执行命名、格式或结构一致性
  • 配置 lint、格式化或类型检查规则
  • 帮助新贡献者了解编码约定

需要注意技能的范围定位。ECC 主仓中对应的基线版技能skills/coding-standards/SKILL.md在 frontmatter 之后额外给出了明确的边界说明:它是“共享的底线,而非详细框架手册”(the shared floor, not the detailed framework playbook)——

  • React 组合、hooks、渲染与 UI 架构问题应使用frontend-patterns
  • 后端架构、API 设计、数据库分层应使用backend-patternsapi-design
  • 只需要最短可复用规则层时,应参考rules/common/coding-style.md

这种“技能管完整流程、规则管最小约束”的分层设计,是 ECC 规范体系的一个重要特征,后文第四节会结合具体文件展开。

二、代码质量四原则:Readability、KISS、DRY、YAGNI

技能的第一部分确立了四条贯穿全部后续规范的质量原则,理解它们是读懂其余条款的钥匙。

1. Readability First(可读性优先)

  • 代码被阅读的次数远多于被编写的次数
  • 变量与函数命名必须清晰
  • 自解释代码优于注释
  • 保持格式一致

2. KISS(Keep It Simple, Stupid)

  • 采用能工作的最简单方案
  • 避免过度设计
  • 不做过早优化
  • 易理解的代码 > 炫技的代码

3. DRY(Don't Repeat Yourself)

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

4. YAGNI(You Aren't Gonna Need It)

  • 不提前构建尚不需要的功能
  • 避免臆测性泛化(speculative generality)
  • 仅在确有需求时引入复杂度
  • 从简单开始,必要时再重构

ECC 的规则层文件rules/common/coding-style.md将这同一套原则压缩成了更短的可复用表述,例如 DRY 条目补充了一条实践判断标准:“Introduce abstractions when repetition is real, not speculative”(当重复是真实存在的而非臆测时才引入抽象),YAGNI 条目则强调 “Start simple, then refactor when the pressure is real”(从简单开始,等压力真实到来时再重构)。技能版讲“何时激活什么行为”,规则版给“最短可执行判据”,两者互为表里。

三、TypeScript/JavaScript 规范:命名、不可变性、错误处理与类型安全

这是技能的核心章节,全部采用 PASS/FAIL 对照代码示例,可直接作为代码审查清单使用。

3.1 变量命名:描述性名称

// PASS: GOOD: Descriptive names const marketSearchQuery = 'election' const isUserAuthenticated = true const totalRevenue = 1000 // FAIL: BAD: Unclear names const q = 'election' const flag = true const x = 1000

要点:布尔变量使用is/has/should/can前缀表达语义(isUserAuthenticated),名称应承载业务含义而非缩写。

3.2 函数命名:动词-名词模式

// PASS: GOOD: Verb-noun pattern async function fetchMarketData(marketId: string) { } function calculateSimilarity(a: number[], b: number[]) { } function isValidEmail(email: string): boolean { } // FAIL: BAD: Unclear or noun-only async function market(id: string) { } function similarity(a, b) { } function email(e) { }

纯名词(marketemail)无法表达函数“做什么”,应统一采用fetchMarketDatacalculateSimilarity这类动词-名词结构,并在参数与返回值上补全类型。

3.3 不可变性模式(技能标记为 CRITICAL)

// PASS: ALWAYS use spread operator const updatedUser = { ...user, name: 'New Name' } const updatedArray = [...items, newItem] // FAIL: NEVER mutate directly user.name = 'New Name' // BAD items.push(newItem) // BAD

这是技能中唯一被标注为 “CRITICAL” 的条目。ECC 的规则层对此给出了统一的伪代码判据(见rules/common/coding-style.md):

WRONG: modify(original, field, value) → changes original in-place CORRECT: update(original, field, value) → returns new copy with change

其理由写明:不可变数据可防止隐藏副作用、让调试更容易、并支持安全的并发。值得注意的是,技能允许有意识地违反这一默认值,但必须在注释中说明原因——注释规范章节(第六节)的示例正是如此:// Deliberately using mutation here for performance with large arrays配合items.push(newItem)。规则是默认值,带理由的例外优于无理由的遵守。

3.4 错误处理:全面而非缺失

// PASS: GOOD: Comprehensive error handling 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') } } // FAIL: BAD: No error handling async function fetchData(url) { const response = await fetch(url) return response.json() }

模式拆解:先用response.ok拦截 HTTP 层失败并抛出自带状态码的明确错误,再在catch中记录详细上下文(console.error带原始 error 对象)并向上传播精简后的错误消息。这与规则层“错误处理”章节的四条要求一一对应:每一层显式处理、面向 UI 的代码提供用户友好消息、服务端记录详细上下文、绝不静默吞错(Never silently swallow errors)。

3.5 Async/Await:能并行就并行

// PASS: GOOD: Parallel execution when possible const [users, markets, stats] = await Promise.all([ fetchUsers(), fetchMarkets(), fetchStats() ]) // FAIL: BAD: Sequential when unnecessary const users = await fetchUsers() const markets = await fetchMarkets() const stats = await fetchStats()

无依赖关系的多个异步调用应使用Promise.all并发执行;串行await会把总耗时累加为各请求之和。

3.6 类型安全:拒绝any

// PASS: GOOD: Proper types interface Market { id: string name: string status: 'active' | 'resolved' | 'closed' created_at: Date } function getMarket(id: string): Promise<Market> { // Implementation } // FAIL: BAD: Using 'any' function getMarket(id: any): Promise<any> { // Implementation }

示例中status字段使用字符串字面量联合('active' | 'resolved' | 'closed')而非enum,与 ECC 的 TypeScript 规则层rules/typescript/coding-style.md的建议一致:对象形状用interface(可被扩展/实现),联合、交叉、元组与工具类型用type,并优先字符串字面量联合代替enum。该规则文件还进一步给出any的替代路径——对外部/不可信输入使用unknown再安全收窄:

// CORRECT: unknown forces safe narrowing function getErrorMessage(error: unknown): string { if (error instanceof Error) { return error.message } return 'Unexpected error' }

该规则文件顶部带有pathsfrontmatter(**/*.ts**/*.tsx**/*.js**/*.jsx),说明 ECC 的规则按 glob 路径条件注入——这正是“规则管最小约束、按文件类型生效”的实现方式。

四、React 最佳实践:组件、Hooks、状态与条件渲染

4.1 组件结构:函数式组件 + 显式 Props 类型

// PASS: GOOD: Functional component with types 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> ) } // FAIL: BAD: No types, unclear structure export function Button(props) { return <button onClick={props.onClick}>{props.children}</button> }

示例涵盖了技能隐含的组件四要素:命名interface定义 Props(而非React.FC,规则层明确 “Do not useReact.FCunless there is a specific reason”)、解构 + 默认值参数、回调属性显式类型、variant用字面量联合收敛取值范围。

4.2 自定义 Hooks:可复用的防抖示例

// PASS: GOOD: Reusable custom 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 } // Usage const debouncedQuery = useDebounce(searchQuery, 500)

实现要点:泛型<T>使 hook 适用于任意值类型;useEffect依赖[value, delay];清理函数clearTimeout保证值变化时旧定时器不残留——这是手写防抖 hook 最容易漏掉的一环。

4.3 状态管理:函数式更新

// PASS: GOOD: Proper state updates const [count, setCount] = useState(0) // Functional update for state based on previous state setCount(prev => prev + 1) // FAIL: BAD: Direct state reference setCount(count + 1) // Can be stale in async scenarios

setCount(count + 1)读取的是当前渲染周期的闭包值,在事件循环、异步回调或连续触发场景下可能拿到过期状态;setCount(prev => prev + 1)始终基于最新状态计算,应作为默认写法。

4.4 条件渲染:拒绝三目嵌套地狱

// PASS: GOOD: Clear conditional rendering {isLoading && <Spinner />} {error && <ErrorMessage error={error} />} {data && <DataDisplay data={data} />} // FAIL: BAD: Ternary hell {isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}

短路与并列布尔表达式比多层嵌套三目更易读、更易局部修改;isLoading && <Spinner />这类写法在三个状态互斥时同样成立(假值不渲染任何有意义的东西)。

五、API 设计标准:REST 约定、统一响应格式与 Zod 校验

5.1 REST 资源路由约定

GET /api/markets # List all markets GET /api/markets/:id # Get specific market POST /api/markets # Create new market PUT /api/markets/:id # Update market (full) PATCH /api/markets/:id # Update market (partial) DELETE /api/markets/:id # Delete market # Query parameters for filtering GET /api/markets?status=active&limit=10&offset=0

资源用名词复数、全量/部分更新分别用PUT/PATCH、过滤与分页走查询参数(status/limit/offset)——这是与响应结构中meta.total/page/limit字段相互呼应的分页契约。

5.2 统一响应结构

// PASS: GOOD: Consistent response structure interface ApiResponse<T> { success: boolean data?: T error?: string meta?: { total: number page: number limit: number } } // Success response return NextResponse.json({ success: true, data: markets, meta: { total: 100, page: 1, limit: 10 } }) // Error response return NextResponse.json({ success: false, error: 'Invalid request' }, { status: 400 })

泛型ApiResponse<T>让每个端点复用同一信封:成功时success: true携带data(分页接口附带meta),失败时success: false携带error字符串并配正确的 HTTP 状态码。前端因此只需一套解包逻辑即可处理所有端点。

5.3 输入校验:Zod Schema 在系统边界拦截

import { z } from 'zod' // PASS: GOOD: Schema validation 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) // Proceed with validated data } catch (error) { if (error instanceof z.ZodError) { return NextResponse.json({ success: false, error: 'Validation failed', details: error.errors }, { status: 400 } } } }

要点:Schema 即接口契约(长度限制min/max、ISO 日期校验z.string().datetime()、非空数组min(1));parse失败时返回400并回传校验详情,让调用方一次修全。这一点与规则层“输入校验”章节的边界原则直接对应:“ALWAYS validate at system boundaries”“Never trust external data (API responses, user input, file content)”——外部数据在边界处校验失败要快速失败(Fail fast)并给出清晰错误消息。一个小的版本差异值得留意:ECC 主仓的基线版技能skills/coding-standards/SKILL.md在同一段示例中回传的是error.issues(较新 Zod 版本的属性名),而 Kiro 版使用error.errors——实际项目中以所用 Zod 版本的 API 为准即可,两者语义相同。

六、文件组织与命名约定

6.1 项目结构(以 Next.js App Router 为例)

src/ ├── app/ # Next.js App Router │ ├── api/ # API routes │ ├── markets/ # Market pages │ └── (auth)/ # Auth pages (route groups) ├── components/ # React components │ ├── ui/ # Generic UI components │ ├── forms/ # Form components │ └── layouts/ # Layout components ├── hooks/ # Custom React hooks ├── lib/ # Utilities and configs │ ├── api/ # API clients │ ├── utils/ # Helper functions │ └── constants/ # Constants ├── types/ # TypeScript types └── styles/ # Global styles

结构逻辑是按职责分层:app/只放路由(含(auth)这类不产生 URL 段的 route group),components/再按 ui/forms/layouts 细分子类,lib/按 api/utils/constants 归拢基础设施,types/集中共享类型。

6.2 文件命名规则

components/Button.tsx # PascalCase for components hooks/useAuth.ts # camelCase with 'use' prefix lib/formatDate.ts # camelCase for utilities types/market.types.ts # camelCase with .types suffix

组件文件名与组件名同形(PascalCase)便于检索与自动导入;hook 文件以use前缀保持与函数命名一致;纯类型文件用.types.ts后缀区分“只含类型”与“含实现”的文件。

规则层rules/common/coding-style.md对“文件多大算大”给出了量化标准,可作为上述结构的补充判据:

  • MANY SMALL FILES > FEW LARGE FILES:高内聚低耦合
  • 源文件典型规模 200–400 行,800 行为可维护性的软上限(测试、生成与 vendored 文件因职责所需可豁免)
  • 按 feature/domain 组织,而非按 type 组织

七、注释与文档:解释 WHY 而非 WHAT

7.1 何时该写注释

// PASS: GOOD: Explain WHY, not WHAT // Use exponential backoff to avoid overwhelming the API during outages const delay = Math.min(1000 * Math.pow(2, retryCount), 30000) // Deliberately using mutation here for performance with large arrays items.push(newItem) // FAIL: BAD: Stating the obvious // Increment counter by 1 count++ // Set name to user's name name = user.name

两条正例展示了注释的合法用途:一是解释非显而易见的设计动机(指数退避避免故障期压垮 API,并内嵌了 30 秒上限Math.min(..., 30000)),二是为“故意违反默认规则”(第三节中的不可变性)提供豁免理由。反例则是复述代码字面行为的无效注释。

7.2 公共 API 的 JSDoc

/** * Searches markets using semantic similarity. * * @param query - Natural language search query * @param limit - Maximum number of results (default: 10) * @returns Array of markets sorted by similarity score * @throws {Error} If OpenAI API fails or Redis unavailable * * @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[]> { // Implementation }

公共函数的 JSDoc 模板包含五个要素:功能一句话、每个@param的含义与默认值、@returns的排序/形状约定、@throws的失败条件、@example可运行示例。规则层补充了一条面向纯 JS 项目的实践:在.js/.jsx文件中当 TypeScript 迁移不现实时,用 JSDoc 表达类型且必须与运行时行为保持一致(“Keep JSDoc aligned with runtime behavior”)。

八、性能最佳实践:记忆化、懒加载与查询裁剪

8.1 记忆化(Memoization)

import { useMemo, useCallback } from 'react' // PASS: GOOD: Memoize expensive computations // Copy before sorting - Array.prototype.sort mutates in place const sortedMarkets = useMemo(() => { return [...markets].sort((a, b) => b.volume - a.volume) }, [markets]) // PASS: GOOD: Memoize callbacks const handleSearch = useCallback((query: string) => { setSearchQuery(query) }, [])

注意[...markets].sort(...)这一细节:Array.prototype.sort原地修改数组,直接对状态数组排序既违反不可变性原则(第三节 CRITICAL 条目)又会触发难以追踪的状态污染,因此注释先声明 “Copy before sorting” 再展开拷贝。这展示了技能内部各章节的交叉引用——性能优化代码同样受不可变性约束。

8.2 懒加载重型组件

import { lazy, Suspense } from 'react' // PASS: GOOD: Lazy load heavy components const HeavyChart = lazy(() => import('./HeavyChart')) export function Dashboard() { return ( <Suspense fallback={<Spinner />}> <HeavyChart /> </Suspense> ) }

lazy+ 动态import()将重图表拆成独立 chunk,Suspense的 fallback 与第四节条件渲染的<Spinner />复用同一组件,保持加载态视觉一致。

8.3 数据库查询:只取需要的列

// PASS: GOOD: Select only needed columns const { data } = await supabase .from('markets') .select('id, name, status') .limit(10) // FAIL: BAD: Select everything const { data } = await supabase .from('markets') .select('*')

列裁剪 +limit是最基础的传输层优化,与第五节分页契约(limit/offset)保持一致:API 层约定分页参数,查询层必须兑现。

九、测试标准:AAA 结构与描述性命名

9.1 AAA 模式(Arrange–Act–Assert)

test('calculates similarity correctly', () => { // Arrange const vector1 = [1, 0, 0] const vector2 = [0, 1, 0] // Act const similarity = calculateCosineSimilarity(vector1, vector2) // Assert expect(similarity).toBe(0) })

测试体固定分三段:准备输入(含正交的向量 1 与向量 2)、执行单一被测调用、断言精确结果。正交向量余弦相似为 0,使断言值本身可手工验证。

9.2 测试命名:描述“场景-行为”

// PASS: GOOD: Descriptive test names 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', () => { }) // FAIL: BAD: Vague test names test('works', () => { }) test('test search', () => { })

正例遵循 “<行为> when <条件>” 句式,覆盖边界(无匹配)、故障(密钥缺失)与降级(Redis 不可用回退)三类场景;测试名本身就是文档,失败日志能直接定位问题。

十、代码坏味道检测:三类反模式的量化判据

技能将坏味道检查收敛为三类,且都给出了可量化的重构手法。

10.1 长函数(超过 50 行)

// FAIL: BAD: Function > 50 lines function processMarketData() { // 100 lines of code } // PASS: GOOD: Split into smaller functions function processMarketData() { const validated = validateData() const transformed = transformData(validated) return saveData(transformed) }

重构模式是“管道式分解”:原函数退化为 validate → transform → save 三步编排,每步独立命名、可单独测试。规则层将此量化为 checklist 项 “Functions are small (<50 lines)”。

10.2 深层嵌套(5 层以上)

// FAIL: BAD: 5+ levels of nesting if (user) { if (user.isAdmin) { if (market) { if (market.isActive) { if (hasPermission) { // Do something } } } } } // PASS: GOOD: Early returns if (!user) return if (!user.isAdmin) return if (!market) return if (!market.isActive) return if (!hasPermission) return // Do something

守卫子句(guard clause)把 5 层嵌套压平成 5 个线性早退,主逻辑的缩进深度归零。规则层 checklist 对应项为 “No deep nesting (>4 levels)”。

10.3 魔法数字

// FAIL: BAD: Unexplained numbers if (retryCount > 3) { } setTimeout(callback, 500) // PASS: GOOD: Named constants const MAX_RETRIES = 3 const DEBOUNCE_DELAY_MS = 500 if (retryCount > MAX_RETRIES) { } setTimeout(callback, DEBOUNCE_DELAY_MS)

命名常量的关键在语义命名MAX_RETRIES表达“上限”,DEBOUNCE_DELAY_MS表达“防抖延迟”且带单位后缀MS。规则层 checklist 对应项为 “No hardcoded values (use constants or config)”,并补充了命名规范总表:变量/函数camelCase、布尔值is/has/should/can前缀、接口/类型/组件PascalCase、常量UPPER_SNAKE_CASE、hookuse前缀。

技能文末的收束句值得原样引用:“Code quality is not negotiable. Clear, maintainable code enables rapid development and confident refactoring.”——代码质量不可妥协,清晰可维护的代码换来的是快速开发与可信赖的重构。

十一、从源码结构看:规范如何被 ECC 工程化地执行

前述规范不是孤立文档。结合仓库中的实际文件,可以看出 ECC 用一个“三层执行体系”把 coding-standards 技能从文本变成约束:

第一层:技能层(完整流程)。.kiro/skills/coding-standards/SKILL.md(Kiro 版)与skills/coding-standards/SKILL.md(主仓基线版)承载本文正文的全部规范内容。主仓版额外增加的 “Scope Boundaries” 小节明确了技能的激活面(描述性命名、不可变默认值、KISS/DRY/YAGNI 执行、错误处理与坏味道审查)与非激活面(React 组合、后端分层、已有更窄技能覆盖的框架指导),防止通用技能被误用于它不该主导的场景。

第二层:规则层(按路径注入的最小约束)。rules/common/coding-style.md是跨语言通用规则(含 800 行文件软上限、200–400 行典型规模、代码质量 checklist);rules/typescript/coding-style.md通过pathsfrontmatter 声明只对**/*.ts**/*.tsx**/*.js**/*.jsx生效,补充了技能中示例背后的成文规则——interface vs type 的取舍、unknown替代any的安全收窄、React Props 禁用React.FC、JS 文件 JSDoc 与运行时对齐等。从源码结构看,这种 “common 打底 + 语言包叠加” 的组织方式,让同一套原则可以按文件类型精准生效,而不需要把全部规范塞进每个技能。

第三层:工具层(可机检的兜底)。仓库根目录的 eslint.config.js 展示了技能中“配置 lint 规则”这一激活场景在 ECC 自身工程里的落地形态——flat config 下:

  • ecmaVersion: 2022,默认 CommonJS、.mjs文件切换为 module;
  • 引入@eslint/js的 recommended 基线;
  • no-unused-vars提升为error,但通过argsIgnorePattern: '^_'varsIgnorePattern: '^_'caughtErrorsIgnorePattern: '^_'允许下划线前缀的刻意未用变量/参数/捕获错误——这与技能注释规范中“有理由的例外要显式声明”的精神一致,用命名约定把例外白名单化;
  • no-undef: 'error'堵住未定义引用,eqeqeq: 'warn'提示用严格相等。

此外,.kiro安装目录下还配套了审查类代理(如.kiro/agents/typescript-reviewer.md.kiro/agents/react-reviewer.md),与技能同属一个生态:技能负责在开发/审查时注入规范,reviewer 代理负责按规范执行审查。

适用前提与限制

  • 该技能面向TypeScript/JavaScript、React 与 Node.js技术栈(frontmatter description 明确),示例大量使用 Next.js(NextResponse、App Router)与 Supabase 客户端;若项目栈不同,示例的载体 API 需替换,但原则与结构(命名、不可变性、响应信封、Zod 边界校验、AAA 测试)是框架无关的。
  • 技能中的量化阈值(函数 <50 行、嵌套 >4 层即坏味道、文件 800 行软上限)来自 ECC 规则层的团队约定,属于建议性判据而非硬约束,可按团队规模调整。
  • Kiro 侧的调用前提是项目已通过.kiro安装器完成技能安装(/菜单可见),frontmatter 中origin: ECC标记了技能来源谱系,便于在多技能环境中溯源。

小结

coding-standards技能的完整脉络可以概括为:四大原则(Readability/KISS/DRY/YAGNI)定方向 → TS/JS 规范(描述性命名、CRITICAL 级不可变性、全面错误处理、Promise.all并行、拒绝any)定日常写法 → React 与 API 标准(显式 Props、函数式状态更新、统一响应信封、Zod 边界校验)定系统形态 → 文件组织与注释规范(按职责分层、WHY 注释、五要素 JSDoc)定协作界面 → 性能与测试实践(拷贝后排序、懒加载、列裁剪、AAA 与场景化测试名)定质量下限 → 三类坏味道的量化判据(<50 行、>4 层、命名常量)定审查清单。再叠加 ECC 仓库中“技能—规则—ESLint”三层执行体系,这份文档从“写给 Agent 看的规范”变成了“人、Agent 与工具共同遵守的工程契约”。将其安装进自己的 TypeScript/React 项目后,最先值得落地的三件事是:把不可变性设为代码审查的一票否决项、在系统边界引入 Schema 校验、并用 rules/common/coding-style.md 末尾的 checklist 作为每次提交前的自检清单。

【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 15:18:31

OSG/OSGEarth预编译三方库配置指南:从环境搭建到空间查询

简介&#xff1a;面向基于Visual Studio 2019构建64位OSG3.6.5与OSGEarth2.10项目的开发者&#xff0c;这份预编译三方库直击第三方依赖缺失、编译配置繁琐的痛点。压缩包约137.76MB&#xff0c;内含2000个文件&#xff0c;以头文件、静态库、CMake配置、inc文件、C源文件、pro…

作者头像 李华
网站建设 2026/9/7 15:16:44

COD20 PVE最高画质调优实战:幽灵船绞肉战稳定帧数指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 15:12:41

DSpark半自回归投机解码:置信度动态调度实现推理加速

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 15:12:27

SVN备份迁移实战:从dump到load的完整攻略及常见坑位

SVN备份迁移实战&#xff1a;一套完整的仓库搬迁方案&#xff0c;含常见坑位清单 干了快十年运维和研发管理&#xff0c;经手过的版本控制服务器少说也有十几台。每次接到“SVN备份迁移”这种活儿&#xff0c;我知道八成又有人要踩坑了&#xff1a;要么是项目组要换机房&#x…

作者头像 李华