claudeos-core 2.4.0 → 2.4.1

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.
package/README.zh-CN.md CHANGED
@@ -7,7 +7,11 @@
7
7
  [![license](https://img.shields.io/npm/l/claudeos-core.svg?color=blue)](LICENSE)
8
8
  [![downloads](https://img.shields.io/npm/dm/claudeos-core.svg?logo=npm&color=blue&label=downloads)](https://www.npmjs.com/package/claudeos-core)
9
9
 
10
- **从你的实际源代码自动生成 Claude Code 文档。** 一个 CLI 工具,先对项目进行静态分析,再运行 4-pass Claude 流水线生成 `.claude/rules/`、standards、skills 和 guides 这样 Claude Code 遵循的就是**你项目的**约定,而不是通用约定。
10
+ **让 Claude Code 第一次就遵循 _你项目的_ 约定而不是 generic 默认值。**
11
+
12
+ deterministic Node.js scanner 先读取你的代码,然后 4-pass Claude 流水线写出完整的文档集 — `CLAUDE.md` + 自动加载的 `.claude/rules/` + standards + skills + L4 memory。10 种输出语言、5 个 post-generation validator,以及阻止 LLM 编造代码中不存在的文件或 framework 的明确 path allowlist。
13
+
14
+ 在 [**12 个栈**](#supported-stacks)上即开即用 (含 monorepo) — 一条 `npx` 命令,无需配置,中断可 resume,重跑 idempotent。
11
15
 
12
16
  ```bash
13
17
  npx claudeos-core init
@@ -19,18 +23,28 @@ npx claudeos-core init
19
23
 
20
24
  ## 这是什么?
21
25
 
22
- 你在用 Claude Code。它很聪明,但它不知道**你项目的约定**:
23
- - 你的团队用 MyBatis,但 Claude 生成 JPA 代码。
24
- - 你的封装是 `ApiResponse.ok()`,但 Claude `ResponseEntity.success()`。
25
- - 你的包是 `controller/order/`,但 Claude 创建 `order/controller/`。
26
+ 你在用 Claude Code。它很强大,但每次会话都从零开始 — 它对 _你的_ 项目结构没有任何记忆。所以它会回退到"看上去通用"的默认值,这些默认值很少和你团队实际的做法匹配:
27
+
28
+ - 你的团队用 **MyBatis**,但 Claude 生成 JPA repository。
29
+ - 你的响应封装是 `ApiResponse.ok()`,但 Claude 写的是 `ResponseEntity.success()`。
30
+ - 你的包是 layer-first (`controller/order/`),但 Claude 创建的是 domain-first (`order/controller/`)。
31
+ - 你的错误走的是中央 middleware,但 Claude 在每个 endpoint 散布 `try/catch`。
32
+
33
+ 你会希望每个项目都有一份 `.claude/rules/` — Claude Code 每个会话自动加载 — 但每个新 repo 手写这些 rules 要花数小时,且代码演进时会 drift。
34
+
35
+ **ClaudeOS-Core 从你的实际源代码为你写好它们。** deterministic Node.js scanner 先读你的项目 (栈、ORM、包 layout、约定、文件路径)。然后 4-pass Claude 流水线把抽取出的事实变成完整的文档集:
26
36
 
27
- 于是你花了大量时间去修正每一个生成的文件。
37
+ - **`CLAUDE.md`** — Claude 每次会话先读的项目索引
38
+ - **`.claude/rules/`** — 按分类自动加载的 rules (`00.core` / `10.backend` / `20.frontend` / `30.security-db` / `40.infra` / `60.memory` / `70.domains` / `80.verification`)
39
+ - **`claudeos-core/standard/`** — 参考文档 (每条 rule 背后的"为什么")
40
+ - **`claudeos-core/skills/`** — 可复用模式 (CRUD scaffolding、页面模板)
41
+ - **`claudeos-core/memory/`** — 随项目共同生长的 decision log + failure pattern
28
42
 
29
- **ClaudeOS-Core 解决这个问题。** 它扫描你的实际源代码,推断出你的约定,然后把一整套规则写入 `.claude/rules/` 这是 Claude Code 自动读取的目录。下次你说 *"给 orders 做一个 CRUD"*,Claude 第一次就会按你的约定来。
43
+ 因为 scanner 把一份明确的 path allowlist 交给 Claude,LLM **无法编造代码里不存在的文件或 framework**。5 post-generation validator (`claude-md-validator`、`content-validator`、`pass-json-validator`、`plan-validator`、`sync-checker`) 在出货前验证输出 — language-invariant,无论你用英语、中文还是其他 8 种语言生成,都适用同一套规则。
30
44
 
31
45
  ```
32
- 之前: 你 → Claude Code → "看上去还行" 的代码 → 手动修正
33
- 之后: 你 → Claude Code → 与项目匹配的代码 → 直接发布
46
+ 之前: 你 → Claude Code → "看上去还行" 的代码 → 每次手动修正
47
+ 之后: 你 → Claude Code → 与你项目匹配的代码 → 直接发布
34
48
  ```
35
49
 
36
50
  ---
@@ -44,7 +58,7 @@ npx claudeos-core init
44
58
  </p>
45
59
 
46
60
  <details>
47
- <summary><strong>📺 终端输出(文本版,便于搜索和复制)</strong></summary>
61
+ <summary><strong>📺 终端输出 (文本版,便于搜索和复制)</strong></summary>
48
62
 
49
63
  ```text
50
64
  ╔════════════════════════════════════════════════════╗
@@ -119,37 +133,45 @@ npx claudeos-core init
119
133
  </details>
120
134
 
121
135
  <details>
122
- <summary><strong>📄 生成的 <code>CLAUDE.md</code> 节选(实际输出)</strong></summary>
136
+ <summary><strong>📄 生成的 <code>CLAUDE.md</code> 节选 (实际输出 — Section 1 + 2)</strong></summary>
123
137
 
124
138
  ```markdown
125
- ## 4. Core Architecture
126
-
127
- ### Core Patterns
128
-
129
- - **Hexagonal ports & adapters**: domain ports live in `io.spring.core.{aggregate}`
130
- and are implemented by `io.spring.infrastructure.repository.MyBatis{Aggregate}Repository`.
131
- The domain layer has zero MyBatis imports.
132
- - **CQRS-lite read/write split (same DB)**: write side goes through repository ports
133
- + entities; read side is a separate `readservice` package whose `@Mapper`
134
- interfaces return `*Data` DTOs directly (no entity hydration).
135
- - **No aggregator/orchestrator layer**: multi-source orchestration happens inside
136
- application services (e.g., `ArticleQueryService`); there is no `*Aggregator`
137
- class in the codebase.
138
- - **Application-supplied UUIDs**: entity constructors assign their own UUID; PK is
139
- passed via `#{user.id}` on INSERT. The global
140
- `mybatis.configuration.use-generated-keys=true` flag is dead config
141
- (auto-increment is unused).
142
- - **JWT HS512 authentication**: `io.spring.infrastructure.service.DefaultJwtService`
143
- is the sole token subject in/out; `io.spring.api.security.JwtTokenFilter`
144
- extracts the token at the servlet layer.
139
+ # CLAUDE.md spring-boot-realworld-example-app
140
+
141
+ > Reference implementation of the RealWorld backend specification on
142
+ > Java 11 + Spring Boot 2.6, exposing both REST and GraphQL endpoints
143
+ > over a hexagonal MyBatis persistence layer.
144
+
145
+ ## 1. Role Definition
146
+
147
+ As the senior developer for this repository, you are responsible for
148
+ writing, modifying, and reviewing code. Responses must be written in English.
149
+ A Java Spring Boot REST + GraphQL API server organized around a hexagonal
150
+ (ports & adapters) architecture, with a CQRS-lite read/write split inside
151
+ an XML-driven MyBatis persistence layer and JWT-based authentication.
152
+
153
+ ## 2. Project Overview
154
+
155
+ | Item | Value |
156
+ |---|---|
157
+ | Language | Java 11 |
158
+ | Framework | Spring Boot 2.6.3 |
159
+ | Build Tool | Gradle (Groovy DSL) |
160
+ | Persistence | MyBatis 3 via `mybatis-spring-boot-starter:2.2.2` (no JPA) |
161
+ | Database | SQLite (`org.xerial:sqlite-jdbc:3.36.0.3`) — `dev.db` (default), `:memory:` (test) |
162
+ | Migration | Flyway — single baseline `V1__create_tables.sql` |
163
+ | API Style | REST (`io.spring.api.*`) + GraphQL via Netflix DGS `:4.9.21` |
164
+ | Authentication | JWT HS512 (`jjwt-api:0.11.2`) + Spring Security `PasswordEncoder` |
165
+ | Server Port | 8080 (default) |
166
+ | Test Stack | JUnit Jupiter 5, Mockito, AssertJ, rest-assured, spring-mock-mvc |
145
167
  ```
146
168
 
147
- 注意:上面所有的论断都基于实际源码类名、包路径、配置键、dead-config 标记,都是 scanner 在 Claude 写文件之前先提取好的。
169
+ 上面所有的值精确的依赖坐标、`dev.db` 文件名、`V1__create_tables.sql` 迁移名、"no JPA" — 都是 scanner 在 Claude 写文件之前先从 `build.gradle` / `application.properties` / 源码树中提取出来的。没有任何东西是猜的。
148
170
 
149
171
  </details>
150
172
 
151
173
  <details>
152
- <summary><strong>🛡️ 一个被自动加载的真实 rule 文件 (<code>.claude/rules/10.backend/03.data-access-rules.md</code>)</strong></summary>
174
+ <summary><strong>🛡️ 一个被自动加载的真实 rule 文件 (<code>.claude/rules/10.backend/01.controller-rules.md</code>)</strong></summary>
153
175
 
154
176
  ````markdown
155
177
  ---
@@ -157,68 +179,83 @@ paths:
157
179
  - "**/*"
158
180
  ---
159
181
 
160
- # Data Access Rules
182
+ # Controller Rules
183
+
184
+ ## REST (`io.spring.api.*`)
161
185
 
162
- ## XML-only SQL
163
- - Every SQL statement lives in `src/main/resources/mapper/*.xml`.
164
- NO `@Select` / `@Insert` / `@Update` / `@Delete` annotations on `@Mapper` methods.
165
- - Each `@Mapper` interface has exactly one XML file at
166
- `src/main/resources/mapper/{InterfaceName}.xml`.
167
- - `<mapper namespace="...">` MUST be the fully qualified Java interface name.
168
- The single existing exception is `TransferData.xml` (free-form `transfer.data`).
186
+ - Controllers are the SOLE response wrapper for HTTP — no aggregator/facade above them.
187
+ Return `ResponseEntity<?>` or a body Spring serializes via `JacksonCustomizations`.
188
+ - Each controller method calls exactly ONE application service method. Multi-source
189
+ composition lives in the application service.
190
+ - Controllers MUST NOT import `io.spring.infrastructure.*`. No direct `@Mapper` access.
191
+ - Validate command-param arguments with `@Valid`. Custom JSR-303 constraints live under
192
+ `io.spring.application.{aggregate}.*`.
193
+ - Resolve the current user via `@AuthenticationPrincipal User`.
194
+ - Let exceptions propagate to `io.spring.api.exception.CustomizeExceptionHandler`
195
+ (`@ControllerAdvice`). Do NOT `try/catch` business exceptions inside the controller.
169
196
 
170
- ## Dynamic SQL
171
- - `<if>` predicates MUST guard both null and empty:
172
- `<if test="X != null and X != ''">`. Empty-only is the existing HIGH-severity bug pattern.
173
- - Prefer `LIMIT n OFFSET m` over MySQL-style `LIMIT m, n`.
197
+ ## GraphQL (`io.spring.graphql.*`)
198
+
199
+ - DGS components (`@DgsComponent`) are the sole GraphQL response wrappers.
200
+ Use `@DgsQuery` / `@DgsData` / `@DgsMutation`.
201
+ - Resolve the current user via `io.spring.graphql.SecurityUtil.getCurrentUser()`.
174
202
 
175
203
  ## Examples
176
204
 
177
205
  ✅ Correct:
178
- ```xml
179
- <update id="update">
180
- UPDATE articles
181
- <set>
182
- <if test="article.title != null and article.title != ''">title = #{article.title},</if>
183
- updated_at = #{article.updatedAt}
184
- </set>
185
- WHERE id = #{article.id}
186
- </update>
206
+ ```java
207
+ @PostMapping
208
+ public ResponseEntity<?> createArticle(@AuthenticationPrincipal User user,
209
+ @Valid @RequestBody NewArticleParam param) {
210
+ Article article = articleCommandService.createArticle(param, user);
211
+ ArticleData data = articleQueryService.findById(article.getId(), user)
212
+ .orElseThrow(ResourceNotFoundException::new);
213
+ return ResponseEntity.ok(Map.of("article", data));
214
+ }
187
215
  ```
188
216
 
189
217
  ❌ Incorrect:
190
- ```xml
191
- <mapper namespace="article.mapper"> <!-- NO — namespace MUST be FQCN -->
218
+ ```java
219
+ @PostMapping
220
+ public ResponseEntity<?> create(@RequestBody NewArticleParam p) {
221
+ try {
222
+ articleCommandService.createArticle(p, currentUser);
223
+ } catch (Exception e) { // NO — let CustomizeExceptionHandler handle it
224
+ return ResponseEntity.status(500).body(e.getMessage()); // NO — leaks raw message
225
+ }
226
+ return ResponseEntity.ok().build();
227
+ }
192
228
  ```
193
229
  ````
194
230
 
195
- `paths: ["**/*"]` glob 表示无论你在该项目里编辑哪个文件,Claude Code 都会自动加载这条 rule。✅/❌ 示例直接来自这个代码库的实际约定和已有的 bug 模式。
231
+ `paths: ["**/*"]` glob 表示无论你在该项目里编辑哪个文件,Claude Code 都会自动加载这条 rule。rule 中的每个类名、包路径、exception handler 都直接来自被扫描的源代码 — 包括项目实际的 `CustomizeExceptionHandler` 与 `JacksonCustomizations`。
196
232
 
197
233
  </details>
198
234
 
199
235
  <details>
200
- <summary><strong>🧠 自动生成的 <code>decision-log.md</code> 种子(实际输出)</strong></summary>
236
+ <summary><strong>🧠 自动生成的 <code>decision-log.md</code> 种子 (实际输出)</strong></summary>
201
237
 
202
238
  ```markdown
203
- ## 2026-04-26 — CQRS-lite read/write split inside the persistence layer
204
-
205
- - **Context:** Writes go through `core.*Repository` port → `MyBatis*Repository`
206
- adapter → `io.spring.infrastructure.mybatis.mapper.{Aggregate}Mapper`.
207
- Reads bypass the domain port: application service →
208
- `io.spring.infrastructure.mybatis.readservice.{Concept}ReadService` directly,
209
- returning flat `*Data` DTOs from `io.spring.application.data.*`.
210
- - **Options considered:** Single repository surface returning hydrated entities
211
- for both reads and writes.
212
- - **Decision:** Same database, two `@Mapper` packages — `mapper/` (write side,
213
- operates on core entities) and `readservice/` (read side, returns `*Data` DTOs).
214
- Read DTOs avoid entity hydration overhead.
215
- - **Consequences:** Reads are NOT routed through the domain port this is
216
- intentional, not a bug. Application services may inject both a `*Repository`
217
- (writes) and one or more `*ReadService` interfaces (reads) at the same time.
218
- Do NOT add hydrate-then-map glue in the read path.
239
+ ## 2026-04-26 — Hexagonal ports & adapters with MyBatis-only persistence
240
+
241
+ - **Context:** `io.spring.core.*` exposes `*Repository` ports (e.g.,
242
+ `io.spring.core.article.ArticleRepository`) implemented by
243
+ `io.spring.infrastructure.repository.MyBatis*Repository` adapters.
244
+ The domain layer has zero `org.springframework.*` /
245
+ `org.apache.ibatis.*` / `io.spring.infrastructure.*` imports.
246
+ - **Options considered:** JPA/Hibernate, Spring Data, MyBatis-Plus
247
+ `BaseMapper`. None adopted.
248
+ - **Decision:** MyBatis 3 (`mybatis-spring-boot-starter:2.2.2`) with
249
+ hand-written XML statements under `src/main/resources/mapper/*.xml`.
250
+ Hexagonal port/adapter wiring keeps the domain framework-free.
251
+ - **Consequences:** Every SQL lives in XML`@Select`/`@Insert`/`@Update`/`@Delete`
252
+ annotations are forbidden. New aggregates require both a
253
+ `core.{aggregate}.{Aggregate}Repository` port AND a
254
+ `MyBatis{Aggregate}Repository` adapter; introducing a JPA repository would
255
+ split the persistence model.
219
256
  ```
220
257
 
221
- Pass 4 用从 `pass2-merged.json` 中提取的架构决策为 `decision-log.md` 播种 — 这样以后的会话不仅记得代码库 _长成什么样_,也记得 _为什么_ 这样。
258
+ Pass 4 用从 `pass2-merged.json` 提取的架构决策为 `decision-log.md` 播种,这样以后的会话不仅记得代码库 _长成什么样_,也记得 _为什么_ 这样。每个被考虑过的选项 ("JPA/Hibernate"、"MyBatis-Plus") 和每个 consequence 都基于实际的 `build.gradle` 依赖块。
222
259
 
223
260
  </details>
224
261
 
@@ -232,7 +269,7 @@ Pass 4 用从 `pass2-merged.json` 中提取的架构决策为 `decision-log.md`
232
269
  # 1. 进入你的项目根目录
233
270
  cd my-spring-boot-project
234
271
 
235
- # 2. 运行 init(它会分析你的代码并请求 Claude 写出 rules)
272
+ # 2. 运行 init (它会分析你的代码并请求 Claude 写出 rules)
236
273
  npx claudeos-core init
237
274
 
238
275
  # 3. 完成。打开 Claude Code 开始编码 — rules 已经加载好了。
@@ -254,7 +291,7 @@ your-project/
254
291
  │ ├── 70.domains/{type}/ (按域 rules,type = backend|frontend)
255
292
  │ └── 80.verification/ (测试策略 + 构建验证提醒)
256
293
  ├── claudeos-core/
257
- │ ├── standard/ ← 参考文档(镜像分类结构)
294
+ │ ├── standard/ ← 参考文档 (镜像分类结构)
258
295
  │ │ ├── 00.core/ (项目概览、架构、命名)
259
296
  │ │ ├── 10.backend/ (后端 reference — 仅当存在后端栈)
260
297
  │ │ ├── 20.frontend/ (前端 reference — 仅当存在前端栈)
@@ -271,19 +308,23 @@ your-project/
271
308
  └── CLAUDE.md (Claude 最先读取的索引)
272
309
  ```
273
310
 
274
- `rules/` 与 `standard/` 之间共享相同数字 prefix 的分类代表同一概念领域(例如 `10.backend` rules ↔ `10.backend` standards)。Rules-only 分类:`50.sync`(文档同步提醒)、`60.memory`(Pass 4 memory)。Standard-only 分类:`90.optional`(无强制力的栈相关附加)。其他 prefix(`00`、`10`、`20`、`30`、`40`、`70`、`80`)在 `rules/` 和 `standard/` 中都存在。现在 Claude Code 认识你的项目了。
311
+ `rules/` 与 `standard/` 之间共享相同数字 prefix 的分类代表同一概念领域 (例如 `10.backend` rules ↔ `10.backend` standards)。Rules-only 分类:`50.sync` (文档同步提醒)、`60.memory` (Pass 4 memory)。Standard-only 分类:`90.optional` (无强制力的栈相关附加)。其他 prefix (`00`、`10`、`20`、`30`、`40`、`70`、`80`) 在 `rules/` 和 `standard/` 中都存在。现在 Claude Code 认识你的项目了。
275
312
 
276
313
  ---
277
314
 
278
315
  ## 适合谁?
279
316
 
280
- | 你是… | 这工具帮你… |
317
+ | 你是… | 这个工具消除的痛点 |
281
318
  |---|---|
282
- | **用 Claude Code 启动新项目的独立开发者** | 完全跳过" Claude 我的约定"这一步 |
283
- | **维护共享标准的团队负责人** | 自动化 `.claude/rules/` 的繁琐维护 |
284
- | **已经在用 Claude Code 但厌倦修代码的人** | Claude 跟随**你的**模式,而非"看上去通用"的模式 |
319
+ | **用 Claude Code 启动新项目的独立开发者** | "每个会话都要教 Claude 我的约定" — 消失。`CLAUDE.md` + 8 个分类 `.claude/rules/` 一次生成完毕。 |
320
+ | **维护跨 repo 共享标准的团队负责人** | 改包名、换 ORM、改 response wrapper 时 `.claude/rules/` drift。ClaudeOS-Core 以 deterministic 方式重新同步 — 同输入 → byte-identical 输出,无 diff 噪音。 |
321
+ | **已经在用 Claude Code 但厌倦修代码** | 错误的 response wrapper、错误的包 layout、明明用 MyBatis 却生成 JPA、明明有中央 middleware 却散布 `try/catch`。scanner 提取你真实的约定;每个 Claude pass 都基于明确的 path allowlist 运行。 |
322
+ | **新 repo onboarding** (既有项目 / 加入团队) | 在 repo 上跑 `init`,得到一份活的架构地图:CLAUDE.md 里的 stack 表、按 layer 的 rules with ✅/❌ 示例、用主要决策的"为什么"播种好的 decision log (JPA vs MyBatis、REST vs GraphQL 等)。读 5 个文件胜过读 5,000 个源文件。 |
323
+ | **使用中文 / 韩语 / 日语 / 其他 7 种语言** | 大多数 Claude Code rule generator 只支持英文。ClaudeOS-Core 用 **10 种语言** (`en/ko/ja/zh-CN/es/vi/hi/ru/fr/de`) 写完整套,并提供 **byte-identical 结构验证** — 不论输出语言如何,`claude-md-validator` 给出同一个 verdict。 |
324
+ | **在 monorepo 中工作** (Turborepo、pnpm/yarn workspaces、Lerna) | 一次运行同时分析 backend + frontend 域,各用独立 prompt;`apps/*/` 与 `packages/*/` 自动 walk;按栈输出的 rules 落在 `70.domains/{type}/` 之下。 |
325
+ | **OSS 贡献者或实验项目** | 输出对 gitignore 友好 — `claudeos-core/` 是你的本地工作目录,只有 `CLAUDE.md` + `.claude/` 需要随仓库发布。中断时 resume-safe;重跑 idempotent (不带 `--force` 时手工编辑会被保留)。 |
285
326
 
286
- **不适合的场景:** 你想要一个开箱即用的预设 agents/skills/rules 包,不需要 scan 步骤(参见 [docs/zh-CN/comparison.md](docs/zh-CN/comparison.md));或者你的项目还不属于[受支持的栈](#supported-stacks)之一。
327
+ **不适合的场景:** 你想要无需 scan 步骤、第一天就开箱即用的 one-size-fits-all 预设 agents/skills/rules (各工具的定位见 [docs/zh-CN/comparison.md](docs/zh-CN/comparison.md));你的项目还不属于[受支持的栈](#supported-stacks);或者你只需要单一 `CLAUDE.md` (内置的 `claude /init` 已经够用 — 不需要再装别的工具)。
287
328
 
288
329
  ---
289
330
 
@@ -296,9 +337,28 @@ ClaudeOS-Core 把通常的 Claude Code 工作流反过来:
296
337
  本工具: 代码读出你的栈 → 代码把已确认的事实交给 Claude → Claude 基于事实写文档
297
338
  ```
298
339
 
299
- 核心思想:**Node.js scanner 先读你的源代码**(deterministic,没有 AI),然后 4-pass Claude 流水线在 scanner 找到的事实约束下写文档。Claude 没法编造代码里实际不存在的路径或框架。
340
+ 流水线分 **三个阶段**运行,LLM 调用的两侧都有代码:
341
+
342
+ **1. Step A — Scanner (deterministic,无 LLM)。** Node.js scanner walk 你的项目根,读 `package.json` / `build.gradle` / `pom.xml` / `pyproject.toml`,解析 `.env*` 文件 (对 `PASSWORD/SECRET/TOKEN/JWT_SECRET/...` 等敏感变量做 redaction),分类你的架构模式 (Java 5 模式 A/B/C/D/E、Kotlin CQRS / 多模块、Next.js App vs. Pages Router、FSD、components-pattern),发现领域,并构建一份所有存在的源文件路径的明确 allowlist。输出:`project-analysis.json` — 后续所有步骤的单一 source of truth。
343
+
344
+ **2. Step B — 4-Pass Claude 流水线 (受 Step A 的事实约束)。**
345
+ - **Pass 1** 按域组读取代表文件,每个域抽取 ~50–100 个约定 — response wrapper、logging library、error handling、命名约定、test pattern。每个域组运行一次 (`max 4 domains, 40 files per group`),所以 context 永远不会 overflow。
346
+ - **Pass 2** 把所有按域的分析合并成项目级全景图,在域之间不一致时挑选 dominant 约定。
347
+ - **Pass 3** 写出 `CLAUDE.md` + `.claude/rules/` + `claudeos-core/standard/` + skills + guides — 切分成 stage (`3a` facts → `3b-core/3b-N` rules+standards → `3c-core/3c-N` skills+guides → `3d-aux` database+mcp-guide),即使 `pass2-merged.json` 很大,每个 stage 的 prompt 也能 fit 进 LLM 的 context window。≥16 域的项目把 3b/3c 进一步切成 ≤15 域 batch。
348
+ - **Pass 4** 为 L4 memory layer (`decision-log.md`、`failure-patterns.md`、`compaction.md`、`auto-rule-update.md`) 播种,并补充通用 scaffold rules。Pass 4 **禁止修改 `CLAUDE.md`** — Pass 3 的 Section 8 是 authoritative。
349
+
350
+ **3. Step C — Verification (deterministic,无 LLM)。** 5 个 validator 检查输出:
351
+ - `claude-md-validator` — 对 `CLAUDE.md` 做 25 项结构检查 (8 个 section、H3/H4 计数、memory file uniqueness、T1 canonical heading invariant)。Language-invariant:无论 `--lang` 是什么,verdict 相同。
352
+ - `content-validator` — 10 项内容检查,包括 path-claim 验证 (`STALE_PATH` 抓出编造的 `src/...` 引用) 和 MANIFEST drift 检测。
353
+ - `pass-json-validator` — Pass 1/2/3/4 JSON well-formedness + stack-aware section 计数。
354
+ - `plan-validator` — plan ↔ disk 一致性 (legacy,自 v2.1.0 起大部分 no-op)。
355
+ - `sync-checker` — 跨 7 个被追踪目录的 disk ↔ `sync-map.json` 注册一致性。
356
+
357
+ 三档严重度 (`fail` / `warn` / `advisory`),所以对用户能手动修复的 LLM 幻觉,warning 不会卡死 CI。
358
+
359
+ 把整个流程绑在一起的 invariant:**Claude 只能引用代码中实际存在的路径**,因为 Step A 给了它一份 finite allowlist。如果 LLM 仍然试图编造 (罕见但在某些 seed 上确实会发生),Step C 会在 docs 出货前抓出来。
300
360
 
301
- 完整架构见 [docs/zh-CN/architecture.md](docs/zh-CN/architecture.md)。
361
+ 每个 pass 的细节、基于 marker 的 resume、用于绕过 Claude Code `.claude/` sensitive-path block 的 staged-rules workaround,以及 stack 检测内部细节,见 [docs/zh-CN/architecture.md](docs/zh-CN/architecture.md)。
302
362
 
303
363
  ---
304
364
 
@@ -310,7 +370,7 @@ ClaudeOS-Core 把通常的 Claude Code 工作流反过来:
310
370
 
311
371
  **Frontend:** Node/Next.js · Node/Vite · Angular · Vue/Nuxt
312
372
 
313
- 多栈项目(例如 Spring Boot 后端 + Next.js 前端)开箱即用。
373
+ 多栈项目 (例如 Spring Boot 后端 + Next.js 前端) 开箱即用。
314
374
 
315
375
  每个 scanner 的检测规则和提取内容,见 [docs/zh-CN/stacks.md](docs/zh-CN/stacks.md)。
316
376
 
@@ -327,14 +387,14 @@ npx claudeos-core init
327
387
  # 手动改了 standards 或 rules 之后
328
388
  npx claudeos-core lint
329
389
 
330
- # 健康检查(commit 前或在 CI 中运行)
390
+ # 健康检查 (commit 前或在 CI 中运行)
331
391
  npx claudeos-core health
332
392
  ```
333
393
 
334
394
  memory layer 维护用的另外两条:
335
395
 
336
396
  ```bash
337
- # 压缩 failure-patterns 日志(定期运行)
397
+ # 压缩 failure-patterns 日志 (定期运行)
338
398
  npx claudeos-core memory compact
339
399
 
340
400
  # 把高频 failure pattern 提升为提议规则
@@ -347,7 +407,7 @@ npx claudeos-core memory propose-rules
347
407
 
348
408
  ## 它有什么不同
349
409
 
350
- 大多数 Claude Code 文档工具是从描述出发(你告诉工具,工具告诉 Claude)。ClaudeOS-Core 是从你的实际源代码出发(工具读取,工具把已确认的事实告诉 Claude,Claude 只写已确认的内容)。
410
+ 大多数 Claude Code 文档工具是从描述出发 (你告诉工具,工具告诉 Claude)。ClaudeOS-Core 是从你的实际源代码出发 (工具读取,工具把已确认的事实告诉 Claude,Claude 只写已确认的内容)。
351
411
 
352
412
  三个具体后果:
353
413
 
@@ -359,19 +419,19 @@ npx claudeos-core memory propose-rules
359
419
 
360
420
  ---
361
421
 
362
- ## 验证(post-generation)
422
+ ## 验证 (post-generation)
363
423
 
364
424
  Claude 写完文档后,代码会去验证。5 个独立 validator:
365
425
 
366
426
  | Validator | 它检查什么 | 由谁触发 |
367
427
  |---|---|---|
368
- | `claude-md-validator` | CLAUDE.md 的结构性不变量(8 sections,language-invariant) | `claudeos-core lint` |
369
- | `content-validator` | 引用的路径是否真实存在;manifest 一致性 | `health`(advisory) |
370
- | `pass-json-validator` | Pass 1 / 2 / 3 / 4 的输出是 well-formed JSON | `health`(warn) |
371
- | `plan-validator` | 保存的 plan 与 disk 上的内容一致 | `health`(fail-on-error) |
372
- | `sync-checker` | Disk 文件与 `sync-map.json` 的注册项一致(orphaned/unregistered 检测) | `health`(fail-on-error) |
428
+ | `claude-md-validator` | CLAUDE.md 的结构性不变量 (8 sections,language-invariant) | `claudeos-core lint` |
429
+ | `content-validator` | 引用的路径是否真实存在;manifest 一致性 | `health` (advisory) |
430
+ | `pass-json-validator` | Pass 1 / 2 / 3 / 4 的输出是 well-formed JSON | `health` (warn) |
431
+ | `plan-validator` | 保存的 plan 与 disk 上的内容一致 | `health` (fail-on-error) |
432
+ | `sync-checker` | Disk 文件与 `sync-map.json` 的注册项一致 (orphaned/unregistered 检测) | `health` (fail-on-error) |
373
433
 
374
- `health-checker` 用三档严重度(fail / warn / advisory)编排这 4 个运行时 validator,并以适合 CI 的 exit code 退出。`claude-md-validator` 通过 `lint` 命令单独运行,因为结构 drift 是 re-init 信号,不是软警告。可随时运行:
434
+ `health-checker` 用三档严重度 (fail / warn / advisory) 编排这 4 个运行时 validator,并以适合 CI 的 exit code 退出。`claude-md-validator` 通过 `lint` 命令单独运行,因为结构 drift 是 re-init 信号,不是软警告。可随时运行:
375
435
 
376
436
  ```bash
377
437
  npx claudeos-core health
@@ -381,7 +441,7 @@ npx claudeos-core health
381
441
 
382
442
  ---
383
443
 
384
- ## Memory Layer(可选,适合长期项目)
444
+ ## Memory Layer (可选,适合长期项目)
385
445
 
386
446
  v2.0 起,ClaudeOS-Core 会写出一个包含 4 个文件的 `claudeos-core/memory/` 文件夹:
387
447
 
@@ -402,19 +462,19 @@ memory 模型与生命周期,见 [docs/zh-CN/memory-layer.md](docs/zh-CN/memory-
402
462
  A: 不需要。ClaudeOS-Core 使用你已安装的 Claude Code — 它把 prompt 通过管道送给本机的 `claude -p`。不用额外开账号。
403
463
 
404
464
  **Q: 这会覆盖我现有的 CLAUDE.md 或 `.claude/rules/` 吗?**
405
- A: 在新项目上首次运行:它会创建。不带 `--force` 重新运行:保留你的修改 — 上一次运行的 pass marker 会被检测到,对应的 pass 被跳过。带 `--force` 重新运行:全部清掉重新生成(你的修改会丢失 — 这就是 `--force` 的含义)。见 [docs/zh-CN/safety.md](docs/zh-CN/safety.md)。
465
+ A: 在新项目上首次运行:它会创建。不带 `--force` 重新运行:保留你的修改 — 上一次运行的 pass marker 会被检测到,对应的 pass 被跳过。带 `--force` 重新运行:全部清掉重新生成 (你的修改会丢失 — 这就是 `--force` 的含义)。见 [docs/zh-CN/safety.md](docs/zh-CN/safety.md)。
406
466
 
407
467
  **Q: 我的栈不被支持。可以加吗?**
408
468
  A: 可以。新栈需要约 3 个 prompt 模板 + 一个 domain scanner。8 步指南见 [CONTRIBUTING.md](CONTRIBUTING.md)。
409
469
 
410
- **Q: 如何用韩语(或其他语言)生成文档?**
470
+ **Q: 如何用韩语 (或其他语言) 生成文档?**
411
471
  A: `npx claudeos-core init --lang ko`。支持 10 种语言:en、ko、ja、zh-CN、es、vi、hi、ru、fr、de。
412
472
 
413
473
  **Q: 它能用于 monorepo 吗?**
414
- A: 可以 — Turborepo(`turbo.json`)、pnpm workspaces(`pnpm-workspace.yaml`)、Lerna(`lerna.json`)和 npm/yarn workspaces(`package.json#workspaces`)由 stack-detector 检测。每个 app 拥有独立分析。其他 monorepo 布局(例如 NX)不会被特别检测,但通用的 `apps/*/` 与 `packages/*/` 模式仍会被各栈 scanner 拾取。
474
+ A: 可以 — Turborepo (`turbo.json`)、pnpm workspaces (`pnpm-workspace.yaml`)、Lerna (`lerna.json`) 和 npm/yarn workspaces (`package.json#workspaces`) 由 stack-detector 检测。每个 app 拥有独立分析。其他 monorepo 布局 (例如 NX) 不会被特别检测,但通用的 `apps/*/` 与 `packages/*/` 模式仍会被各栈 scanner 拾取。
415
475
 
416
476
  **Q: 如果 Claude Code 生成了我不同意的 rules 怎么办?**
417
- A: 直接编辑。然后运行 `npx claudeos-core lint` 验证 CLAUDE.md 在结构上仍然有效。在后续 `init` 运行(不带 `--force`)中,你的修改会被保留 — resume 机制会跳过已有 marker 的 pass。
477
+ A: 直接编辑。然后运行 `npx claudeos-core lint` 验证 CLAUDE.md 在结构上仍然有效。在后续 `init` 运行 (不带 `--force`) 中,你的修改会被保留 — resume 机制会跳过已有 marker 的 pass。
418
478
 
419
479
  **Q: 在哪里报告 bug?**
420
480
  A: [GitHub Issues](https://github.com/claudeos-core/claudeos-core/issues)。安全相关问题见 [SECURITY.md](SECURITY.md)。
@@ -425,16 +485,16 @@ A: [GitHub Issues](https://github.com/claudeos-core/claudeos-core/issues)。安
425
485
 
426
486
  | 主题 | 阅读 |
427
487
  |---|---|
428
- | 4-pass 流水线如何工作(比图更深入) | [docs/zh-CN/architecture.md](docs/zh-CN/architecture.md) |
429
- | 架构的可视化图示(Mermaid) | [docs/zh-CN/diagrams.md](docs/zh-CN/diagrams.md) |
488
+ | 4-pass 流水线如何工作 (比图更深入) | [docs/zh-CN/architecture.md](docs/zh-CN/architecture.md) |
489
+ | 架构的可视化图示 (Mermaid) | [docs/zh-CN/diagrams.md](docs/zh-CN/diagrams.md) |
430
490
  | Stack 检测 — 每个 scanner 看什么 | [docs/zh-CN/stacks.md](docs/zh-CN/stacks.md) |
431
491
  | Memory layer — decision log 和 failure pattern | [docs/zh-CN/memory-layer.md](docs/zh-CN/memory-layer.md) |
432
492
  | 5 个 validator 详解 | [docs/zh-CN/verification.md](docs/zh-CN/verification.md) |
433
493
  | 所有 CLI 命令和选项 | [docs/zh-CN/commands.md](docs/zh-CN/commands.md) |
434
- | 手动安装(不用 `npx`) | [docs/zh-CN/manual-installation.md](docs/zh-CN/manual-installation.md) |
494
+ | 手动安装 (不用 `npx`) | [docs/zh-CN/manual-installation.md](docs/zh-CN/manual-installation.md) |
435
495
  | Scanner 覆盖 — `.claudeos-scan.json` | [docs/zh-CN/advanced-config.md](docs/zh-CN/advanced-config.md) |
436
496
  | 安全性:re-init 时保留什么 | [docs/zh-CN/safety.md](docs/zh-CN/safety.md) |
437
- | 与同类工具的对比(scope,而非质量) | [docs/zh-CN/comparison.md](docs/zh-CN/comparison.md) |
497
+ | 与同类工具的对比 (scope,而非质量) | [docs/zh-CN/comparison.md](docs/zh-CN/comparison.md) |
438
498
  | 错误与恢复 | [docs/zh-CN/troubleshooting.md](docs/zh-CN/troubleshooting.md) |
439
499
 
440
500
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudeos-core",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "description": "Auto-generate Claude Code documentation from your actual source code — Standards, Rules, Skills, and Guides tailored to your project",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {