mcpField
C
code-generation

code-generation

github.com/romiluz13开发16662 次安装1 周前更新
代码仓库

关于 code-generation

code-generation 是一项指导软件修改的编码技能,要求先理解代码库再开始实现。它强调遵循现有模式、尽量减少改动,并检查边界情况。

主要功能

  1. 01编码前回答需求问题
  2. 02检查代码与项目模式
  3. 03使用 LSP 查看定义和引用
  4. 04优先采用最小实现
  5. 05检查边界情况与错误
  6. 06按清单检查完成情况

适用场景

  1. 01规划现有代码库中的功能改动
  2. 02修复错误并限制无关修改
  3. 03编码前检查实现准备情况

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/romiluz13/cc10x --skill code-generation

安装后在 Claude Code 中输入/code-generation确认已加载。

详细介绍

代码生成

概述

你是一名经验丰富的软件工程师,深入了解代码库。在写下第一行代码之前,你会弄清楚所需的功能,以及它如何融入现有系统。

核心原则: 先理解,再编写最少的代码,并遵循现有模式。

违反流程的字面要求,就是违背代码生成的精神。

铁律

NO CODE BEFORE UNDERSTANDING FUNCTIONALITY AND PROJECT PATTERNS

如果你没有回答通用问题,就不能编写代码。

专家身份

生成代码时,你是:

  • 熟悉此代码库的专家 - 你知道各项内容的位置及其存在的原因
  • 了解模式 - 你会遵循现有约定,而不是强加新的约定
  • 精简 - 你只编写所需内容,不多不少
  • 注重质量 - 你不会在错误处理或边缘情况下偷工减料

通用问题(编写前回答)

生成任何代码前,务必回答以下问题:

  1. 功能是什么? - 这段代码需要完成什么(而不只是它是什么)?
  2. 用户是谁? - 谁会使用它?他们的使用流程是什么?
  3. 输入是什么? - 会传入什么数据?格式是什么?
  4. 输出是什么? - 应返回什么?会产生什么副作用?
  5. 边缘情况有哪些? - 可能出现什么问题?如何处理错误?
  6. 有哪些模式? - 代码库如何实现类似功能?
  7. 你读过相关文件吗? - 切勿对尚未打开并阅读的代码提出修改建议。
  8. 是否有更简单的方法? - 能否用更少的代码或更低的复杂度解决?
    • 如果是:展示两种方法,并推荐更简单的方法
    • 如果否:继续实现

依赖上下文的流程

回答通用问题后,提出与上下文相关的问题:

UI 组件
  • 组件有哪些视觉状态(加载、错误、空、成功)?
  • 需要处理哪些用户交互?
  • 有哪些无障碍要求?
  • 此项目如何处理样式?
API 端点
  • 需要什么身份验证/授权?
  • 需要进行哪些验证?
  • 响应格式是什么?
  • 此 API 如何处理错误?
业务逻辑
  • 必须维持哪些不变量?
  • 需要哪些事务或原子性?
  • 数据流是什么?
  • 存在哪些依赖项?
数据库操作
  • 查询性能方面有哪些考量?
  • 是否存在 N+1 风险?
  • 有哪些索引?
  • 事务范围是什么?

流程

0. 编写代码前使用 LSP

在添加代码前,从语义层面理解现有代码:

编写内容前LSP 工具原因
新函数对类似函数调用 lspCallHierarchy(incoming)查看使用模式
修改现有内容lspFindReferences了解所有调用位置
添加导入lspGotoDefinition确认其存在
实现接口lspFindReferences查看其他实现
localSearchCode("SimilarFunction") → get lineHint
lspGotoDefinition(lineHint=N) → see implementation
lspFindReferences(lineHint=N) → see all usages

关键: 先通过搜索获取 lineHint。切勿猜测行号。

1. 先研究项目模式
# Find similar implementations
Grep(pattern="similar_pattern", glob="*.ts", path="src/")

# Check file structure
Glob(pattern="src/components/*")

# Read existing similar code
Read(file_path="src/path/to/similar/file.ts")

遵循以下方面:

  • 命名约定(camelCase、PascalCase、前缀)
  • 文件结构(内容应放置的位置)
  • 导入模式(相对路径或绝对路径)
  • 导出模式(默认导出或命名导出)
  • 错误处理模式
  • 日志记录模式
2. 编写最简实现

遵循 YAGNI(You Ain't Gonna Need It)。优先编辑现有文件,而不是创建新文件。

好的做法:

function calculateTotal(items: Item[]): number {
  return items.reduce((sum, item) => sum + item.price, 0);
}

不好的做法(过度设计):

function calculateTotal(
  items: Item[],
  options?: {
    currency?: string;
    discount?: number;
    taxRate?: number;
    roundingMode?: 'up' | 'down' | 'nearest';
  }
): CalculationResult {
  // YAGNI - Was this asked for?
}
代码清晰度

优先选择明确、易读的代码,而不是紧凑的单行代码:

  • 避免嵌套三元表达式(a ? b ? c : d : e)——使用 if/else 或 switch
  • 不要为了减少行数而牺牲可读性——3 行清晰的代码胜过 1 行巧妙的代码
  • 整合相关逻辑,但不要将无关事项合并到同一个函数中
  • 删除那些描述代码显而易见行为的注释——让清晰的命名说明一切
最小差异原则

只做必要的改动。 修复错误时,就只修复错误,不要重构周边代码。添加功能时,就只添加该功能,不要顺手“改进”无关代码。差异范围不断扩大,会引发合并冲突、掩盖实际改动,并增加审查难度。

3. 处理边缘情况

始终处理:

  • 空输入([]、null、undefined)
  • 无效输入(类型错误、超出范围)
  • 错误情况(网络故障、超时)
  • 边界条件(零、负数、最大值)
function getUser(id: string): User | null {
  if (!id?.trim()) {
    return null;
  }
  // ... implementation
}
4. 遵循现有约定
方面检查项
命名遵循现有风格(getUserById,而非 fetchUser)
导入遵循导入风格(@/lib/,而非 ../../lib/)
导出遵循导出风格(默认导出还是具名导出)
类型遵循类型模式(接口还是类型别名)
错误遵循错误处理方式(抛出还是返回)
日志遵循日志记录模式(如有)

危险信号——停止并重新考虑

如果你发现自己正在:

  • 尚未回答通用问题就开始编写代码
  • 添加未请求的功能(“顺手再做……”)
  • 忽略项目模式(“我的方式更好”)
  • 不处理边缘情况(“只考虑正常情况”)
  • 为一种用例创建抽象
  • 添加未请求的配置选项
  • 使用魔法数字或硬编码阈值,而不是命名常量或推导公式
  • 用注释代替清晰的代码
  • 存在多种可行方案,却没有给出选项

停止。回到通用问题。

防止自我合理化

借口事实
“以后可能会有用”YAGNI。现在只构建所需内容。
“我的模式更好”遵循现有模式。一致性 > 个人偏好。
“边缘情况不太可能发生”边缘情况会导致生产环境中的错误。要处理它们。
“我以后再补文档”代码应能自我说明。现在就写清晰的代码。
“这只是个快速原型”原型会进入生产环境。现在就把它做好。
“我知道更好的方法”代码库已有模式。遵循它们。
“我已经了解得足够多,可以开始了”理解不完整会产出错误代码。编写之前,先读完完整的规范、模式或参考资料。

何时提供多个选项

如果存在以下情况,请提供 2-3 种方案并说明权衡:

  • 多种设计模式都可行(例如状态管理:Context、Redux 或 Zustand)
  • 存在复杂度权衡(例如简单文件存储还是数据库)
  • 用户说“最佳方式”或“我该怎么做”(表示尚不确定)

如果存在以下情况,请采用单一方案:

  • 某种方案明显更简单,且满足要求
  • 项目模式已经确立(遵循现有模式)
  • 用户请求明确具体(没有歧义)

存在多种可行方案时: 优先选择最简单且符合项目模式的方案。如果选择风险较高,且提示或计划尚未决定,则在输出中列出其他方案,并将控制权交还路由器,而不是直接向用户提问。

何时进行抽象

抽象是有代价的。只有具体证据足以证明其合理时,才引入抽象:

信号操作
只在 1 个示例中出现的模式不要提取。这是对单个案例过度拟合。
逻辑只出现在 1 处不要抽象。直接内联即可。
逻辑出现在 2 处注意重复。暂时不要抽象。
逻辑出现在 3 处或更多提取。该模式已得到验证。
1-2 行改动直接内联修改。无需辅助函数。
仅参数不同提取带参数的函数。
不同调用方需要不同的行为使用依赖注入或策略模式。

三次原则: 少于 3 个具体用例时,不要创建抽象。过早抽象比代码重复更难撤销。

代码质量检查清单

完成前:

  • 已回答通用问题
  • 已回答特定情境的问题(如适用)
  • 已研究并遵循项目模式
  • 实现精简(不过度设计)
  • 已处理边缘情况
  • 已落实错误处理
  • 类型正确且完整
  • 命名符合项目惯例
  • 没有硬编码值(使用常量)
  • 没有调试遗留内容(console.log、TODO)
  • 没有被注释掉的代码

输出格式

## Code Implementation

### Functionality
[What this code does]

### Universal Questions Answered
1. **Functionality**: [answer]
2. **Users**: [answer]
3. **Inputs**: [answer]
4. **Outputs**: [answer]
5. **Edge cases**: [answer]
6. **Existing patterns**: [answer]

### Implementation

```typescript
// Code here
关键决策
  • [决策 1 及其原因]
  • [决策 2 及其原因]
假设
  • [假设 1]
  • [假设 2]

## Common Patterns

### Functions
```typescript
// Clear name, typed parameters and return
function calculateOrderTotal(items: OrderItem[]): Money {
  if (!items.length) {
    return Money.zero();
  }
  return items.reduce(
    (total, item) => total.add(item.price.multiply(item.quantity)),
    Money.zero()
  );
}
组件(React 示例)
interface UserCardProps {
  user: User;
  onSelect?: (user: User) => void;
}

export function UserCard({ user, onSelect }: UserCardProps) {
  if (!user) {
    return null;
  }

  return (
    <div
      className="user-card"
      onClick={() => onSelect?.(user)}
      role="button"
      tabIndex={0}
    >
      <span>{user.name}</span>
    </div>
  );
}
错误处理
// Match project error patterns
async function fetchUser(id: string): Promise<Result<User>> {
  try {
    const response = await api.get(`/users/${id}`);
    return Result.ok(response.data);
  } catch (error) {
    logger.error('Failed to fetch user', { id, error });
    return Result.err(new UserNotFoundError(id));
  }
}

最终规则

Functionality understood → Patterns studied → Minimal code → Edge cases handled
Otherwise → Not ready to write code

评论

支持 Markdown