edit-spec

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Edit a
.spec.ts
file to update the project's instruction files. The spec is the source of truth — CLAUDE.md and AGENTS.md are compiled build artifacts that must not be edited directly.
编辑
.spec.ts
文件以更新项目的指令文件。spec文件是唯一可信来源——CLAUDE.md和AGENTS.md是编译生成的成品文件,绝不能直接编辑。

Arguments

参数

$ARGUMENTS — What the user wants to change. Examples:
  • "add a rule about always using the custom logger"
  • "update the architecture section"
  • "add src/services/auth.ts to key files"
  • "add npm run lint to commands"
  • "change the testing guidance"
$ARGUMENTS — 用户想要进行的修改内容。示例:
  • "添加一条关于始终使用自定义日志器的规则"
  • "更新架构章节"
  • "将src/services/auth.ts添加到关键文件列表"
  • "添加npm run lint到命令列表"
  • "修改测试指导内容"

Instructions

操作步骤

Step 1: Find the Spec

步骤1:找到Spec文件

Look for spec files in the repo root:
  • CLAUDE.md.spec.ts
    — source for CLAUDE.md
  • AGENTS.md.spec.ts
    — source for AGENTS.md
  • Any
    *.spec.ts
    matching instruction files
If no spec exists: if there's a hand-written
CLAUDE.md
, suggest the
migrate-to-spec
skill; otherwise suggest
npx vigiles init
to scaffold one.
在仓库根目录中查找spec文件:
  • CLAUDE.md.spec.ts
    — CLAUDE.md的源文件
  • AGENTS.md.spec.ts
    — AGENTS.md的源文件
  • 所有与指令文件匹配的
    *.spec.ts
    文件
如果不存在spec文件:若存在手写的
CLAUDE.md
,建议使用
migrate-to-spec
技能;否则建议执行
npx vigiles init
来生成初始文件。

Step 2: Read and Understand the Spec

步骤2:阅读并理解Spec文件

Read the spec file. It's a TypeScript file that exports a
claude()
call with these fields:
typescript
import { claude, enforce, guidance, check, every } from "vigiles/spec";

export default claude({
  // Optional: output target (defaults to "CLAUDE.md")
  target: "CLAUDE.md",
  // or multi-target:
  // target: ["CLAUDE.md", "AGENTS.md"],

  // Prose sections — become ## headings in compiled output
  sections: {
    positioning: "What this project does...",
    architecture: "How the codebase is structured...",
  },

  // File paths verified to exist at compile time
  keyFiles: {
    "src/index.ts": "Main entry point",
  },

  // Commands verified against package.json
  commands: {
    "npm run build": "Compile the project",
    "npm test": "Run all tests",
  },

  // Rules — three types
  rules: {
    // enforce() — backed by a linter rule, verified to exist AND be enabled
    "no-any": enforce(
      "@typescript-eslint/no-explicit-any",
      "Use unknown and narrow with type guards.",
    ),

    // check() — filesystem assertion run by vigiles
    "test-pairing": check(
      every("src/**/*.service.ts").has("{name}.test.ts"),
      "Every service must have tests.",
    ),

    // guidance() — prose only, no enforcement
    "research-first": guidance("Google unfamiliar APIs before implementing."),
  },
});
阅读spec文件。这是一个TypeScript文件,导出一个包含以下字段的
claude()
调用:
typescript
import { claude, enforce, guidance, check, every } from "vigiles/spec";

export default claude({
  // 可选:输出目标(默认值为"CLAUDE.md")
  target: "CLAUDE.md",
  // 或多目标:
  // target: ["CLAUDE.md", "AGENTS.md"],

  // 文本章节——在编译输出中会成为##标题
  sections: {
    positioning: "本项目的功能...",
    architecture: "代码库的结构方式...",
  },

  // 编译时会验证是否存在的文件路径
  keyFiles: {
    "src/index.ts": "主入口文件",
  },

  // 会与package.json验证匹配的命令
  commands: {
    "npm run build": "编译项目",
    "npm test": "运行所有测试",
  },

  // 规则——三种类型
  rules: {
    // enforce() — 由lint规则支持,会验证规则是否存在且已启用
    "no-any": enforce(
      "@typescript-eslint/no-explicit-any",
      "使用unknown类型并通过类型守卫进行收窄。",
    ),

    // check() — 由vigiles执行的文件系统断言
    "test-pairing": check(
      every("src/**/*.service.ts").has("{name}.test.ts"),
      "每个服务文件都必须对应测试文件。",
    ),

    // guidance() — 仅文本说明,无强制校验
    "research-first": guidance("在实现不熟悉的API前先查阅资料。"),
  },
});

Step 3: Make the Changes

步骤3:进行修改

Based on what the user asked for:
Adding a rule (this absorbs the old
generate-rule
skill):
  • Classify the rule from the request:
    • enforce()
      — a linter rule can back it. Check the project's linter configs (ESLint, Ruff, Clippy, Pylint, RuboCop, Stylelint) for a matching rule; also consider an architectural tool (ast-grep, Dependency Cruiser, Steiger). If uncertain whether a rule exists, ask the user rather than guessing.
    • check()
      — a filesystem structural convention ("every X needs a Y"). Only for file-pairing; never for code content.
    • guidance()
      — can't be mechanically enforced (subjective conventions, process rules, migration context).
  • For
    enforce()
    : use the real linter rule name (e.g.
    eslint/no-console
    ,
    @typescript-eslint/no-explicit-any
    ,
    ruff/T201
    ).
  • Add to the
    rules
    object with a kebab-case key derived from the intent, preserving alphabetical order if the existing rules are alphabetical. Import any new builders needed (e.g.
    check
    and
    every
    for the first
    check()
    ).
Updating a section:
  • Edit the string in
    sections
    . Sections are plain strings or tagged template literals with
    file()
    ,
    cmd()
    ,
    ref()
    for verified references
  • Do NOT add
    #
    or
    ##
    headers inside sections — they break the document structure
Adding a key file or command:
  • Add to
    keyFiles
    or
    commands
    . The compiler verifies these exist at compile time
  • For commands: must match a script in
    package.json
  • For key files: must exist on disk
根据用户的需求执行操作:
添加规则(替代旧的
generate-rule
技能):
  • 对规则进行分类
    • enforce()
      — 可由lint规则支持。检查项目的lint配置(ESLint、Ruff、Clippy、Pylint、RuboCop、Stylelint)是否有匹配规则;也可考虑架构工具(ast-grep、Dependency Cruiser、Steiger)。若不确定规则是否存在,询问用户而非猜测。
    • check()
      — 文件系统结构约定(“每个X都需要对应Y”)。仅适用于文件配对场景;绝不能用于代码内容校验。
    • guidance()
      — 无法机械强制执行的规则(主观约定、流程规则、迁移背景等)。
  • 对于
    enforce()
    :使用真实的lint规则名称(例如
    eslint/no-console
    @typescript-eslint/no-explicit-any
    ruff/T201
    )。
  • 将规则添加到
    rules
    对象中,使用基于意图的短横线命名法作为键;若现有规则按字母排序,需保持字母顺序。导入所需的新构建器(例如第一个
    check()
    需要导入
    check
    every
    )。
更新章节
  • 编辑
    sections
    中的字符串。章节可以是普通字符串,也可以是带有
    file()
    cmd()
    ref()
    的标签模板字面量,用于添加已验证的引用
  • 不要在章节内添加
    #
    ##
    标题——这会破坏文档结构
添加关键文件或命令
  • 添加到
    keyFiles
    commands
    中。编译器会在编译时验证这些内容是否存在
  • 命令必须与
    package.json
    中的脚本匹配
  • 关键文件必须存在于磁盘上

Step 4: Compile

步骤4:编译

After editing the spec, run:
bash
npx vigiles compile
This regenerates the compiled instruction file(s). Review the output for any errors:
  • stale-file
    — a key file path doesn't exist
  • stale-command
    — a command isn't in package.json
  • invalid-rule
    — a linter rule doesn't exist or is disabled
  • section-has-header
    — a section contains
    #
    headers (break into separate named sections)
编辑完spec文件后,执行:
bash
npx vigiles compile
这会重新生成编译后的指令文件。检查输出是否有错误:
  • stale-file
    — 关键文件路径不存在
  • stale-command
    — 命令不在package.json中
  • invalid-rule
    — lint规则不存在或已禁用
  • section-has-header
    — 章节包含
    #
    标题(拆分为多个命名章节)

Step 5: Verify

步骤5:验证

bash
npx vigiles lint
If the vigiles plugin is installed (
/plugin marketplace add zernie/vigiles
then
/plugin install vigiles@vigiles
, or
npx vigiles init
), the PostToolUse hook recompiles automatically after you save the spec.
bash
npx vigiles lint
如果已安装vigiles插件(执行
/plugin marketplace add zernie/vigiles
然后
/plugin install vigiles@vigiles
,或执行
npx vigiles init
),则在保存spec文件后,PostToolUse钩子会自动重新编译。

Important

重要提示

  • Never edit CLAUDE.md or AGENTS.md directly — they have a vigiles hash comment and are build artifacts
  • The spec is TypeScript — you get type checking, autocomplete, and verified references
  • enforce()
    rules are verified
    — the compiler checks the rule exists AND is enabled in your linter config
  • Sections must not contain
    #
    or
    ##
    headers
    — use separate named sections instead
  • 绝不要直接编辑CLAUDE.md或AGENTS.md——它们带有vigiles哈希注释,属于编译成品文件
  • Spec文件是TypeScript文件——你可以获得类型检查、自动补全和已验证的引用
  • enforce()
    规则会被验证
    ——编译器会检查规则是否存在且在你的lint配置中已启用
  • 章节中不能包含
    #
    ##
    标题
    ——改用多个命名章节替代