claudeos-core 2.1.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CHANGELOG.md +1649 -481
  2. package/CONTRIBUTING.md +92 -92
  3. package/README.de.md +64 -5
  4. package/README.es.md +64 -5
  5. package/README.fr.md +64 -5
  6. package/README.hi.md +64 -5
  7. package/README.ja.md +64 -5
  8. package/README.ko.md +1018 -959
  9. package/README.md +1020 -960
  10. package/README.ru.md +66 -5
  11. package/README.vi.md +1019 -960
  12. package/README.zh-CN.md +64 -5
  13. package/bin/cli.js +152 -148
  14. package/bin/commands/init.js +1673 -1518
  15. package/bin/commands/lint.js +62 -0
  16. package/bin/commands/memory.js +438 -438
  17. package/bin/lib/cli-utils.js +206 -206
  18. package/claude-md-validator/index.js +184 -0
  19. package/claude-md-validator/reporter.js +66 -0
  20. package/claude-md-validator/structural-checks.js +528 -0
  21. package/content-validator/index.js +666 -436
  22. package/lib/env-parser.js +317 -0
  23. package/lib/expected-guides.js +23 -23
  24. package/lib/expected-outputs.js +90 -90
  25. package/lib/language-config.js +35 -35
  26. package/lib/memory-scaffold.js +1058 -1052
  27. package/lib/plan-parser.js +165 -165
  28. package/lib/staged-rules.js +118 -118
  29. package/manifest-generator/index.js +174 -174
  30. package/package.json +90 -87
  31. package/pass-json-validator/index.js +337 -337
  32. package/pass-prompts/templates/angular/pass3.md +28 -13
  33. package/pass-prompts/templates/common/claude-md-scaffold.md +686 -0
  34. package/pass-prompts/templates/common/pass3-footer.md +402 -39
  35. package/pass-prompts/templates/common/pass3b-core-header.md +43 -0
  36. package/pass-prompts/templates/common/pass4.md +375 -302
  37. package/pass-prompts/templates/common/staging-override.md +26 -26
  38. package/pass-prompts/templates/java-spring/pass3.md +31 -21
  39. package/pass-prompts/templates/kotlin-spring/pass3.md +34 -22
  40. package/pass-prompts/templates/node-express/pass3.md +30 -21
  41. package/pass-prompts/templates/node-fastify/pass3.md +28 -14
  42. package/pass-prompts/templates/node-nestjs/pass3.md +29 -14
  43. package/pass-prompts/templates/node-nextjs/pass3.md +34 -21
  44. package/pass-prompts/templates/node-vite/pass1.md +117 -117
  45. package/pass-prompts/templates/node-vite/pass2.md +78 -78
  46. package/pass-prompts/templates/node-vite/pass3.md +30 -13
  47. package/pass-prompts/templates/python-django/pass3.md +32 -21
  48. package/pass-prompts/templates/python-fastapi/pass3.md +33 -21
  49. package/pass-prompts/templates/python-flask/pass1.md +119 -119
  50. package/pass-prompts/templates/python-flask/pass2.md +85 -85
  51. package/pass-prompts/templates/python-flask/pass3.md +31 -13
  52. package/pass-prompts/templates/vue-nuxt/pass3.md +32 -13
  53. package/plan-installer/domain-grouper.js +76 -76
  54. package/plan-installer/index.js +137 -129
  55. package/plan-installer/prompt-generator.js +188 -128
  56. package/plan-installer/scanners/scan-frontend.js +505 -473
  57. package/plan-installer/scanners/scan-java.js +226 -226
  58. package/plan-installer/scanners/scan-node.js +57 -57
  59. package/plan-installer/scanners/scan-python.js +85 -85
  60. package/plan-installer/stack-detector.js +482 -466
  61. package/plan-installer/structure-scanner.js +65 -65
  62. package/sync-checker/index.js +177 -177
package/README.zh-CN.md CHANGED
@@ -69,6 +69,38 @@ ClaudeOS-Core 生成的文档知道你的项目使用 `ApiResponse.ok()`(而
69
69
 
70
70
  ---
71
71
 
72
+ ## 生成后质量保证 (v2.3.0)
73
+
74
+ 生成只解决了问题的一半。另一半是 **知道输出是正确的** —— 跨越 10 种输出语言、11 种 stack 模板、以及各种规模的项目。v2.3.0 添加了两个在生成之后运行的确定性验证器,它们不依赖 LLM 自检。
75
+
76
+ ### `claude-md-validator` —— 结构不变式
77
+
78
+ 每个生成的 `CLAUDE.md` 都会对照 25 个结构不变式进行检查,这些不变式只使用语言无关的信号: markdown 语法 (`^## `, `^### `)、不会被翻译的字面文件名 (`decision-log.md`, `failure-patterns.md`)、section 数量、每个 section 的子 section 数量、表格行数。同一个验证器对英语、韩语、日语、越南语、印地语、俄语、西班牙语、中文、法语、德语生成的 `CLAUDE.md` 会产出逐字节相同的判定。
79
+
80
+ 跨语言保证由所有 10 种语言的测试 fixture 验证,其中 6 种语言的坏用例 fixture 会产生完全相同的错误签名。当不变式在越南语项目上失败时,修复方法与在德语项目上失败时完全相同。
81
+
82
+ ### `content-validator [10/10]` —— 路径声明验证与 MANIFEST 一致性
83
+
84
+ 读取所有生成的 `.md` 文件中以反引号括起的路径引用 (`src/...`, `.claude/rules/...`, `claudeos-core/skills/...`) 并对照真实文件系统进行验证。捕捉两类此前没有工具能检测的 LLM 失败:
85
+
86
+ - **`STALE_PATH`** —— 当 Pass 3 或 Pass 4 捏造出看似合理但不存在的路径时。典型例子: 实际文件是 `routePath.ts`,但因 TypeScript 常量名为 `FEATURE_ROUTE_PATH` 而推断出 `featureRoutePath.ts`; 在多入口项目中从 Vite 约定推断出 `src/main.tsx`; 项目根本没有测试,却从 MSW 文档推断出 `src/__mocks__/handlers.ts`。
87
+ - **`MANIFEST_DRIFT`** —— 当 `claudeos-core/skills/00.shared/MANIFEST.md` 注册了某个 skill 但 `CLAUDE.md §6` 没有提到 (或反之)。它识别出 orchestrator + sub-skills 布局 (其中 `CLAUDE.md §6` 是入口点,`MANIFEST.md` 是完整注册表),并将 sub-skills 判定为通过其父 orchestrator 间接覆盖。
88
+
89
+ 验证器与 `pass3-footer.md` 和 `pass4.md` 中的 prompt 级别预防配对: 记录了具体幻觉类别 (父目录前缀、Vite/MSW/Vitest/Jest/RTL 库约定) 的 anti-pattern 块,以及在 `pass3a-facts.md` 没有具体文件名时把规则限定到目录级别的明确 positive guidance。
90
+
91
+ ### 在任意项目上运行验证
92
+
93
+ ```bash
94
+ npx claudeos-core health # 所有验证器 —— 单一 go/no-go 判定
95
+ npx claudeos-core lint # 仅 CLAUDE.md 结构不变式 (任意语言)
96
+ ```
97
+
98
+ ### 真实世界验证
99
+
100
+ v2.3.0 在发布前在两个真实世界的韩语姐妹项目上完成了 end-to-end 验证: 一个 14 domain 的 single-SPA Vite + React 19 前端,带有一个 8 子 skill 的 `scaffold-page-feature` orchestrator; 以及一个 8 domain 的 Spring Boot + MyBatis 后端,带有一个 8 子 skill 的 `scaffold-crud-feature` orchestrator,正在进行 PostgreSQL → MariaDB 迁移。两个项目在完整 health check 中都稳定在 **0 errors, 0 warnings** —— `STALE_PATH` 0、`MANIFEST_DRIFT` 0、25/25 结构不变式全部通过 —— 没有对生成输出进行任何手动编辑。
101
+
102
+ ---
103
+
72
104
  ## 支持的技术栈
73
105
 
74
106
  | 技术栈 | 检测方式 | 分析深度 |
@@ -85,10 +117,20 @@ ClaudeOS-Core 生成的文档知道你的项目使用 `ApiResponse.ok()`(而
85
117
  | **Vite / React SPA** | `package.json`、`vite.config.*` | 9 大类、55 小项 |
86
118
  | **Angular** | `package.json`、`angular.json` | 12 大类、78 小项 |
87
119
 
88
- 自动检测:语言和版本、框架和版本(包括作为 SPA 框架的 Vite)、ORM(MyBatis、JPA、Exposed、Prisma、TypeORM、SQLAlchemy 等)、数据库(PostgreSQL、MySQL、Oracle、MongoDB、SQLite)、包管理器(Gradle、Maven、npm、yarn、pnpm、pip、poetry)、架构(CQRS、BFF — 从模块名检测)、多模块结构(从 settings.gradle 检测)、单体仓库(Turborepo、pnpm-workspace、Lerna、npm/yarn workspaces)。
120
+ 自动检测:语言和版本、框架和版本(包括作为 SPA 框架的 Vite)、ORM(MyBatis、JPA、Exposed、Prisma、TypeORM、SQLAlchemy 等)、数据库(PostgreSQL、MySQL、Oracle、MongoDB、SQLite)、包管理器(Gradle、Maven、npm、yarn、pnpm、pip、poetry)、架构(CQRS、BFF — 从模块名检测)、多模块结构(从 settings.gradle 检测)、单体仓库(Turborepo、pnpm-workspace、Lerna、npm/yarn workspaces)、**`.env.example` 运行时配置**(v2.2.0 — 从 Vite、Next.js、Nuxt、Angular、Node、Python 框架的 16 个以上约定变量名中提取 port/host/API-target)。
89
121
 
90
122
  **你不需要指定任何内容。一切都会自动检测。**
91
123
 
124
+ ### `.env`-driven 运行时配置 (v2.2.0)
125
+
126
+ v2.2.0 新增 `lib/env-parser.js`,使生成的 `CLAUDE.md` 反映项目实际声明的内容,而非框架默认值。
127
+
128
+ - **搜索顺序**:`.env.example`(canonical、已提交)→ `.env.local.example` → `.env.sample` → `.env.template` → `.env` → `.env.local` → `.env.development`。`.example` 变体优先,因为它是 developer-neutral 的 shape-of-truth,而非某个贡献者的本地覆盖。
129
+ - **识别的 port 变量约定**:`VITE_PORT` / `VITE_DEV_PORT` / `VITE_DESKTOP_PORT` / `NEXT_PUBLIC_PORT` / `NUXT_PORT` / `NG_PORT` / `APP_PORT` / `SERVER_PORT` / `HTTP_PORT` / `DEV_PORT` / `FLASK_RUN_PORT` / `UVICORN_PORT` / `DJANGO_PORT` / 通用 `PORT`。当两者同时存在时,framework-specific 名称优先于通用的 `PORT`。
130
+ - **Host 与 API target**:`VITE_DEV_HOST` / `VITE_API_TARGET` / `NEXT_PUBLIC_API_URL` / `NUXT_PUBLIC_API_BASE` / `BACKEND_URL` / `PROXY_TARGET` 等。
131
+ - **优先级**:Spring Boot `application.yml` 的 `server.port` 仍然优先(framework-native config),然后是 `.env` 中声明的 port,最后才是 framework 默认值(Vite 5173、Next.js 3000、Django 8000 等)作为兜底。
132
+ - **敏感变量 redaction**:匹配 `PASSWORD` / `SECRET` / `TOKEN` / `API_KEY` / `ACCESS_KEY` / `PRIVATE_KEY` / `CREDENTIAL` / `JWT_SECRET` / `CLIENT_SECRET` / `SESSION_SECRET` / `BEARER` / `SALT` 模式的变量值在进入任何下游生成器之前被替换为 `***REDACTED***`。对意外提交到 `.env.example` 的 secrets 的 defense-in-depth 保护。`DATABASE_URL` 因 stack-detector DB 识别 back-compat 而被显式白名单保留。
133
+
92
134
  ### Java 领域检测(5 种模式,带回退)
93
135
 
94
136
  | 优先级 | 模式 | 结构 | 示例 |
@@ -364,7 +406,7 @@ cat claudeos-core/generated/pass4-prompt.md \
364
406
 
365
407
  **验证:** `claudeos-core/memory/` 应该包含 4 个文件(`decision-log.md`、`failure-patterns.md`、`compaction.md`、`auto-rule-update.md`),`.claude/rules/60.memory/` 应该包含 4 个规则文件,并且 `CLAUDE.md` 应该附加了一个 `## Memory (L4)` 部分。标记:`claudeos-core/generated/pass4-memory.json`。
366
408
 
367
- > **v2.1.0 gap-fill:** Pass 4 也会确保 `claudeos-core/skills/00.shared/MANIFEST.md` 存在。如果 Pass 3c 省略了它(在 skill-sparse 项目上可能发生,因为各 stack 的 `pass3.md` 模板将 `MANIFEST.md` 列为生成目标但未标记为 REQUIRED),gap-fill 会创建一个最小 stub,使 `.claude/rules/50.sync/03.skills-sync.md` 始终有一个有效的引用目标。幂等:若文件已有真实内容(>20 字符)则跳过。
409
+ > **v2.1.0 gap-fill:** Pass 4 也会确保 `claudeos-core/skills/00.shared/MANIFEST.md` 存在。如果 Pass 3c 省略了它(在 skill-sparse 项目上可能发生,因为各 stack 的 `pass3.md` 模板将 `MANIFEST.md` 列为生成目标但未标记为 REQUIRED),gap-fill 会创建一个最小 stub,使 `.claude/rules/50.sync/02.skills-sync.md`(v2.2.0 路径 — sync 规则数量从 3 个减至 2 个,原 `03` 变为 `02`)始终有一个有效的引用目标。幂等:若文件已有真实内容(>20 字符)则跳过。
368
410
 
369
411
  > **注意:** 如果 `claude -p` 失败或 `pass4-prompt.md` 缺失,自动化管道会回退到通过 `lib/memory-scaffold.js` 的静态脚手架(当 `--lang` 为非英语时,带有 Claude 驱动的翻译)。静态回退仅在 `npx claudeos-core init` 内部运行 — 手动模式要求 Pass 4 成功。
370
412
 
@@ -474,6 +516,8 @@ Pass 3 提示模板还包括一个 **Phase 1 "Read Once, Extract Facts" 块**,
474
516
  - **Rule D** — 输出简洁:文件写入之间仅一行(`[WRITE]`/`[SKIP]`),不复述事实表,不回显文件内容。
475
517
  - **Rule E** — 批量幂等检查:在 PHASE 2 开始时进行一次 `Glob`,而不是每个目标调用 `Read`。
476
518
 
519
+ 在 **v2.2.0** 中,Pass 3 会将一个确定性的 CLAUDE.md scaffold(`pass-prompts/templates/common/claude-md-scaffold.md`)内联到提示中。这固定了 8 个顶层章节的标题和顺序,使生成的 `CLAUDE.md` 不会在项目之间漂移,同时仍允许每个章节的内容适应各个项目。stack-detector 的新 `.env` 解析器(`lib/env-parser.js`)向提示供应 `stack.envInfo`,使 port/host/API target 行匹配项目实际声明的值,而不是 framework 默认值。
520
+
477
521
  **Pass 4** 搭建 L4 内存层:持久化的团队知识文件(decision-log、failure-patterns、compaction 策略、auto-rule-update)加上告诉未来会话何时以及如何读/写这些文件的 `60.memory/` 规则。内存层是 Claude Code 能够跨会话积累教训而不是每次重新发现的原因。当 `--lang` 是非英语时,回退的静态内容在被写入之前会通过 Claude 翻译。v2.1.0 为 `skills/00.shared/MANIFEST.md` 添加了一个 gap-fill,以防 Pass 3c 省略它。
478
522
 
479
523
  ---
@@ -483,7 +527,7 @@ Pass 3 提示模板还包括一个 **Phase 1 "Read Once, Extract Facts" 块**,
483
527
  ```
484
528
  your-project/
485
529
 
486
- ├── CLAUDE.md ← Claude Code 入口点
530
+ ├── CLAUDE.md ← Claude Code 入口点(8 部分确定性结构,v2.2.0)
487
531
 
488
532
  ├── .claude/
489
533
  │ └── rules/ ← Glob 触发规则
@@ -832,7 +876,14 @@ Claude Code 的 sensitive-path 策略拒绝从 `claude -p` 子进程直接写入
832
876
 
833
877
  ```
834
878
  pass-prompts/templates/
835
- ├── common/ # 共享 header/footer + pass4 + staging-override
879
+ ├── common/ # 共享 header/footer + pass4 + staging-override + CLAUDE.md scaffold (v2.2.0)
880
+ │ ├── header.md # 角色 + 输出格式指令(所有 pass)
881
+ │ ├── pass3-footer.md # Pass 3 完成后 health-check 指令 + 5 个 CRITICAL 护栏块 (v2.2.0)
882
+ │ ├── pass3-phase1.md # "Read Once, Extract Facts" 块(Rule A-E)(v2.1.0)
883
+ │ ├── pass4.md # 内存脚手架提示 (v2.0.0)
884
+ │ ├── staging-override.md # 将 .claude/rules/** 写入重定向至 .staged-rules/** (v2.0.0)
885
+ │ ├── claude-md-scaffold.md # 确定性 8 节 CLAUDE.md 模板 (v2.2.0)
886
+ │ └── lang-instructions.json # 按语言的输出指令(10 种语言)
836
887
  ├── java-spring/ # Java / Spring Boot
837
888
  ├── kotlin-spring/ # Kotlin / Spring Boot (CQRS, BFF, multi-module)
838
889
  ├── node-express/ # Node.js / Express
@@ -849,6 +900,8 @@ pass-prompts/templates/
849
900
 
850
901
  `plan-installer` 自动检测你的技术栈,然后组装特定于类型的提示。NestJS、Vue/Nuxt、Vite SPA 和 Flask 分别使用专用模板,具有框架特定的分析类别(例如 NestJS 的 `@Module`/`@Injectable`/Guards;Vue 的 `<script setup>`/Pinia/useFetch;Vite 的 client-side routing/`VITE_` env;Flask 的 Blueprint/`app.factory`/Flask-SQLAlchemy)。对于多技术栈项目,分别生成 `pass1-backend-prompt.md` 和 `pass1-frontend-prompt.md`,而 `pass3-prompt.md` 结合两个技术栈的生成目标。在 v2.1.0 中,Pass 3 模板在被按 split-mode 阶段切片前,会被前置 `common/pass3-phase1.md`(包含 Rules A–E 的 "Read Once, Extract Facts" 块)。Pass 4 使用共享的 `common/pass4.md` 模板(内存脚手架),与技术栈无关。
851
902
 
903
+ **在 v2.2.0 中**,Pass 3 提示词还在 phase1 块和栈特定主体之间内联嵌入 `common/claude-md-scaffold.md`(确定性 8 节 CLAUDE.md 模板)——这固定了 8 节的结构以避免生成的 CLAUDE.md 在项目间漂移,同时内容仍按项目自适应。`claude-md-scaffold.md` 采用 **English-first** 编写;来自 `lang-instructions.json` 的语言注入指示 LLM 在输出时将节标题和散文翻译为目标输出语言。
904
+
852
905
  ---
853
906
 
854
907
  ## 单体仓库支持
@@ -935,6 +988,12 @@ my-monorepo/ ← 在此运行:npx claudeos-core init
935
988
 
936
989
  **"CLAUDEOS_SKIP_TRANSLATION=1 is set but --lang='ko' requires translation" InitError(v2.0.0)** — 你在 shell 中设置了仅用于测试的环境变量 `CLAUDEOS_SKIP_TRANSLATION=1`(可能是 CI/测试设置遗留下来的)并选择了非英语 `--lang`。这个环境变量使 Pass 4 的静态回退和 gap-fill 依赖的翻译路径短路以用于非英语输出。`init` 在语言选择时检测冲突并立即中止(而不是在 Pass 4 中途带着令人困惑的嵌套错误崩溃)。修复:在运行之前 `unset CLAUDEOS_SKIP_TRANSLATION`,或使用 `npx claudeos-core init --lang en`。
937
990
 
991
+ **"⚠️ v2.2.0 upgrade detected" 警告 (v2.2.0)** — 现有的 `CLAUDE.md` 是用 v2.2.0 之前的版本生成的。默认 resume 模式重新生成会根据 Rule B idempotency 跳过现有文件,因此 v2.2.0 的结构性改进(8 节 CLAUDE.md scaffold、`40.infra/*` 每文件 paths、`.env.example` 端口准确性、Section 8 `Common Rules & Memory (L4)` 重新设计(通用规则 · L4 内存两个子节结构)、`60.memory/*` 规则行、forward-reference 的 `04.doc-writing-guide.md`)不会被应用。解决:使用 `npx claudeos-core init --force` 重新运行。生成文件(`CLAUDE.md`、`.claude/rules/`、`claudeos-core/standard/`、`claudeos-core/skills/`、`claudeos-core/guide/`)会被覆盖,但 `claudeos-core/memory/` 内容(decision-log、failure-patterns 等累积条目——append-only)完全保留。如需在覆盖前检查 diff,请在 `--force` 之前先 git commit 项目。
992
+
993
+ **CLAUDE.md 中的 port 与 `.env.example` 不一致 (v2.2.0)** — v2.2.0 的新 `.env` 解析器(`lib/env-parser.js`)优先读取 `.env.example`(提交的 canonical 文件),然后 fallback 到 `.env` 变种。识别的端口变量名:`PORT`、`VITE_PORT`、`VITE_DESKTOP_PORT`、`NEXT_PUBLIC_PORT`、`NUXT_PORT`、`DJANGO_PORT` 等。对于 Spring Boot,`application.yml` 的 `server.port` 仍然优先于 `.env`(framework-native config 优先)。如果项目使用非标准 env 变量名,请改用惯例名称或提 issue 请求扩展 `PORT_VAR_KEYS`。framework 默认值(Vite 5173、Next.js 3000、Django 8000)仅在直接检测和 `.env` 都静默时使用。
994
+
995
+ **生成的文档中显示 `***REDACTED***` 值 (v2.2.0)** — 预期行为。v2.2.0 的 `.env` 解析器会自动将匹配 `PASSWORD`/`SECRET`/`TOKEN`/`API_KEY`/`CREDENTIAL`/`PRIVATE_KEY` 模式的变量值替换为 `***REDACTED***`,然后传递给所有生成器。这是对 `.env.example` 中意外提交的敏感信息的 defense-in-depth 保护。`DATABASE_URL` 因 stack-detector DB 识别 back-compat 而保留。如果在生成的 `CLAUDE.md` 表格中看到 `***REDACTED***`,这是 bug,请提交 issue——redacted 值不应到达表格。非敏感运行时配置(port、host、API target、NODE_ENV 等)照常通过。
996
+
938
997
  ---
939
998
 
940
999
  ## 贡献
@@ -944,7 +1003,7 @@ my-monorepo/ ← 在此运行:npx claudeos-core init
944
1003
  - **新技术栈模板** — Ruby/Rails、Go (Gin/Fiber/Echo)、PHP (Laravel/Symfony)、Rust (Axum/Actix)、Svelte/SvelteKit、Remix
945
1004
  - **IDE 集成** — VS Code 扩展、IntelliJ 插件
946
1005
  - **CI/CD 模板** — GitLab CI、CircleCI、Jenkins 示例(GitHub Actions 已经自带 — 参见 `.github/workflows/test.yml`)
947
- - **测试覆盖率** — 扩展测试套件(当前 29 个测试文件中的 563 个测试,涵盖扫描器、技术栈检测、领域分组、计划解析、提示生成、CLI 选择器、单体仓库检测、Vite SPA 检测、验证工具、L4 内存脚手架、Pass 2 恢复验证、Pass 3 Guards 1/2/3(H1 哨兵 + H2 BOM-aware 空文件 + 严格陈旧标记 unlink)、Pass 3 split-mode 批次子分割、Pass 3 部分标记 resume(v2.1.0)、Pass 4 标记内容验证 + 陈旧标记 unlink 严格性 + scaffoldSkillsManifest gap-fill(v2.1.0)、翻译 env-skip 守卫 + early fail-fast + CI 工作流、staged-rules 移动、语言感知翻译回退、master plan 移除回归套件(v2.1.0)、memory score/compact 格式化回归(v2.1.0)和 AI Work Rules 模板结构)
1006
+ - **测试覆盖率** — 扩展测试套件(当前 30 个测试文件中的 602 个测试,涵盖扫描器、技术栈检测、领域分组、计划解析、提示生成、CLI 选择器、单体仓库检测、Vite SPA 检测、验证工具、L4 内存脚手架、Pass 2 恢复验证、Pass 3 Guards 1/2/3(H1 哨兵 + H2 BOM-aware 空文件 + 严格陈旧标记 unlink)、Pass 3 split-mode 批次子分割、Pass 3 部分标记 resume(v2.1.0)、Pass 4 标记内容验证 + 陈旧标记 unlink 严格性 + scaffoldSkillsManifest gap-fill(v2.1.0)、翻译 env-skip 守卫 + early fail-fast + CI 工作流、staged-rules 移动、语言感知翻译回退、master plan 移除回归套件(v2.1.0)、memory score/compact 格式化回归(v2.1.0)和 AI Work Rules 模板结构、`.env` 解析器 port/host/API-target 提取 + 敏感变量 redaction (v2.2.0))
948
1007
 
949
1008
  查看 [`CONTRIBUTING.md`](./CONTRIBUTING.md) 以获取完整的领域列表、代码风格、提交约定和添加新技术栈模板的分步指南。
950
1009
 
package/bin/cli.js CHANGED
@@ -1,149 +1,153 @@
1
1
  #!/usr/bin/env node
2
-
3
- /**
4
- * ClaudeOS-Core — CLI
5
- *
6
- * Node.js replacement for bootstrap.sh with cross-platform support.
7
- * Usage:
8
- * npx claudeos-core init --lang ko ← Run 4-Pass pipeline (Korean output)
9
- * npx claudeos-core init ← Interactive language selection
10
- * npx claudeos-core health ← Run health checker
11
- * npx claudeos-core validate ← Run plan validator (--check)
12
- * npx claudeos-core restore ← Restore from Master Plan
13
- * npx claudeos-core refresh ← Sync disk → Plan
14
- * npx claudeos-core memory <sub> ← L4 memory (compact/score/propose-rules)
15
- * npx claudeos-core --help ← Show help
16
- *
17
- * Also works when cloned directly:
18
- * node claudeos-core-tools/bin/cli.js init
19
- */
20
-
21
- const path = require("path");
22
- const { TOOLS_DIR, PROJECT_ROOT, log, run, readFile } = require("./lib/cli-utils");
23
- const { cmdInit, InitError } = require("./commands/init");
24
- const { cmdMemory } = require("./commands/memory");
25
-
26
- // Set env var so sub-tools (plan-installer, etc.) correctly resolve the project root
27
- process.env.CLAUDEOS_ROOT = PROJECT_ROOT;
28
-
29
- // ─── Command handlers (simple — delegate to sub-tools) ───────────
30
- function cmdHealth() {
31
- run(`node "${path.join(TOOLS_DIR, "health-checker/index.js")}"`);
32
- }
33
-
34
- function cmdValidate() {
35
- run(`node "${path.join(TOOLS_DIR, "plan-validator/index.js")}" --check`);
36
- }
37
-
38
- function cmdRestore() {
39
- run(`node "${path.join(TOOLS_DIR, "plan-validator/index.js")}" --execute`);
40
- }
41
-
42
- function cmdRefresh() {
43
- run(`node "${path.join(TOOLS_DIR, "plan-validator/index.js")}" --refresh`);
44
- }
45
-
46
- // ─── Help ───────────────────────────────────────────────────────
47
- function showHelp() {
48
- log(`
49
- ClaudeOS-Core — Auto-generate Claude Code documentation from your source code.
50
-
51
- Usage:
52
- claudeos-core <command>
53
-
54
- Commands:
55
- init Run the full 4-Pass pipeline (analyze → merge → generate → memory scaffold)
56
- health Run all verification tools (health checker)
57
- validate Check Plan disk consistency
58
- refresh Sync disk changes Master Plan
59
- restore Restore all files from Master Plan
60
- memory <sub> L4 memory: compact | score | propose-rules
61
-
62
- Options:
63
- --lang CODE Output language for generated files (required for init)
64
- Supported: en, ko, zh-CN, ja, es, vi, hi, ru, fr, de
65
- If omitted, interactive selection is shown.
66
- --force Skip resume prompt and start fresh (delete previous results)
67
- --help Show this help message
68
- --version Show version
69
-
70
- Examples:
71
- npx claudeos-core init --lang ko # Generate in Korean
72
- npx claudeos-core init --lang ja # Generate in Japanese
73
- npx claudeos-core init # Interactive language selection
74
- npx claudeos-core health # Check everything is consistent
75
- npx claudeos-core restore # Recover from corrupted docs
76
- `);
77
- }
78
-
79
- // ─── Argument parser ────────────────────────────────────────────
80
- function parseArgs(argv) {
81
- const result = { command: null, lang: null };
82
- for (let i = 0; i < argv.length; i++) {
83
- if (argv[i] === "--lang" && i + 1 < argv.length) {
84
- result.lang = argv[++i];
85
- } else if (argv[i].startsWith("--lang=")) {
86
- result.lang = argv[i].split("=")[1];
87
- } else if (argv[i] === "--force" || argv[i] === "-f") {
88
- result.force = true;
89
- } else if (argv[i] === "--help" || argv[i] === "-h") {
90
- // If we already saw a command (e.g. `memory --help`), let that command
91
- // handle --help itself via process.argv. Only promote --help to
92
- // top-level when it appears before any command (e.g. `--help` alone or
93
- // `--help memory`). This lets `memory --help` show memory's subcommand
94
- // help rather than the top-level usage.
95
- if (!result.command) result.command = "--help";
96
- } else if (argv[i] === "--version" || argv[i] === "-v") {
97
- result.command = "--version";
98
- } else if (!argv[i].startsWith("-") && !result.command) {
99
- result.command = argv[i];
100
- }
101
- }
102
- return result;
103
- }
104
-
105
- // ─── Main ───────────────────────────────────────────────────────
106
- const args = process.argv.slice(2);
107
- const parsedArgs = parseArgs(args);
108
- const command = parsedArgs.command;
109
-
110
- if (!command || command === "--help") {
111
- showHelp();
112
- process.exit(0);
113
- }
114
-
115
- if (command === "--version") {
116
- try {
117
- const pkg = JSON.parse(
118
- readFile(path.join(TOOLS_DIR, "package.json"))
119
- );
120
- log(`claudeos-core v${pkg.version}`);
121
- } catch (e) {
122
- log("claudeos-core (version unknown)");
123
- }
124
- process.exit(0);
125
- }
126
-
127
- const commands = {
128
- init: () => cmdInit(parsedArgs),
129
- health: cmdHealth,
130
- validate: cmdValidate,
131
- restore: cmdRestore,
132
- refresh: cmdRefresh,
133
- memory: () => cmdMemory(parsedArgs),
134
- };
135
-
136
- if (!commands[command]) {
137
- log(`Unknown command: ${command}`);
138
- log('Run "claudeos-core --help" for usage.');
139
- process.exit(1);
140
- }
141
-
142
- Promise.resolve().then(() => commands[command]()).catch((e) => {
143
- if (e instanceof InitError) {
144
- log(`\n ❌ ${e.message}\n`);
145
- } else {
146
- console.error(e.message || e);
147
- }
148
- process.exit(1);
149
- });
2
+
3
+ /**
4
+ * ClaudeOS-Core — CLI
5
+ *
6
+ * Node.js replacement for bootstrap.sh with cross-platform support.
7
+ * Usage:
8
+ * npx claudeos-core init --lang ko ← Run 4-Pass pipeline (Korean output)
9
+ * npx claudeos-core init ← Interactive language selection
10
+ * npx claudeos-core health ← Run health checker
11
+ * npx claudeos-core validate ← Run plan validator (--check)
12
+ * npx claudeos-core restore ← Restore from Master Plan
13
+ * npx claudeos-core refresh ← Sync disk → Plan
14
+ * npx claudeos-core memory <sub> ← L4 memory (compact/score/propose-rules)
15
+ * npx claudeos-core --help ← Show help
16
+ *
17
+ * Also works when cloned directly:
18
+ * node claudeos-core-tools/bin/cli.js init
19
+ */
20
+
21
+ const path = require("path");
22
+ const { TOOLS_DIR, PROJECT_ROOT, log, run, readFile } = require("./lib/cli-utils");
23
+ const { cmdInit, InitError } = require("./commands/init");
24
+ const { cmdMemory } = require("./commands/memory");
25
+ const { cmdLint } = require("./commands/lint");
26
+
27
+ // Set env var so sub-tools (plan-installer, etc.) correctly resolve the project root
28
+ process.env.CLAUDEOS_ROOT = PROJECT_ROOT;
29
+
30
+ // ─── Command handlers (simple — delegate to sub-tools) ───────────
31
+ function cmdHealth() {
32
+ run(`node "${path.join(TOOLS_DIR, "health-checker/index.js")}"`);
33
+ }
34
+
35
+ function cmdValidate() {
36
+ run(`node "${path.join(TOOLS_DIR, "plan-validator/index.js")}" --check`);
37
+ }
38
+
39
+ function cmdRestore() {
40
+ run(`node "${path.join(TOOLS_DIR, "plan-validator/index.js")}" --execute`);
41
+ }
42
+
43
+ function cmdRefresh() {
44
+ run(`node "${path.join(TOOLS_DIR, "plan-validator/index.js")}" --refresh`);
45
+ }
46
+
47
+ // ─── Help ───────────────────────────────────────────────────────
48
+ function showHelp() {
49
+ log(`
50
+ ClaudeOS-Core — Auto-generate Claude Code documentation from your source code.
51
+
52
+ Usage:
53
+ claudeos-core <command>
54
+
55
+ Commands:
56
+ init Run the full 4-Pass pipeline (analyze → merge → generate → memory scaffold)
57
+ lint Validate CLAUDE.md structure (language-invariant post-generation check)
58
+ health Run all verification tools (health checker)
59
+ validate Check Plan disk consistency
60
+ refresh Sync disk changes Master Plan
61
+ restore Restore all files from Master Plan
62
+ memory <sub> L4 memory: compact | score | propose-rules
63
+
64
+ Options:
65
+ --lang CODE Output language for generated files (required for init)
66
+ Supported: en, ko, zh-CN, ja, es, vi, hi, ru, fr, de
67
+ If omitted, interactive selection is shown.
68
+ --force Skip resume prompt and start fresh (delete previous results)
69
+ --help Show this help message
70
+ --version Show version
71
+
72
+ Examples:
73
+ npx claudeos-core init --lang ko # Generate in Korean
74
+ npx claudeos-core init --lang ja # Generate in Japanese
75
+ npx claudeos-core init # Interactive language selection
76
+ npx claudeos-core lint # Validate CLAUDE.md structure (any language)
77
+ npx claudeos-core health # Check everything is consistent
78
+ npx claudeos-core restore # Recover from corrupted docs
79
+ `);
80
+ }
81
+
82
+ // ─── Argument parser ────────────────────────────────────────────
83
+ function parseArgs(argv) {
84
+ const result = { command: null, lang: null };
85
+ for (let i = 0; i < argv.length; i++) {
86
+ if (argv[i] === "--lang" && i + 1 < argv.length) {
87
+ result.lang = argv[++i];
88
+ } else if (argv[i].startsWith("--lang=")) {
89
+ result.lang = argv[i].split("=")[1];
90
+ } else if (argv[i] === "--force" || argv[i] === "-f") {
91
+ result.force = true;
92
+ } else if (argv[i] === "--help" || argv[i] === "-h") {
93
+ // If we already saw a command (e.g. `memory --help`), let that command
94
+ // handle --help itself via process.argv. Only promote --help to
95
+ // top-level when it appears before any command (e.g. `--help` alone or
96
+ // `--help memory`). This lets `memory --help` show memory's subcommand
97
+ // help rather than the top-level usage.
98
+ if (!result.command) result.command = "--help";
99
+ } else if (argv[i] === "--version" || argv[i] === "-v") {
100
+ result.command = "--version";
101
+ } else if (!argv[i].startsWith("-") && !result.command) {
102
+ result.command = argv[i];
103
+ }
104
+ }
105
+ return result;
106
+ }
107
+
108
+ // ─── Main ───────────────────────────────────────────────────────
109
+ const args = process.argv.slice(2);
110
+ const parsedArgs = parseArgs(args);
111
+ const command = parsedArgs.command;
112
+
113
+ if (!command || command === "--help") {
114
+ showHelp();
115
+ process.exit(0);
116
+ }
117
+
118
+ if (command === "--version") {
119
+ try {
120
+ const pkg = JSON.parse(
121
+ readFile(path.join(TOOLS_DIR, "package.json"))
122
+ );
123
+ log(`claudeos-core v${pkg.version}`);
124
+ } catch (e) {
125
+ log("claudeos-core (version unknown)");
126
+ }
127
+ process.exit(0);
128
+ }
129
+
130
+ const commands = {
131
+ init: () => cmdInit(parsedArgs),
132
+ lint: () => cmdLint(parsedArgs),
133
+ health: cmdHealth,
134
+ validate: cmdValidate,
135
+ restore: cmdRestore,
136
+ refresh: cmdRefresh,
137
+ memory: () => cmdMemory(parsedArgs),
138
+ };
139
+
140
+ if (!commands[command]) {
141
+ log(`Unknown command: ${command}`);
142
+ log('Run "claudeos-core --help" for usage.');
143
+ process.exit(1);
144
+ }
145
+
146
+ Promise.resolve().then(() => commands[command]()).catch((e) => {
147
+ if (e instanceof InitError) {
148
+ log(`\n ❌ ${e.message}\n`);
149
+ } else {
150
+ console.error(e.message || e);
151
+ }
152
+ process.exit(1);
153
+ });