@mycodemap/mycodemap 1.9.0 → 2.0.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.
- package/CHANGELOG.md +18 -0
- package/README.md +138 -928
- package/README.zh-CN.md +1096 -0
- package/dist/cli/commands/analyze-options.d.ts.map +1 -1
- package/dist/cli/commands/analyze-options.js +8 -0
- package/dist/cli/commands/analyze-options.js.map +1 -1
- package/dist/cli/commands/analyze.d.ts.map +1 -1
- package/dist/cli/commands/analyze.js +60 -41
- package/dist/cli/commands/analyze.js.map +1 -1
- package/dist/cli/commands/benchmark.d.ts +8 -0
- package/dist/cli/commands/benchmark.d.ts.map +1 -0
- package/dist/cli/commands/benchmark.js +150 -0
- package/dist/cli/commands/benchmark.js.map +1 -0
- package/dist/cli/commands/deps.d.ts +2 -1
- package/dist/cli/commands/deps.d.ts.map +1 -1
- package/dist/cli/commands/deps.js +107 -78
- package/dist/cli/commands/deps.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +3 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +34 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/query.d.ts +1 -0
- package/dist/cli/commands/query.d.ts.map +1 -1
- package/dist/cli/commands/query.js +123 -140
- package/dist/cli/commands/query.js.map +1 -1
- package/dist/cli/doctor/check-agent.d.ts +3 -0
- package/dist/cli/doctor/check-agent.d.ts.map +1 -0
- package/dist/cli/doctor/check-agent.js +60 -0
- package/dist/cli/doctor/check-agent.js.map +1 -0
- package/dist/cli/doctor/check-ghost-commands.d.ts +3 -0
- package/dist/cli/doctor/check-ghost-commands.d.ts.map +1 -0
- package/dist/cli/doctor/check-ghost-commands.js +86 -0
- package/dist/cli/doctor/check-ghost-commands.js.map +1 -0
- package/dist/cli/doctor/check-native-deps.d.ts +3 -0
- package/dist/cli/doctor/check-native-deps.d.ts.map +1 -0
- package/dist/cli/doctor/check-native-deps.js +54 -0
- package/dist/cli/doctor/check-native-deps.js.map +1 -0
- package/dist/cli/doctor/check-workspace-drift.d.ts +3 -0
- package/dist/cli/doctor/check-workspace-drift.d.ts.map +1 -0
- package/dist/cli/doctor/check-workspace-drift.js +83 -0
- package/dist/cli/doctor/check-workspace-drift.js.map +1 -0
- package/dist/cli/doctor/formatter.d.ts +20 -0
- package/dist/cli/doctor/formatter.d.ts.map +1 -0
- package/dist/cli/doctor/formatter.js +91 -0
- package/dist/cli/doctor/formatter.js.map +1 -0
- package/dist/cli/doctor/index.d.ts +8 -0
- package/dist/cli/doctor/index.d.ts.map +1 -0
- package/dist/cli/doctor/index.js +9 -0
- package/dist/cli/doctor/index.js.map +1 -0
- package/dist/cli/doctor/orchestrator.d.ts +3 -0
- package/dist/cli/doctor/orchestrator.d.ts.map +1 -0
- package/dist/cli/doctor/orchestrator.js +37 -0
- package/dist/cli/doctor/orchestrator.js.map +1 -0
- package/dist/cli/doctor/types.d.ts +19 -0
- package/dist/cli/doctor/types.d.ts.map +1 -0
- package/dist/cli/doctor/types.js +4 -0
- package/dist/cli/doctor/types.js.map +1 -0
- package/dist/cli/index.js +72 -20
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/interface-contract/commands/analyze.d.ts +3 -0
- package/dist/cli/interface-contract/commands/analyze.d.ts.map +1 -0
- package/dist/cli/interface-contract/commands/analyze.js +138 -0
- package/dist/cli/interface-contract/commands/analyze.js.map +1 -0
- package/dist/cli/interface-contract/commands/benchmark.d.ts +3 -0
- package/dist/cli/interface-contract/commands/benchmark.d.ts.map +1 -0
- package/dist/cli/interface-contract/commands/benchmark.js +107 -0
- package/dist/cli/interface-contract/commands/benchmark.js.map +1 -0
- package/dist/cli/interface-contract/commands/deps.d.ts +3 -0
- package/dist/cli/interface-contract/commands/deps.d.ts.map +1 -0
- package/dist/cli/interface-contract/commands/deps.js +129 -0
- package/dist/cli/interface-contract/commands/deps.js.map +1 -0
- package/dist/cli/interface-contract/commands/doctor.d.ts +3 -0
- package/dist/cli/interface-contract/commands/doctor.d.ts.map +1 -0
- package/dist/cli/interface-contract/commands/doctor.js +59 -0
- package/dist/cli/interface-contract/commands/doctor.js.map +1 -0
- package/dist/cli/interface-contract/commands/index.d.ts +9 -0
- package/dist/cli/interface-contract/commands/index.d.ts.map +1 -0
- package/dist/cli/interface-contract/commands/index.js +18 -0
- package/dist/cli/interface-contract/commands/index.js.map +1 -0
- package/dist/cli/interface-contract/commands/init.d.ts +3 -0
- package/dist/cli/interface-contract/commands/init.d.ts.map +1 -0
- package/dist/cli/interface-contract/commands/init.js +87 -0
- package/dist/cli/interface-contract/commands/init.js.map +1 -0
- package/dist/cli/interface-contract/commands/query.d.ts +3 -0
- package/dist/cli/interface-contract/commands/query.d.ts.map +1 -0
- package/dist/cli/interface-contract/commands/query.js +185 -0
- package/dist/cli/interface-contract/commands/query.js.map +1 -0
- package/dist/cli/interface-contract/index.d.ts +22 -0
- package/dist/cli/interface-contract/index.d.ts.map +1 -0
- package/dist/cli/interface-contract/index.js +41 -0
- package/dist/cli/interface-contract/index.js.map +1 -0
- package/dist/cli/interface-contract/schema.d.ts +30 -0
- package/dist/cli/interface-contract/schema.d.ts.map +1 -0
- package/dist/cli/interface-contract/schema.js +72 -0
- package/dist/cli/interface-contract/schema.js.map +1 -0
- package/dist/cli/interface-contract/types.d.ts +76 -0
- package/dist/cli/interface-contract/types.d.ts.map +1 -0
- package/dist/cli/interface-contract/types.js +4 -0
- package/dist/cli/interface-contract/types.js.map +1 -0
- package/dist/cli/output/apply-suggestion.d.ts +12 -0
- package/dist/cli/output/apply-suggestion.d.ts.map +1 -0
- package/dist/cli/output/apply-suggestion.js +29 -0
- package/dist/cli/output/apply-suggestion.js.map +1 -0
- package/dist/cli/output/error-codes.d.ts +22 -0
- package/dist/cli/output/error-codes.d.ts.map +1 -0
- package/dist/cli/output/error-codes.js +82 -0
- package/dist/cli/output/error-codes.js.map +1 -0
- package/dist/cli/output/errors.d.ts +14 -0
- package/dist/cli/output/errors.d.ts.map +1 -0
- package/dist/cli/output/errors.js +170 -0
- package/dist/cli/output/errors.js.map +1 -0
- package/dist/cli/output/index.d.ts +13 -0
- package/dist/cli/output/index.d.ts.map +1 -0
- package/dist/cli/output/index.js +11 -0
- package/dist/cli/output/index.js.map +1 -0
- package/dist/cli/output/mode.d.ts +12 -0
- package/dist/cli/output/mode.d.ts.map +1 -0
- package/dist/cli/output/mode.js +23 -0
- package/dist/cli/output/mode.js.map +1 -0
- package/dist/cli/output/progress.d.ts +9 -0
- package/dist/cli/output/progress.d.ts.map +1 -0
- package/dist/cli/output/progress.js +65 -0
- package/dist/cli/output/progress.js.map +1 -0
- package/dist/cli/output/render.d.ts +11 -0
- package/dist/cli/output/render.d.ts.map +1 -0
- package/dist/cli/output/render.js +18 -0
- package/dist/cli/output/render.js.map +1 -0
- package/dist/cli/output/types.d.ts +53 -0
- package/dist/cli/output/types.d.ts.map +1 -0
- package/dist/cli/output/types.js +14 -0
- package/dist/cli/output/types.js.map +1 -0
- package/dist/cli/output/wasm-fallback.d.ts +13 -0
- package/dist/cli/output/wasm-fallback.d.ts.map +1 -0
- package/dist/cli/output/wasm-fallback.js +92 -0
- package/dist/cli/output/wasm-fallback.js.map +1 -0
- package/dist/cli/tree-sitter-check.d.ts +6 -1
- package/dist/cli/tree-sitter-check.d.ts.map +1 -1
- package/dist/cli/tree-sitter-check.js +23 -1
- package/dist/cli/tree-sitter-check.js.map +1 -1
- package/dist/infrastructure/storage/adapters/SQLiteStorage.d.ts.map +1 -1
- package/dist/infrastructure/storage/adapters/SQLiteStorage.js +2 -2
- package/dist/infrastructure/storage/adapters/SQLiteStorage.js.map +1 -1
- package/dist/infrastructure/storage/adapters/sqlite-loader.d.ts +23 -0
- package/dist/infrastructure/storage/adapters/sqlite-loader.d.ts.map +1 -0
- package/dist/infrastructure/storage/adapters/sqlite-loader.js +210 -0
- package/dist/infrastructure/storage/adapters/sqlite-loader.js.map +1 -0
- package/dist/orchestrator/types.d.ts +2 -0
- package/dist/orchestrator/types.d.ts.map +1 -1
- package/dist/orchestrator/types.js.map +1 -1
- package/dist/parser/implementations/tree-sitter-loader.d.ts +16 -0
- package/dist/parser/implementations/tree-sitter-loader.d.ts.map +1 -0
- package/dist/parser/implementations/tree-sitter-loader.js +105 -0
- package/dist/parser/implementations/tree-sitter-loader.js.map +1 -0
- package/dist/parser/implementations/tree-sitter-parser.d.ts +3 -0
- package/dist/parser/implementations/tree-sitter-parser.d.ts.map +1 -1
- package/dist/parser/implementations/tree-sitter-parser.js +8 -3
- package/dist/parser/implementations/tree-sitter-parser.js.map +1 -1
- package/dist/server/mcp/schema-adapter.d.ts +45 -0
- package/dist/server/mcp/schema-adapter.d.ts.map +1 -0
- package/dist/server/mcp/schema-adapter.js +290 -0
- package/dist/server/mcp/schema-adapter.js.map +1 -0
- package/dist/server/mcp/server.d.ts.map +1 -1
- package/dist/server/mcp/server.js +32 -2
- package/dist/server/mcp/server.js.map +1 -1
- package/docs/AI_ASSISTANT_SETUP.md +169 -12
- package/docs/README.md +40 -1
- package/docs/SETUP_GUIDE.md +11 -14
- package/docs/ai-guide/COMMANDS.md +68 -10
- package/docs/ai-guide/INTEGRATION.md +77 -10
- package/docs/ai-guide/OUTPUT.md +295 -2
- package/docs/ai-guide/PROMPTS.md +2 -2
- package/docs/ai-guide/QUICKSTART.md +28 -1
- package/docs/ai-guide/README.md +2 -2
- package/docs/archive/ideation/2026-04-15-executable-architecture-constitution-ideation-archive.md +70 -0
- package/docs/archive/ideation/2026-04-20-mycodemap-init-enhancements-ideation-archive.md +109 -0
- package/docs/archive/ideation/2026-04-22-rules-entry-docs-optimization-consolidated-ideation-archive.md +54 -0
- package/docs/ideation/2026-04-15-executable-architecture-constitution-ideation.md +10 -22
- package/docs/ideation/2026-04-20-mycodemap-init-enhancements-ideation.md +15 -60
- package/docs/ideation/2026-04-22-rules-entry-docs-optimization-consolidated-ideation.md +47 -52
- package/docs/ideation/2026-04-29-ux-install-agent-experience-ideation.md +256 -0
- package/docs/plans/2026-04-30-install-guide-and-repo-analyzer-design.md +394 -0
- package/docs/rules/README.md +1 -0
- package/docs/rules/architecture-guardrails.md +2 -1
- package/docs/rules/engineering-with-codex-openai.md +1 -1
- package/docs/rules/harness.md +106 -0
- package/docs/rules/pre-release-checklist.md +28 -0
- package/docs/rules/testing.md +51 -0
- package/examples/claude/skills/mycodemap-repo-analyzer/SKILL.md +294 -0
- package/examples/claude/skills/mycodemap-repo-analyzer/references/analysis-guide.md +166 -0
- package/examples/claude/skills/mycodemap-repo-analyzer/references/module-analysis-guide.md +150 -0
- package/package.json +7 -4
- package/scripts/sync-analyze-docs.js +2 -2
- package/scripts/validate-docs.js +113 -16
- package/docs/references/tmp.md +0 -527
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# 分析哲学与思维框架
|
|
2
|
+
|
|
3
|
+
## 核心立场
|
|
4
|
+
|
|
5
|
+
分析的目标是让读者**学到东西、产生思考**,而不是获得一份代码说明书。好的分析像一位资深工程师在白板前讲解——有观点、有推理、有对比,读完后读者能参与架构讨论。
|
|
6
|
+
|
|
7
|
+
每个评价都需要:代码依据、对比基准、推理过程。"代码质量不错"不是评价,"项目在错误处理上采用了统一的 Result 类型而非异常,这让错误路径在类型层面可见,代价是增加了调用方的样板代码——对于这个强调可靠性的基础设施项目来说,这个权衡是合理的"才是评价。
|
|
8
|
+
|
|
9
|
+
## 从项目特征中发现值得深挖的点
|
|
10
|
+
|
|
11
|
+
不要套用模板。每个项目都有自己的"有趣之处",发现它们的方法:
|
|
12
|
+
|
|
13
|
+
**追问设计动机**:看到一个设计选择时,问"为什么不用更常见的方案?"如果答案是"没有特别原因",这可能是一个改进点;如果答案揭示了深层约束,这就是值得展开的洞察。
|
|
14
|
+
|
|
15
|
+
**寻找张力点**:好的架构是在矛盾需求之间找平衡。寻找项目中的张力——性能 vs 可读性、灵活性 vs 简单性、一致性 vs 自治性。这些张力点往往是最有分析价值的地方。
|
|
16
|
+
|
|
17
|
+
**识别设计哲学**:大多数成熟项目有贯穿始终的设计风格("约定优于配置"、"零成本抽象"、"显式优于隐式")。识别这个哲学,然后检验它是否被一致地贯彻——不一致的地方往往有故事。
|
|
18
|
+
|
|
19
|
+
**关注边界**:模块边界、抽象层边界、系统边界——边界的设计往往比内部实现更能体现架构思考。一个模块内部可以随时重写,但边界一旦确定就很难改。
|
|
20
|
+
|
|
21
|
+
## 如何发现真正的设计亮点
|
|
22
|
+
|
|
23
|
+
亮点是**在特定约束下做出的聪明权衡**,不是"代码整洁"或"注释完善"这种泛泛之谈。
|
|
24
|
+
|
|
25
|
+
### 发现方法
|
|
26
|
+
|
|
27
|
+
**对比法**:"如果是我来设计,我会怎么做?"——如果你的第一反应方案和项目的方案不同,深入比较两者的权衡,往往能发现项目方案的精妙之处。
|
|
28
|
+
|
|
29
|
+
**追问法**:"这个设计解决了什么不明显的问题?"——表面上看起来过度设计的地方,可能是在防御一个你还没注意到的边界情况。
|
|
30
|
+
|
|
31
|
+
**场景法**:"在极端场景下会怎样?"——高并发、网络分区、数据量暴增、下游服务挂掉——好的设计在极端场景下优雅降级,差的设计在极端场景下崩溃。
|
|
32
|
+
|
|
33
|
+
**演进法**:"这个设计是如何演变到现在的?"——git 历史和代码中的注释有时能揭示设计演进的故事,当前的"复杂"设计可能是多次踩坑后的智慧结晶。
|
|
34
|
+
|
|
35
|
+
### 亮点的层次
|
|
36
|
+
|
|
37
|
+
| 层次 | 示例 | 分析价值 |
|
|
38
|
+
|------|------|----------|
|
|
39
|
+
| 架构级 | 独特的模块化策略、创新的扩展机制 | 高——值得深入展开 |
|
|
40
|
+
| 设计模式级 | 巧妙的状态管理、优雅的错误传播 | 中——值得一段解释 |
|
|
41
|
+
| 实现级 | 精巧的算法选择、高效的数据结构 | 视情况——只有当它体现设计思想时才值得展开 |
|
|
42
|
+
|
|
43
|
+
## 如何写出有启发性的分析
|
|
44
|
+
|
|
45
|
+
### 对比式思考
|
|
46
|
+
|
|
47
|
+
每个设计决策都存在于一个选择空间中。好的分析不只描述"选了什么",还要说明"没选什么以及为什么"。
|
|
48
|
+
|
|
49
|
+
> ❌ 该项目使用事件驱动架构进行模块间通信。
|
|
50
|
+
>
|
|
51
|
+
> ✅ 模块间通信选择了事件总线而非直接调用。直接调用更简单、调试更容易,但会让模块间产生编译期依赖——任何模块的接口变更都会波及调用方。事件总线的代价是运行时才能发现通信错误,但换来了模块可以独立开发和部署。对于这个插件化架构来说,这个权衡是合理的。
|
|
52
|
+
|
|
53
|
+
### 反事实推理
|
|
54
|
+
|
|
55
|
+
"如果不这样做会怎样"是检验设计必要性的利器。如果去掉一个设计元素后系统仍然正常工作,那它可能是过度设计;如果会导致严重问题,那就值得深入解释。
|
|
56
|
+
|
|
57
|
+
### 设计权衡三角
|
|
58
|
+
|
|
59
|
+
大多数架构决策涉及三个维度的权衡。找到这三个维度并说明项目在哪个方向上做了倾斜,比简单说"好"或"不好"有价值得多。
|
|
60
|
+
|
|
61
|
+
常见的权衡三角:
|
|
62
|
+
- 简单性 / 灵活性 / 性能
|
|
63
|
+
- 一致性 / 可用性 / 分区容忍
|
|
64
|
+
- 开发速度 / 运行时安全 / 学习曲线
|
|
65
|
+
|
|
66
|
+
## 全局关联
|
|
67
|
+
|
|
68
|
+
**每个局部分析都必须连接到项目整体设计哲学。** 这是区分"代码说明书"和"架构分析"的关键。
|
|
69
|
+
|
|
70
|
+
做法:
|
|
71
|
+
- 分析一个模块时,先说明它在整个系统中扮演什么角色
|
|
72
|
+
- 解释一个设计决策时,说明它如何服务于项目的整体设计哲学
|
|
73
|
+
- 发现一个问题时,评估它对整个系统的影响范围
|
|
74
|
+
- 描述模块间协作时,解释这种协作模式是否与项目其他部分一致
|
|
75
|
+
|
|
76
|
+
反面教材:孤立地分析每个模块,最后拼在一起——这样的报告读起来像一堆独立的代码审查,缺乏整体叙事。
|
|
77
|
+
|
|
78
|
+
## 叙事连贯
|
|
79
|
+
|
|
80
|
+
**模块分析不是独立章节的拼接,而是一条有逻辑的叙事线。**
|
|
81
|
+
|
|
82
|
+
好的模块叙事像一本书的章节——每章结尾自然引出下一章的主题。读者不需要目录就能理解为什么先讲 A 再讲 B。
|
|
83
|
+
|
|
84
|
+
常见的叙事主线:
|
|
85
|
+
- **数据流驱动**:跟随一个请求从进入系统到返回响应的完整路径,沿途讲解每个模块的职责。适合 Web 框架、API 网关等请求驱动的系统
|
|
86
|
+
- **分层驱动**:从最底层的基础设施讲到最上层的用户接口,每层依赖下层的能力。适合操作系统、编译器等分层架构
|
|
87
|
+
- **问题驱动**:从核心业务问题出发,逐步引入解决每个子问题的模块。适合领域复杂的业务系统
|
|
88
|
+
|
|
89
|
+
反面教材:按目录结构或字母顺序排列模块——这样的报告读起来像一本字典,不像一篇分析。
|
|
90
|
+
|
|
91
|
+
过渡句示例:
|
|
92
|
+
> ✅ Gateway 完成了请求的认证和路由分发,但它只负责"谁可以进来",不负责"进来之后能做什么"。这个行为控制的职责,由沙箱运行时的策略引擎承担。
|
|
93
|
+
>
|
|
94
|
+
> ❌ 接下来我们分析策略引擎模块。
|
|
95
|
+
|
|
96
|
+
## 深度标准
|
|
97
|
+
|
|
98
|
+
### 有深度的分析长这样
|
|
99
|
+
|
|
100
|
+
> 路由系统选择了基数树(radix tree)而非哈希表。哈希表查找是 O(1),但不支持参数路由(`/users/:id`)和通配符——要支持这些就得退化为线性扫描。基数树在静态路由上接近 O(1),同时天然支持前缀匹配,让参数路由和通配符成为一等公民。代价是实现复杂度高、内存占用略大,但对于一个以路由性能为卖点的框架来说,这个投入是值得的。值得注意的是,Fastify 和 Hono 也做了同样的选择,这已经成为高性能路由的事实标准。
|
|
101
|
+
|
|
102
|
+
特征:有具体的技术推理、有量化的权衡、有业界对比、有"为什么适合这个项目"的判断。
|
|
103
|
+
|
|
104
|
+
### 没有深度的分析长这样
|
|
105
|
+
|
|
106
|
+
> 路由系统采用了高效的数据结构来存储和匹配路由,支持参数路由和通配符匹配,性能表现优秀。
|
|
107
|
+
|
|
108
|
+
特征:泛泛而谈、没有具体技术细节、没有推理过程、换一个项目也能用。
|
|
109
|
+
|
|
110
|
+
## 批判性思考指引
|
|
111
|
+
|
|
112
|
+
### 如何诚实评价
|
|
113
|
+
|
|
114
|
+
- **有代码依据**:每个评价都要指向具体的代码证据,不能凭印象
|
|
115
|
+
- **有对比基准**:说"好"或"不好"时,对比的是什么?业界最佳实践?同类项目?项目自身的设计目标?
|
|
116
|
+
- **区分"不同"和"不好"**:非主流的设计选择不等于错误,可能是在不同约束下的合理权衡
|
|
117
|
+
|
|
118
|
+
### 如何与业界对比
|
|
119
|
+
|
|
120
|
+
- 选择真正可比的项目(同领域、同规模、同目标用户)
|
|
121
|
+
- 对比设计选择而非实现质量——不同项目有不同的成熟度
|
|
122
|
+
- 承认各自的约束差异——一个 2 人项目和一个 200 人项目面对的问题不同
|
|
123
|
+
|
|
124
|
+
### 如何指出问题而不流于吹毛求疵
|
|
125
|
+
|
|
126
|
+
- 只指出架构级别的问题,不纠结命名风格或代码格式
|
|
127
|
+
- 解释问题的实际影响——"这会导致什么具体后果"
|
|
128
|
+
- 如果可能,提供改进方向(不需要完整方案)
|
|
129
|
+
- 承认项目的约束——有些"问题"在特定约束下是合理的妥协
|
|
130
|
+
|
|
131
|
+
### 如何识别真正的问题
|
|
132
|
+
|
|
133
|
+
问题是**对系统产生实际影响的架构缺陷**,不是命名风格或代码格式。
|
|
134
|
+
|
|
135
|
+
**影响面分析**:这个问题影响多少模块?影响的是核心路径还是边缘场景?影响面越大,问题越值得指出。
|
|
136
|
+
|
|
137
|
+
**演进风险**:这个问题现在可能不严重,但随着项目增长会恶化吗?"技术债务"的本质是利息——现在不还,将来要付更多。
|
|
138
|
+
|
|
139
|
+
**替代方案可行性**:指出问题时,心里要有一个可行的改进方向。如果你想不到更好的方案,那可能不是问题,而是在当前约束下的合理妥协。
|
|
140
|
+
|
|
141
|
+
### 问题的层次
|
|
142
|
+
|
|
143
|
+
| 层次 | 示例 | 如何表述 |
|
|
144
|
+
|------|------|----------|
|
|
145
|
+
| 架构级 | 循环依赖、职责混乱、单点瓶颈 | 详细分析影响 + 改进方向 |
|
|
146
|
+
| 设计级 | 抽象泄漏、过度设计、状态管理混乱 | 说明具体后果 + 对比更好的做法 |
|
|
147
|
+
| 工程级 | 测试策略缺失、可观测性不足 | 简要指出 + 建议 |
|
|
148
|
+
|
|
149
|
+
### 评价的诚实性
|
|
150
|
+
|
|
151
|
+
- 项目质量高就多写亮点,不需要凑问题
|
|
152
|
+
- 项目有明显缺陷就直说,不需要找补
|
|
153
|
+
- 承认不确定性——"从代码来看可能是 X,但也可能有我没看到的约束"
|
|
154
|
+
- 区分"设计选择"和"设计缺陷"——非主流不等于错误
|
|
155
|
+
|
|
156
|
+
### 综合评价维度
|
|
157
|
+
|
|
158
|
+
不使用固定评分表,但评价应覆盖以下维度(根据项目特征选择最相关的):
|
|
159
|
+
|
|
160
|
+
- **架构设计**:模块化程度、关注点分离、扩展性
|
|
161
|
+
- **设计哲学一致性**:项目是否贯彻了自己的设计理念
|
|
162
|
+
- **工程成熟度**:测试、文档、错误处理、可观测性
|
|
163
|
+
- **生态适应性**:在目标生态中的定位是否合理
|
|
164
|
+
- **演进健康度**:技术债务水平、架构是否支持未来演进
|
|
165
|
+
|
|
166
|
+
每个维度的评价都要有具体依据,不要给出没有论证的分数。
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# 模块分析指南
|
|
2
|
+
|
|
3
|
+
## 核心方法
|
|
4
|
+
|
|
5
|
+
按业务功能划分模块,不按文件或目录。一个逻辑模块可能跨越多个文件,一个文件也可能包含多个模块的部分实现。
|
|
6
|
+
|
|
7
|
+
分析深度标准:**交给另一个 AI 能仅凭报告复现系统的设计**。读者能理解模块的设计思路、职责边界、与其他模块的协作方式,并能参与架构讨论。
|
|
8
|
+
|
|
9
|
+
## 全局视角要求
|
|
10
|
+
|
|
11
|
+
**每个模块的分析都必须回答两个全局问题:**
|
|
12
|
+
|
|
13
|
+
1. **在整个项目中的角色**:这个模块为什么存在?去掉它系统会怎样?它服务于项目的哪个核心目标?
|
|
14
|
+
2. **与其他模块的设计协同**:它和其他模块之间的契约是什么?这种协作模式是否与项目整体的设计哲学一致?
|
|
15
|
+
|
|
16
|
+
孤立地分析模块是最常见的错误。一个模块的设计选择往往是被其他模块的约束所驱动的——不理解这些约束,就无法理解设计动机。
|
|
17
|
+
|
|
18
|
+
## 模块分析完整性四要素
|
|
19
|
+
|
|
20
|
+
每个核心模块的分析必须覆盖以下四个要素,缺任何一项都不算完整:
|
|
21
|
+
|
|
22
|
+
1. **核心数据结构** — 贴关键接口/类型定义(不是全部,只贴理解设计必需的)
|
|
23
|
+
2. **执行流程** — 用文字或 Mermaid 时序图描述调用链,标注源文件路径和行号
|
|
24
|
+
3. **设计决策** — 为什么选这个方案,不选另一个,权衡了什么
|
|
25
|
+
4. **模块间依赖** — 谁调用谁,数据怎么流转,共享了什么状态
|
|
26
|
+
|
|
27
|
+
检验标准:如果另一个 AI 只读你的分析(不看源码),能否画出这个模块的架构图并解释它的工作原理?如果不能,说明缺了某个要素。
|
|
28
|
+
|
|
29
|
+
必须包含:业务问题、设计思路和架构模式、核心流程(Mermaid 图)、协作关系、设计权衡。
|
|
30
|
+
不需要包含:完整类型定义、所有函数签名、所有参数列表、错误枚举逐项说明。
|
|
31
|
+
|
|
32
|
+
## 模块识别方法
|
|
33
|
+
|
|
34
|
+
1. **业务功能角度** — 项目提供哪些核心业务能力?
|
|
35
|
+
2. **数据流角度** — 数据从输入到输出经过哪些转换阶段?
|
|
36
|
+
3. **职责角度** — 业务需求变化时,哪些代码需要一起改?
|
|
37
|
+
|
|
38
|
+
## 分析深度
|
|
39
|
+
|
|
40
|
+
- **核心模块**(创新点、架构关键组件):设计思路讲透、核心流程有图有解读、设计决策解释权衡、协作关系画清楚
|
|
41
|
+
- **次要模块**(工具函数、标准封装):一句话职责 + 文件路径 + 特别之处
|
|
42
|
+
|
|
43
|
+
## Subagent 并行分析
|
|
44
|
+
|
|
45
|
+
阶段 6 必须使用 Agent 工具为每个核心模块启动独立 subagent 并行分析。
|
|
46
|
+
|
|
47
|
+
调度策略:
|
|
48
|
+
- 每个核心模块 → 一个独立 Agent subagent(`subagent_type: "general-purpose"`)
|
|
49
|
+
- 所有次要模块 → 合并到一个 Agent subagent 批量处理
|
|
50
|
+
- 所有 subagent 在同一消息中并行启动
|
|
51
|
+
|
|
52
|
+
### 核心模块 Subagent Prompt 模板
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
你是一位资深架构师,正在对 {项目名} 的「{模块名}」模块进行深度分析。
|
|
56
|
+
|
|
57
|
+
## 背景信息
|
|
58
|
+
- 项目定位: {一句话描述}
|
|
59
|
+
- 整体架构: {简述架构风格和核心设计}
|
|
60
|
+
- 项目设计哲学: {贯穿项目的核心设计理念}
|
|
61
|
+
- 该模块在系统中的位置: {与其他模块的关系}
|
|
62
|
+
- 叙事上下文: {该模块在报告叙事线中的位置——前一个模块讲了什么、读者带着什么问题进入本模块、本模块需要为下一个模块铺垫什么}
|
|
63
|
+
|
|
64
|
+
## 需要分析的文件
|
|
65
|
+
{文件路径列表}
|
|
66
|
+
|
|
67
|
+
## 分析结构
|
|
68
|
+
用自然语言描述设计意图,默认不暴露函数名/参数名/类型定义,只有设计特别精妙时才附代码片段。
|
|
69
|
+
|
|
70
|
+
1. 在项目中的角色 — 这个模块为什么存在?去掉它系统会怎样?
|
|
71
|
+
2. 解决什么问题 — 业务背景,没有它系统会怎样
|
|
72
|
+
3. 设计思路 — 方案及理由、放弃的替代方案、核心设计模式
|
|
73
|
+
4. 核心数据结构 — 贴理解设计必需的关键接口/类型定义(不是全部)
|
|
74
|
+
5. 核心业务流程 — Mermaid 流程图 + 自然语言解读,标注源文件路径和行号
|
|
75
|
+
6. 与其他模块的设计协同 — 依赖谁、谁依赖它、协作方式、共享状态、这种协作模式是否与项目整体设计哲学一致。跨模块结论用【待主 agent 验证】标注
|
|
76
|
+
7. 关键设计决策 — 1-3 个最重要的决策及权衡(为什么选这个方案,替代方案的代价)
|
|
77
|
+
8. Deep Research 洞察 — 替代方案代价、业界对比、如果重新设计
|
|
78
|
+
9. 扩展点(如适用)
|
|
79
|
+
10. 亮点与问题 — 涉及文件列表
|
|
80
|
+
|
|
81
|
+
## 全局视角要求
|
|
82
|
+
你的分析必须将模块放在项目整体语境中——设计选择如何服务整体哲学、边界为何这样划、变化会如何影响其他模块。(详见文件头部"全局视角要求")
|
|
83
|
+
|
|
84
|
+
## 相关探索问题
|
|
85
|
+
{问题列表}
|
|
86
|
+
将答案融入各节中。
|
|
87
|
+
|
|
88
|
+
## 写入策略
|
|
89
|
+
对于大模块(文件总行数 > 5000 行),必须增量写入草稿:
|
|
90
|
+
- 每完成一个子系统/子模块的分析后,立即将该部分写入草稿文件
|
|
91
|
+
- 第一个子系统用 Write 创建文件,后续子系统用 Edit 追加
|
|
92
|
+
- 不要等全部文件读完再一次性写入
|
|
93
|
+
- 覆盖率明细表在最后追加
|
|
94
|
+
|
|
95
|
+
## 输出
|
|
96
|
+
写入 {work_dir}/drafts/06-module-{模块名}.md,单次写入不超过 300 行。
|
|
97
|
+
|
|
98
|
+
## 覆盖率要求
|
|
99
|
+
当前分析模式: {分析模式},核心模块最低覆盖率: {最低覆盖率}%。
|
|
100
|
+
草稿末尾必须附覆盖率明细表(格式:文件名 | 总行数 | 已读行数 | 覆盖率% | 未读原因),最后一行为合计行并标注达标✅/未达标❌。
|
|
101
|
+
「已读」指通过 Read 工具实际读取过的行。覆盖率未达标时必须继续阅读直到达标。
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 次要模块批量 Prompt 模板
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
你是一位资深架构师,正在对 {项目名} 的次要模块进行批量分析。
|
|
108
|
+
|
|
109
|
+
## 背景信息
|
|
110
|
+
- 项目定位: {一句话描述}
|
|
111
|
+
- 整体架构: {简述}
|
|
112
|
+
- 项目设计哲学: {贯穿项目的核心设计理念}
|
|
113
|
+
|
|
114
|
+
## 需要分析的次要模块
|
|
115
|
+
{模块列表:名称、职责假设、文件范围}
|
|
116
|
+
|
|
117
|
+
## 每个模块输出
|
|
118
|
+
1. 职责(一句话)
|
|
119
|
+
2. 在项目整体中的角色(一句话)
|
|
120
|
+
3. 实现方式(一句话)
|
|
121
|
+
4. 如有特别之处,展开说明
|
|
122
|
+
5. 涉及文件列表
|
|
123
|
+
|
|
124
|
+
写入 {work_dir}/drafts/06-module-secondary.md
|
|
125
|
+
|
|
126
|
+
## 覆盖率要求
|
|
127
|
+
当前分析模式: {分析模式},次要模块最低覆盖率: {最低覆盖率}%。
|
|
128
|
+
草稿末尾必须附覆盖率明细表(格式:文件名 | 总行数 | 已读行数 | 覆盖率% | 未读原因),最后一行为合计行并标注达标✅/未达标❌。
|
|
129
|
+
「已读」指通过 Read 工具实际读取过的行。覆盖率未达标时必须继续阅读直到达标。
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Subagent 协作规范
|
|
133
|
+
|
|
134
|
+
- **只分析分配的文件**,不越界
|
|
135
|
+
- **跨模块推断用【待主 agent 验证】标注**,主 agent 在阶段 7 交叉验证
|
|
136
|
+
- **深度优先于广度**,宁可把一个核心流程讲透
|
|
137
|
+
- **全局视角**,将模块放在项目整体语境中分析,解释设计选择如何服务于项目整体
|
|
138
|
+
- **叙事衔接**,草稿开头用 1-2 句说明本模块与前一个模块的关系,草稿结尾用 1 句铺垫下一个模块
|
|
139
|
+
|
|
140
|
+
## 质量检查
|
|
141
|
+
|
|
142
|
+
- [ ] 模块按业务功能划分,不是按文件/目录
|
|
143
|
+
- [ ] 每个模块解释了"在项目中的角色"和"为什么这样设计"
|
|
144
|
+
- [ ] 四要素完整:核心数据结构、执行流程(含文件路径行号)、设计决策、模块间依赖
|
|
145
|
+
- [ ] 核心流程用 Mermaid 图展示
|
|
146
|
+
- [ ] 关键接口/类型定义已贴出(只贴理解设计必需的)
|
|
147
|
+
- [ ] 没有暴露不必要的函数名、参数名、类型定义
|
|
148
|
+
- [ ] 协作关系清晰,共享状态已标注
|
|
149
|
+
- [ ] 每个模块的分析都连接到了项目整体设计哲学
|
|
150
|
+
- [ ] 检验:另一个 AI 只读分析(不看源码)能画出模块架构图
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mycodemap/mycodemap",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "TypeScript 代码地图工具 - 为 AI 辅助开发提供结构化上下文",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"examples/",
|
|
23
23
|
"scripts/",
|
|
24
24
|
"README.md",
|
|
25
|
+
"README.zh-CN.md",
|
|
25
26
|
"LICENSE",
|
|
26
27
|
"CHANGELOG.md",
|
|
27
28
|
"mycodemap.config.schema.json"
|
|
@@ -43,9 +44,7 @@
|
|
|
43
44
|
"validate-pack": "node scripts/validate-pack.js",
|
|
44
45
|
"release": "./scripts/release.sh",
|
|
45
46
|
"check:all": "npm run typecheck && npm run lint && npm test && npm run docs:check",
|
|
46
|
-
"check:architecture": "echo 'dependency-cruiser not installed, run: npm i -D dependency-cruiser'",
|
|
47
47
|
"check:security": "npm audit",
|
|
48
|
-
"check:unused": "echo 'knip not installed, run: npm i -D knip'",
|
|
49
48
|
"fix:all": "npm run lint -- --fix",
|
|
50
49
|
"ai:pre-task": "npm run check:all",
|
|
51
50
|
"ai:post-task": "npm run fix:all && npm run check:all"
|
|
@@ -85,8 +84,12 @@
|
|
|
85
84
|
"eslint": "^8.57.1",
|
|
86
85
|
"vitest": "^1.1.0"
|
|
87
86
|
},
|
|
87
|
+
"optionalDependencies": {
|
|
88
|
+
"web-tree-sitter": "^0.24.0",
|
|
89
|
+
"sql.js": "^1.12.0"
|
|
90
|
+
},
|
|
88
91
|
"engines": {
|
|
89
|
-
"node": ">=
|
|
92
|
+
"node": ">=20.0.0"
|
|
90
93
|
},
|
|
91
94
|
"publishConfig": {
|
|
92
95
|
"access": "public",
|
|
@@ -299,12 +299,12 @@ function renderAnalyzeOptionsTable(rootDir) {
|
|
|
299
299
|
|
|
300
300
|
const ANALYZE_DOC_BLOCKS = [
|
|
301
301
|
{
|
|
302
|
-
relativePath: 'README.md',
|
|
302
|
+
relativePath: 'README.zh-CN.md',
|
|
303
303
|
marker: 'analyze-readme-examples',
|
|
304
304
|
render: () => renderReadmeAnalyzeExamples(),
|
|
305
305
|
},
|
|
306
306
|
{
|
|
307
|
-
relativePath: 'README.md',
|
|
307
|
+
relativePath: 'README.zh-CN.md',
|
|
308
308
|
marker: 'analyze-readme-options',
|
|
309
309
|
render: rootDir => renderAnalyzeOptionsTable(rootDir),
|
|
310
310
|
},
|
package/scripts/validate-docs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// [META] since:2026-03 | owner:docs-team | stable:true
|
|
2
2
|
// [WHY] Validate high-signal documentation facts against the current repository guardrails
|
|
3
3
|
|
|
4
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { collectAnalyzeDocSyncFailures } from './sync-analyze-docs.js';
|
|
@@ -273,7 +273,7 @@ function validatePackageScripts(rootDir, failures) {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
function validateAnalyzeDocs(rootDir, failures) {
|
|
276
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
276
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
277
277
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
278
278
|
const claudeGuide = readText(rootDir, 'CLAUDE.md', failures);
|
|
279
279
|
const commandsGuide = readText(rootDir, 'docs/ai-guide/COMMANDS.md', failures);
|
|
@@ -410,7 +410,7 @@ function validateAnalyzeDocs(rootDir, failures) {
|
|
|
410
410
|
}
|
|
411
411
|
|
|
412
412
|
function validateHistoryRiskDocs(rootDir, failures) {
|
|
413
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
413
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
414
414
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
415
415
|
const claudeGuide = readText(rootDir, 'CLAUDE.md', failures);
|
|
416
416
|
const commandsGuide = readText(rootDir, 'docs/ai-guide/COMMANDS.md', failures);
|
|
@@ -513,7 +513,7 @@ function validateHistoryRiskDocs(rootDir, failures) {
|
|
|
513
513
|
}
|
|
514
514
|
|
|
515
515
|
function validateDesignContractDocs(rootDir, failures) {
|
|
516
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
516
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
517
517
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
518
518
|
const claudeGuide = readText(rootDir, 'CLAUDE.md', failures);
|
|
519
519
|
const commandsGuide = readText(rootDir, 'docs/ai-guide/COMMANDS.md', failures);
|
|
@@ -835,8 +835,104 @@ function validateDesignContractDocs(rootDir, failures) {
|
|
|
835
835
|
}
|
|
836
836
|
}
|
|
837
837
|
|
|
838
|
+
function validateNpmScriptsAreReal(rootDir, failures) {
|
|
839
|
+
const packageJsonText = readText(rootDir, 'package.json', failures);
|
|
840
|
+
if (!packageJsonText) {
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
let packageJson;
|
|
845
|
+
try {
|
|
846
|
+
packageJson = JSON.parse(packageJsonText);
|
|
847
|
+
} catch {
|
|
848
|
+
failures.push('package.json is not valid JSON — cannot validate npm scripts');
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
const scripts = packageJson.scripts;
|
|
853
|
+
if (!scripts || typeof scripts !== 'object') {
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/** Pattern matching echo stubs like: echo 'dependency-cruiser not installed, run: npm i -D dependency-cruiser' */
|
|
858
|
+
const ECHO_STUB_PATTERN = /^echo\s+['"].*not installed/i;
|
|
859
|
+
|
|
860
|
+
// Check all referenced npm scripts in docs are real (not echo stubs)
|
|
861
|
+
const docsDir = path.join(rootDir, 'docs');
|
|
862
|
+
const githubDir = path.join(rootDir, '.github');
|
|
863
|
+
const npmRunPattern = /npm\s+run\s+([a-zA-Z0-9:_-]+)/g;
|
|
864
|
+
|
|
865
|
+
function scanFileForNpmRun(filePath, label) {
|
|
866
|
+
if (!existsSync(filePath)) {
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
let content;
|
|
871
|
+
try {
|
|
872
|
+
content = readFileSync(filePath, 'utf8');
|
|
873
|
+
} catch {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
let match;
|
|
878
|
+
while ((match = npmRunPattern.exec(content)) !== null) {
|
|
879
|
+
const scriptName = match[1].replace(/[.,;:!?`'"()\[\]{}]+$/, '');
|
|
880
|
+
// Skip known npm lifecycle scripts that don't need to be in package.json
|
|
881
|
+
const npmLifecycleScripts = new Set([
|
|
882
|
+
'postinstall', 'preinstall', 'prepare', 'prepublish', 'prepublishOnly',
|
|
883
|
+
'prerestart', 'postrestart', 'prestart', 'poststart', 'prestop', 'poststop',
|
|
884
|
+
'pretest', 'posttest', 'preversion', 'postversion',
|
|
885
|
+
]);
|
|
886
|
+
if (npmLifecycleScripts.has(scriptName)) {
|
|
887
|
+
continue;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// Skip if not a defined script
|
|
891
|
+
if (!(scriptName in scripts)) {
|
|
892
|
+
failures.push(`[docs-script-ghost] ${label} references undefined npm script: "npm run ${scriptName}"`);
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
const scriptValue = scripts[scriptName];
|
|
897
|
+
if (typeof scriptValue === 'string' && ECHO_STUB_PATTERN.test(scriptValue)) {
|
|
898
|
+
failures.push(`[docs-script-stub] ${label} references npm script "${scriptName}" which is an echo stub, not a real command`);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
function scanDirectory(dirPath, labelPrefix) {
|
|
904
|
+
if (!existsSync(dirPath)) {
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
// Walk directory recursively
|
|
909
|
+
function walk(currentPath, relativePath) {
|
|
910
|
+
const items = readdirSync(currentPath, { withFileTypes: true });
|
|
911
|
+
for (const item of items) {
|
|
912
|
+
const itemPath = path.join(currentPath, item.name);
|
|
913
|
+
const itemRelPath = path.join(relativePath, item.name);
|
|
914
|
+
if (item.isDirectory()) {
|
|
915
|
+
// Skip historical artifact directories
|
|
916
|
+
if (item.name === 'exec-plans' || item.name === 'ideation' || item.name === 'references' || item.name === 'archive') {
|
|
917
|
+
continue;
|
|
918
|
+
}
|
|
919
|
+
walk(itemPath, itemRelPath);
|
|
920
|
+
} else if (item.isFile() && item.name.endsWith('.md')) {
|
|
921
|
+
scanFileForNpmRun(itemPath, `${labelPrefix}/${itemRelPath}`);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
walk(dirPath, '');
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
scanDirectory(docsDir, 'docs');
|
|
929
|
+
scanDirectory(githubDir, '.github');
|
|
930
|
+
// Note: docs/exec-plans/ and docs/ideation/ contain historical artifacts
|
|
931
|
+
// that reference scripts from their time period — skip them
|
|
932
|
+
}
|
|
933
|
+
|
|
838
934
|
function validatePositioningBaselineDocs(rootDir, failures) {
|
|
839
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
935
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
840
936
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
841
937
|
const aiGuideIndex = readText(rootDir, 'docs/ai-guide/README.md', failures);
|
|
842
938
|
const outputGuide = readText(rootDir, 'docs/ai-guide/OUTPUT.md', failures);
|
|
@@ -844,7 +940,7 @@ function validatePositioningBaselineDocs(rootDir, failures) {
|
|
|
844
940
|
|
|
845
941
|
if (readme) {
|
|
846
942
|
const requiredReadmeSnippets = [
|
|
847
|
-
'AI-
|
|
943
|
+
'AI-Native',
|
|
848
944
|
'AI/Agent 是主要消费者',
|
|
849
945
|
'`server`、`watch`、`report`、`logs` 已从 public CLI 移除,并在调用时给出迁移提示。'
|
|
850
946
|
];
|
|
@@ -863,8 +959,8 @@ function validatePositioningBaselineDocs(rootDir, failures) {
|
|
|
863
959
|
|
|
864
960
|
if (aiGuide) {
|
|
865
961
|
const requiredAiGuideSnippets = [
|
|
866
|
-
'CodeMap 是一个 AI-
|
|
867
|
-
'
|
|
962
|
+
'CodeMap 是一个 AI-Native 优先',
|
|
963
|
+
'JSON/NDJSON 默认输出',
|
|
868
964
|
'`Server Layer` 是内部架构层,不等于公共 `mycodemap server` 命令',
|
|
869
965
|
'后者已从 public CLI 移除'
|
|
870
966
|
];
|
|
@@ -876,7 +972,7 @@ function validatePositioningBaselineDocs(rootDir, failures) {
|
|
|
876
972
|
|
|
877
973
|
if (aiGuideIndex) {
|
|
878
974
|
const requiredIndexSnippets = [
|
|
879
|
-
'AI-
|
|
975
|
+
'AI-Native 优先、人类友好的代码架构治理基础设施',
|
|
880
976
|
'AI/Agent 是主要消费者',
|
|
881
977
|
'`server`、`watch`、`report`、`logs` 已从 public CLI 移除'
|
|
882
978
|
];
|
|
@@ -909,7 +1005,7 @@ function validatePositioningBaselineDocs(rootDir, failures) {
|
|
|
909
1005
|
}
|
|
910
1006
|
|
|
911
1007
|
function validateCliSurfaceDocs(rootDir, failures) {
|
|
912
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
1008
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
913
1009
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
914
1010
|
const aiGuideIndex = readText(rootDir, 'docs/ai-guide/README.md', failures);
|
|
915
1011
|
const commandsGuide = readText(rootDir, 'docs/ai-guide/COMMANDS.md', failures);
|
|
@@ -997,7 +1093,7 @@ function validateCliSurfaceDocs(rootDir, failures) {
|
|
|
997
1093
|
}
|
|
998
1094
|
|
|
999
1095
|
function validateConfigDocs(rootDir, failures) {
|
|
1000
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
1096
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
1001
1097
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
1002
1098
|
const setupGuide = readText(rootDir, 'docs/SETUP_GUIDE.md', failures);
|
|
1003
1099
|
const assistantGuide = readText(rootDir, 'docs/AI_ASSISTANT_SETUP.md', failures);
|
|
@@ -1109,7 +1205,7 @@ function validateConfigDocs(rootDir, failures) {
|
|
|
1109
1205
|
}
|
|
1110
1206
|
|
|
1111
1207
|
function validatePluginRuntimeDocs(rootDir, failures) {
|
|
1112
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
1208
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
1113
1209
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
1114
1210
|
const commandsGuide = readText(rootDir, 'docs/ai-guide/COMMANDS.md', failures);
|
|
1115
1211
|
const outputGuide = readText(rootDir, 'docs/ai-guide/OUTPUT.md', failures);
|
|
@@ -1184,7 +1280,7 @@ function validatePluginRuntimeDocs(rootDir, failures) {
|
|
|
1184
1280
|
}
|
|
1185
1281
|
|
|
1186
1282
|
function validateGraphStorageDocs(rootDir, failures) {
|
|
1187
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
1283
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
1188
1284
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
1189
1285
|
const claudeGuide = readText(rootDir, 'CLAUDE.md', failures);
|
|
1190
1286
|
const commandsGuide = readText(rootDir, 'docs/ai-guide/COMMANDS.md', failures);
|
|
@@ -1331,7 +1427,7 @@ function validateTestingDocs(rootDir, failures) {
|
|
|
1331
1427
|
}
|
|
1332
1428
|
|
|
1333
1429
|
function validateWorkflowAndDiscoveryDocs(rootDir, failures) {
|
|
1334
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
1430
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
1335
1431
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
1336
1432
|
const commandsGuide = readText(rootDir, 'docs/ai-guide/COMMANDS.md', failures);
|
|
1337
1433
|
const outputGuide = readText(rootDir, 'docs/ai-guide/OUTPUT.md', failures);
|
|
@@ -1531,7 +1627,7 @@ function validateProductSpecsDocs(rootDir, failures) {
|
|
|
1531
1627
|
}
|
|
1532
1628
|
|
|
1533
1629
|
function validateGuardrailDocs(rootDir, failures) {
|
|
1534
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
1630
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
1535
1631
|
const engineeringRule = readText(rootDir, 'docs/rules/engineering-with-codex-openai.md', failures);
|
|
1536
1632
|
const validationRule = readText(rootDir, 'docs/rules/validation.md', failures);
|
|
1537
1633
|
const ciWorkflow = readText(rootDir, '.github/workflows/ci-gateway.yml', failures);
|
|
@@ -1593,7 +1689,7 @@ function validateGuardrailDocs(rootDir, failures) {
|
|
|
1593
1689
|
}
|
|
1594
1690
|
|
|
1595
1691
|
function validateValidationTruthDocs(rootDir, failures) {
|
|
1596
|
-
const readme = readText(rootDir, 'README.md', failures);
|
|
1692
|
+
const readme = readText(rootDir, 'README.zh-CN.md', failures) || readText(rootDir, 'README.md', failures);
|
|
1597
1693
|
const aiGuide = readText(rootDir, 'AI_GUIDE.md', failures);
|
|
1598
1694
|
const validationRule = readText(rootDir, 'docs/rules/validation.md', failures);
|
|
1599
1695
|
const engineeringRule = readText(rootDir, 'docs/rules/engineering-with-codex-openai.md', failures);
|
|
@@ -1651,6 +1747,7 @@ function validateDocs(rootDir) {
|
|
|
1651
1747
|
const failures = [];
|
|
1652
1748
|
|
|
1653
1749
|
validatePackageScripts(rootDir, failures);
|
|
1750
|
+
validateNpmScriptsAreReal(rootDir, failures);
|
|
1654
1751
|
validatePositioningBaselineDocs(rootDir, failures);
|
|
1655
1752
|
validateCliSurfaceDocs(rootDir, failures);
|
|
1656
1753
|
validateConfigDocs(rootDir, failures);
|