project-librarian 0.2.0 → 0.2.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.ja.md +34 -46
- package/README.ko.md +35 -47
- package/README.md +38 -47
- package/README.zh.md +34 -46
- package/SKILL.md +27 -12
- package/dist/args.js +10 -1
- package/dist/code-index-file-policy.js +2 -0
- package/dist/hooks.js +65 -7
- package/dist/init-project-wiki.js +25 -1
- package/dist/install-skill.js +28 -9
- package/dist/migration.js +203 -4
- package/dist/modes.js +129 -100
- package/dist/templates.js +28 -7
- package/dist/wiki-files.js +9 -1
- package/package.json +9 -6
package/README.zh.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://nodejs.org/)
|
|
6
6
|
[](https://nodejs.org/api/sqlite.html)
|
|
7
7
|
|
|
8
|
-
面向 Codex 和
|
|
8
|
+
面向 Codex、Claude Code、Cursor 和 Gemini CLI 的简洁项目记忆与代码依据。
|
|
9
9
|
|
|
10
10
|
Project Librarian 会创建仓库本地规划 wiki、简洁启动 hook,以及可选 SQLite 代码依据索引。代理可以从项目计划开始,被路由到正确文档,并在不反复扫描整个仓库的情况下查看由代码支撑的依据。
|
|
11
11
|
|
|
@@ -21,7 +21,8 @@ Project Librarian 给代理两个本地事实来源。
|
|
|
21
21
|
| --- | --- |
|
|
22
22
|
| `wiki/startup.md` + `wiki/index.md` | 简短的会话启动摘要和路由器,只读取相关规划页面。 |
|
|
23
23
|
| `wiki/canonical/` 和 `wiki/decisions/` | 当前项目事实、约束、风险、包契约、CLI 行为和持久决策。 |
|
|
24
|
-
| `.codex/` 和 `.
|
|
24
|
+
| `.codex/`、`.claude/`、`.cursor/` 和 `.gemini/` hooks | 不加载整个 wiki 的 Codex/Claude Code/Cursor/Gemini CLI 启动上下文。 |
|
|
25
|
+
| `GEMINI.md` 和 `.cursor/rules/` | 将 Gemini CLI 和 Cursor 路由到同一个紧凑 wiki-first 契约的 instruction 文件。 |
|
|
25
26
|
| `.project-wiki/code-evidence.sqlite` | 可再生成的代码依据,用于文件、符号、import、route、所有权、工作区图、报告和影响检查。 |
|
|
26
27
|
| 诊断和迁移模式 | 链接检查、质量检查、迁移收件箱、过期信号报告,以及工作流暴露问题时的 issue draft。 |
|
|
27
28
|
|
|
@@ -31,64 +32,41 @@ Project Librarian 给代理两个本地事实来源。
|
|
|
31
32
|
|
|
32
33
|
基准是维护者发布依据,不是公开用户工作流。它让 README 和发布说明用有边界的数字说明价值,而不是使用模糊性能描述。
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
|
37
|
-
| --- | ---: |
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
| 代码索引文件 | 1,608 |
|
|
44
|
-
| 代码索引时间 | 336.312ms |
|
|
45
|
-
| 代码索引吞吐量 | 4,781.27 files/sec |
|
|
46
|
-
| 增量索引时间 | 186.776ms |
|
|
47
|
-
| 全量到增量的时间降低 | 45.52% |
|
|
48
|
-
| 架构报告时间 | 251.175ms |
|
|
49
|
-
| 架构报告依据表 | 6 |
|
|
50
|
-
| 架构报告 route | 24 |
|
|
51
|
-
| 样本仓库 | 3 |
|
|
52
|
-
| 基准运行 | 5 |
|
|
53
|
-
| 预热运行 | 1 |
|
|
54
|
-
| 时间测量状态 | stable |
|
|
55
|
-
| 不稳定指标 | none |
|
|
56
|
-
|
|
57
|
-
场景摘要:
|
|
58
|
-
|
|
59
|
-
| 场景 | 规模 | 结果 |
|
|
60
|
-
| --- | ---: | --- |
|
|
61
|
-
| 文档密集 wiki | 500页 | 99.74% Markdown 上下文估算避免,99.47% 读取降低,43.83ms query |
|
|
62
|
-
| Monorepo wiki | 320页 | 99.43% Markdown 上下文估算避免,99.26% 读取降低,81.12ms doctor |
|
|
63
|
-
| 分范围路由 wiki | 720页 | 99.61% Markdown 上下文估算避免,99.55% 读取降低,67.684ms refresh |
|
|
64
|
-
| 代码密集混合索引 | 1,608个文件 | 336.312ms 全量索引,186.776ms 增量,251.175ms 报告,626.969ms Tree-sitter 索引 |
|
|
65
|
-
| 样本仓库验证 | 3个仓库、16个文件 | 132.363ms 代码索引中位数,135.694ms 架构报告中位数 |
|
|
66
|
-
|
|
67
|
-
声明边界:token 估算值是使用 `ceil(characters / 4)` 得到的 Markdown 上下文大小估算。它不是模型 tokenizer 输出,也不是 API 计费计数器,更不是实际 LLM token 使用量。基准比较 targeted retrieval 读取的 wiki 上下文,相比读取 fixture 中所有 wiki Markdown 文件的 naive full-wiki scan,能避免多少 Markdown 上下文输入。代码索引指标是在生成/样本仓库上测得的本地 CLI 子进程时间。
|
|
35
|
+
当前本地测量报告:`benchmarks/reports/llm/current-local.json` 和 `benchmarks/reports/llm/current-local.md`,生成于 2026-06-10,ChatGPT/Codex auth,`gpt-5.5`,`decision_lookup`,每个条件 1 次测量运行,无预热。以下值是真实 Codex JSONL usage 和本地 wall-clock 测量。正 delta 表示 Project Librarian 条件比 no-Project-Librarian control 使用更多。
|
|
36
|
+
|
|
37
|
+
| Scale | 未使用 Project Librarian | 使用 Project Librarian | 实测 delta |
|
|
38
|
+
| --- | ---: | ---: | ---: |
|
|
39
|
+
| Small | total 102,655 tokens; input 101,226; 37.15s; command 9次 | total 176,104 tokens; input 173,733; 61.04s; command 15次 | tokens +71.55%; time +64.33%; commands +66.67% |
|
|
40
|
+
| Medium | total 79,340 tokens; input 78,348; 44.28s; command 5次 | total 165,840 tokens; input 163,856; 48.48s; command 10次 | tokens +109.02%; time +9.5%; commands +100% |
|
|
41
|
+
| Large | total 197,097 tokens; input 195,278; 45.87s; command 10次 | total 183,959 tokens; input 181,897; 49.42s; command 13次 | tokens -6.67%; time +7.72%; commands +30% |
|
|
42
|
+
|
|
43
|
+
声明边界:这次经批准的本地运行通过了 benchmark claim gate,但不是 clean release baseline。它基于 dirty worktree、每个条件只运行 1 次,而且 runtime state files 触碰了生成的 fixture 目录,因此 post-run fixture fingerprint validator 需要 clean isolated rerun。在重复的 clean actual-LLM 运行显示稳定 delta 前,不声明 Project Librarian 改善 token 或时间。
|
|
68
44
|
|
|
69
45
|
## 安装
|
|
70
46
|
|
|
71
47
|
只在初始 skill 安装时使用 `npx`。
|
|
72
48
|
|
|
73
49
|
```bash
|
|
74
|
-
npx project-librarian install-skill --scope user --agents
|
|
50
|
+
npx project-librarian install-skill --scope user --agents all
|
|
75
51
|
```
|
|
76
52
|
|
|
77
53
|
安装到当前仓库:
|
|
78
54
|
|
|
79
55
|
```bash
|
|
80
|
-
npx project-librarian install-skill --scope project --agents
|
|
56
|
+
npx project-librarian install-skill --scope project --agents all
|
|
81
57
|
```
|
|
82
58
|
|
|
83
|
-
`install-skill` 只复制可复用的 skill 文件。它不会创建或更新 `AGENTS.md`、`CLAUDE.md`、`wiki/`、`.codex/hooks.json` 或 `.claude/settings.json`。
|
|
59
|
+
`install-skill` 只复制可复用的 skill 文件。它不会创建或更新 `AGENTS.md`、`CLAUDE.md`、`GEMINI.md`、`wiki/`、`.cursor/rules/`、`.cursor/hooks.json`、`.gemini/settings.json`、`.codex/hooks.json` 或 `.claude/settings.json`。
|
|
84
60
|
|
|
85
61
|
| 场景 | 命令 |
|
|
86
62
|
| --- | --- |
|
|
87
|
-
|
|
|
88
|
-
| 安装到当前仓库 | `npx project-librarian install-skill --scope project --agents
|
|
63
|
+
| 为所有支持的 agent 全局安装 | `npx project-librarian install-skill --scope user --agents all` |
|
|
64
|
+
| 安装到当前仓库 | `npx project-librarian install-skill --scope project --agents all` |
|
|
89
65
|
| 只安装 Codex | `npx project-librarian install-skill --agents codex` |
|
|
90
66
|
| 只安装 Claude Code | `npx project-librarian install-skill --agents claude` |
|
|
91
|
-
|
|
|
67
|
+
| 只安装 Cursor | `npx project-librarian install-skill --agents cursor` |
|
|
68
|
+
| 只安装 Gemini CLI | `npx project-librarian install-skill --agents gemini` |
|
|
69
|
+
| 预览安装结果 | `npx project-librarian install-skill --scope project --agents all --dry-run` |
|
|
92
70
|
|
|
93
71
|
## 代理运行路径
|
|
94
72
|
|
|
@@ -98,8 +76,12 @@ npx project-librarian install-skill --scope project --agents both
|
|
|
98
76
|
| --- | --- |
|
|
99
77
|
| 项目范围 Codex skill | `node .codex/skills/project-librarian/dist/init-project-wiki.js` |
|
|
100
78
|
| 项目范围 Claude skill | `node .claude/skills/project-librarian/dist/init-project-wiki.js` |
|
|
79
|
+
| 项目范围 Cursor skill | `node .cursor/skills/project-librarian/dist/init-project-wiki.js` |
|
|
80
|
+
| 项目范围 Gemini skill | `node .gemini/skills/project-librarian/dist/init-project-wiki.js` |
|
|
101
81
|
| 用户范围 Codex skill | `node ~/.codex/skills/project-librarian/dist/init-project-wiki.js` |
|
|
102
82
|
| 用户范围 Claude skill | `node ~/.claude/skills/project-librarian/dist/init-project-wiki.js` |
|
|
83
|
+
| 用户范围 Cursor skill | `node ~/.cursor/skills/project-librarian/dist/init-project-wiki.js` |
|
|
84
|
+
| 用户范围 Gemini skill | `node ~/.gemini/skills/project-librarian/dist/init-project-wiki.js` |
|
|
103
85
|
|
|
104
86
|
下面示例使用:
|
|
105
87
|
|
|
@@ -154,11 +136,17 @@ Wiki 验证和维护:
|
|
|
154
136
|
|
|
155
137
|
- `AGENTS.md`
|
|
156
138
|
- `CLAUDE.md`
|
|
139
|
+
- `GEMINI.md`
|
|
157
140
|
- `wiki/AGENTS.md`
|
|
141
|
+
- `.cursor/rules/project-librarian.mdc`
|
|
158
142
|
- `.codex/hooks.json`
|
|
159
143
|
- `.codex/hooks/wiki-session-start.js`
|
|
160
144
|
- `.claude/settings.json`
|
|
161
145
|
- `.claude/hooks/wiki-session-start.js`
|
|
146
|
+
- `.cursor/hooks.json`
|
|
147
|
+
- `.cursor/hooks/wiki-session-start.js`
|
|
148
|
+
- `.gemini/settings.json`
|
|
149
|
+
- `.gemini/hooks/wiki-session-start.js`
|
|
162
150
|
- `.githooks/prepare-commit-msg`
|
|
163
151
|
- `.githooks/wiki-commit-trailers.js`
|
|
164
152
|
- `wiki/canonical/`, `wiki/decisions/`, `wiki/inbox/`, `wiki/meta/`, `wiki/sources/`, `wiki/migration/`
|
|
@@ -172,9 +160,9 @@ Wiki 验证和维护:
|
|
|
172
160
|
4. `--refresh-index` 路由新的 wiki page;route 很多时拆分到 `wiki/indexes/auto-*.md` 分范围路由器。
|
|
173
161
|
5. `--code-index` 在 `.project-wiki/` 下创建可丢弃 SQLite 依据缓存。
|
|
174
162
|
6. `--code-report`、`--code-impact`、`--code-search-symbol`、`--code-query` 为规划更新提供代码依据。
|
|
175
|
-
7. 诊断报告坏链接、重复 route、orphan page、过期页面、缺少 TL;DR、依据 gap
|
|
163
|
+
7. 诊断报告坏链接、重复 route、orphan page、过期页面、缺少 TL;DR、依据 gap 和迁移策略违规。
|
|
176
164
|
|
|
177
|
-
迁移以审查为先。`--migrate` 会把已有 `wiki/` 保存为 `wiki_legacy*`,写入 migration inbox
|
|
165
|
+
迁移以审查为先。`--migrate` 会把已有 `wiki/` 保存为 `wiki_legacy*`,写入 migration inbox 和 unit-level coverage ledger,并把 legacy 含义按当前 wiki 规则重构。保留或复制的 legacy 内容只要符合新 wiki 的策略和结构即可接受;新的 wiki 不应依赖引用 `wiki_legacy*` 才能被理解。
|
|
178
166
|
|
|
179
167
|
## 语言支持表
|
|
180
168
|
|
|
@@ -201,10 +189,10 @@ Wiki 验证和维护:
|
|
|
201
189
|
|
|
202
190
|
```bash
|
|
203
191
|
$PROJECT_LIBRARIAN [init] [options]
|
|
204
|
-
$PROJECT_LIBRARIAN install-skill [--scope user|project] [--agents codex|claude|both]
|
|
192
|
+
$PROJECT_LIBRARIAN install-skill [--scope user|project] [--agents codex|claude|cursor|gemini|all|both]
|
|
205
193
|
```
|
|
206
194
|
|
|
207
|
-
重要选项:`--migrate`, `--lint`, `--link-check`, `--quality-check`, `--doctor`, `--doctor --fix`, `--query`, `--refresh-index`, `--capture-inbox`, `--issue-draft`, `--issue-create`, `--glossary-init`, `--prune-check`, `--review-migration`, `--no-git-config`, `--code-index`, `--code-report`, `--code-impact`, `--code-search-symbol`, `--code-query`.
|
|
195
|
+
重要选项:`--migrate`, `--lint`, `--link-check`, `--quality-check`, `--doctor`, `--doctor --fix`, `--migration-lint`, `--migration-quality-check`, `--migration-doctor`, `--query`, `--refresh-index`, `--capture-inbox`, `--issue-draft`, `--issue-create`, `--glossary-init`, `--prune-check`, `--review-migration`, `--no-git-config`, `--code-index`, `--code-report`, `--code-impact`, `--code-search-symbol`, `--code-query`.
|
|
208
196
|
|
|
209
197
|
## 开发
|
|
210
198
|
|
package/SKILL.md
CHANGED
|
@@ -37,8 +37,12 @@ Prefer an already installed local runner over network package execution:
|
|
|
37
37
|
- In the project-librarian source repository, use `node dist/init-project-wiki.js` when `dist/init-project-wiki.js` exists.
|
|
38
38
|
- In a target repository with a project-scoped Codex skill install, use `node .codex/skills/project-librarian/dist/init-project-wiki.js`.
|
|
39
39
|
- In a target repository with a project-scoped Claude skill install, use `node .claude/skills/project-librarian/dist/init-project-wiki.js`.
|
|
40
|
+
- In a target repository with a project-scoped Cursor skill install, use `node .cursor/skills/project-librarian/dist/init-project-wiki.js`.
|
|
41
|
+
- In a target repository with a project-scoped Gemini skill install, use `node .gemini/skills/project-librarian/dist/init-project-wiki.js`.
|
|
40
42
|
- In a user-scoped Codex skill install, use `node ~/.codex/skills/project-librarian/dist/init-project-wiki.js`.
|
|
41
43
|
- In a user-scoped Claude skill install, use `node ~/.claude/skills/project-librarian/dist/init-project-wiki.js`.
|
|
44
|
+
- In a user-scoped Cursor skill install, use `node ~/.cursor/skills/project-librarian/dist/init-project-wiki.js`.
|
|
45
|
+
- In a user-scoped Gemini skill install, use `node ~/.gemini/skills/project-librarian/dist/init-project-wiki.js`.
|
|
42
46
|
|
|
43
47
|
Use `npx` or `npm exec` only when no local runner exists and registry access is explicitly acceptable for the environment. When using npm package execution, pin the package version instead of running an unpinned public package.
|
|
44
48
|
|
|
@@ -68,6 +72,7 @@ Map lifecycle requests to these internal operations:
|
|
|
68
72
|
- Check wiki links and routing: `$PROJECT_LIBRARIAN --link-check`.
|
|
69
73
|
- Check document quality signals: `$PROJECT_LIBRARIAN --quality-check`.
|
|
70
74
|
- Run all wiki diagnostics: `$PROJECT_LIBRARIAN --doctor`.
|
|
75
|
+
- Check migration-specific review signals: `$PROJECT_LIBRARIAN --migration-doctor`.
|
|
71
76
|
- Safely refresh generated routing before diagnostics: `$PROJECT_LIBRARIAN --doctor --fix`.
|
|
72
77
|
- Search the wiki: `$PROJECT_LIBRARIAN --query "search terms"`.
|
|
73
78
|
- Refresh wiki routing/index: `$PROJECT_LIBRARIAN --refresh-index`.
|
|
@@ -89,9 +94,11 @@ Skill problem reporting contract:
|
|
|
89
94
|
```bash
|
|
90
95
|
node .codex/hooks/wiki-session-start.js
|
|
91
96
|
node .claude/hooks/wiki-session-start.js
|
|
97
|
+
node .cursor/hooks/wiki-session-start.js
|
|
98
|
+
GEMINI_PROJECT_DIR="$PWD" node .gemini/hooks/wiki-session-start.js
|
|
92
99
|
$PROJECT_LIBRARIAN --lint
|
|
93
100
|
$PROJECT_LIBRARIAN --doctor
|
|
94
|
-
node -e '
|
|
101
|
+
node -e 'const fs=require("fs"); JSON.parse(fs.readFileSync(".codex/hooks.json","utf8")); JSON.parse(fs.readFileSync(".claude/settings.json","utf8")); JSON.parse(fs.readFileSync(".cursor/hooks.json","utf8")); JSON.parse(fs.readFileSync(".gemini/settings.json","utf8")); if (!fs.readFileSync("GEMINI.md","utf8").includes("@AGENTS.md")) process.exit(1); if (!fs.readFileSync(".cursor/rules/project-librarian.mdc","utf8").includes("@AGENTS.md")) process.exit(1); console.log("project librarian ok")'
|
|
95
102
|
```
|
|
96
103
|
|
|
97
104
|
4. Report the files created or updated.
|
|
@@ -102,7 +109,7 @@ The script is idempotent. It creates missing files, updates the managed startup/
|
|
|
102
109
|
|
|
103
110
|
Existing root instruction files are preservation-first:
|
|
104
111
|
|
|
105
|
-
- Existing `AGENTS.md`, `CLAUDE.md`, and `wiki/AGENTS.md` files are not overwritten wholesale.
|
|
112
|
+
- Existing `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, and `wiki/AGENTS.md` files are not overwritten wholesale.
|
|
106
113
|
- If no managed project-wiki section exists, bootstrap appends its marker-bounded section to the existing file.
|
|
107
114
|
- On rerun, bootstrap replaces only content between its own `PROJECT-WIKI-*` markers and preserves surrounding project-specific content.
|
|
108
115
|
|
|
@@ -112,7 +119,7 @@ Use `--lint` for read-only validation:
|
|
|
112
119
|
$PROJECT_LIBRARIAN --lint
|
|
113
120
|
```
|
|
114
121
|
|
|
115
|
-
Use `--query`, `--prune-check`, `--issue-draft`, `--link-check`, `--quality-check`, and `--doctor` for read-only inspection/output through the resolved runner. Use `--doctor --fix` when safe generated routing refresh is intended. Use `--refresh-index`, `--capture-inbox`, `--glossary-init`, and `--migrate` only when updating wiki files is intended.
|
|
122
|
+
Use `--query`, `--prune-check`, `--issue-draft`, `--link-check`, `--quality-check`, `--doctor`, `--migration-lint`, `--migration-quality-check`, and `--migration-doctor` for read-only inspection/output through the resolved runner. Use `--doctor --fix` when safe generated routing refresh is intended. Use `--refresh-index`, `--capture-inbox`, `--glossary-init`, and `--migrate` only when updating wiki files is intended.
|
|
116
123
|
|
|
117
124
|
Use `--review-migration` or `--semantic-migrate` after migration inbox rows are processed. It syncs inbox statuses into `wiki/migration/review.md` and `wiki/migration/verification.md`.
|
|
118
125
|
|
|
@@ -204,13 +211,19 @@ It installs:
|
|
|
204
211
|
|
|
205
212
|
- `AGENTS.md` compact project-wide wiki-first planning instructions.
|
|
206
213
|
- `CLAUDE.md` compact Claude Code compatibility file that imports `AGENTS.md`.
|
|
214
|
+
- `GEMINI.md` compact Gemini CLI compatibility file that imports `AGENTS.md`.
|
|
207
215
|
- `wiki/AGENTS.md` detailed wiki-internal editing and boundary rules.
|
|
216
|
+
- `.cursor/rules/project-librarian.mdc` compact always-applied Cursor rule that references `AGENTS.md`.
|
|
208
217
|
- `.githooks/prepare-commit-msg` wiki commit trailer hook.
|
|
209
218
|
- `.githooks/wiki-commit-trailers.js` staged-file based trailer generator.
|
|
210
219
|
- `.codex/hooks.json` `SessionStart` hook.
|
|
211
220
|
- `.codex/hooks/wiki-session-start.js` compact startup context injector.
|
|
212
221
|
- `.claude/settings.json` Claude Code `SessionStart` hook.
|
|
213
222
|
- `.claude/hooks/wiki-session-start.js` compact startup context injector for Claude Code.
|
|
223
|
+
- `.cursor/hooks.json` Cursor `sessionStart` hook.
|
|
224
|
+
- `.cursor/hooks/wiki-session-start.js` compact startup context injector for Cursor.
|
|
225
|
+
- `.gemini/settings.json` Gemini CLI `SessionStart` hook.
|
|
226
|
+
- `.gemini/hooks/wiki-session-start.js` compact startup context injector for Gemini CLI.
|
|
214
227
|
- `wiki/startup.md` compact session-start context.
|
|
215
228
|
- `wiki/index.md` router with read/update/token-budget hints.
|
|
216
229
|
- `wiki/canonical/` project-current-truth starter documents.
|
|
@@ -219,7 +232,7 @@ It installs:
|
|
|
219
232
|
- `wiki/meta/` wiki operating rules, project decision policy, and wiki-operations Decision Pack.
|
|
220
233
|
- `wiki/sources/` source summary starter documents.
|
|
221
234
|
|
|
222
|
-
The Codex
|
|
235
|
+
The Codex, Claude Code, Cursor, and Gemini CLI startup hooks inject only `wiki/startup.md` and `wiki/index.md`. Codex uses `.codex/hooks.json` plus `.codex/hooks/wiki-session-start.js`; Claude Code uses `.claude/settings.json` plus `.claude/hooks/wiki-session-start.js`; Cursor uses `.cursor/hooks.json` plus `.cursor/hooks/wiki-session-start.js`; Gemini CLI uses `.gemini/settings.json` plus `.gemini/hooks/wiki-session-start.js`. `CLAUDE.md` and `GEMINI.md` import `AGENTS.md`, and `.cursor/rules/project-librarian.mdc` references `AGENTS.md`, so Claude Code, Gemini CLI, and Cursor share the same compact wiki-first instruction contract without duplicating the rules. `AGENTS.md` should stay compact and project-wide; `wiki/AGENTS.md` should carry detailed wiki editing rules. `wiki/startup.md` should route detailed canonical and decision files as Read On Demand, not Always Read First, so detailed files are read only when the current question needs them.
|
|
223
236
|
|
|
224
237
|
When the project is a git repository, the script configures `git config core.hooksPath .githooks` by default only when `core.hooksPath` is unset, so wiki commit trailers are generated automatically without replacing an existing hook chain. Use `--no-git-config` to install hook files without changing git config. If the project is not a git repository yet, the hook files are still installed and will work after `core.hooksPath` is set.
|
|
225
238
|
|
|
@@ -249,7 +262,7 @@ Every wiki markdown file should include a compact metadata header with `status`,
|
|
|
249
262
|
|
|
250
263
|
Wiki-specific commit trailers are automated through `.githooks/prepare-commit-msg`.
|
|
251
264
|
|
|
252
|
-
The hook runs when staged files include `wiki/`, `AGENTS.md`, `CLAUDE.md`, `.codex/hooks.json`, `.codex/hooks/`, `.claude/settings.json`, `.claude/hooks/`, `.githooks/`, or `tools/project-librarian/`.
|
|
265
|
+
The hook runs when staged files include `wiki/`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.cursor/rules/`, `.cursor/hooks.json`, `.cursor/hooks/`, `.gemini/settings.json`, `.gemini/hooks/`, `.codex/hooks.json`, `.codex/hooks/`, `.claude/settings.json`, `.claude/hooks/`, `.githooks/`, or `tools/project-librarian/`.
|
|
253
266
|
|
|
254
267
|
It appends these trailers when they are missing:
|
|
255
268
|
|
|
@@ -264,7 +277,7 @@ It appends these trailers when they are missing:
|
|
|
264
277
|
|
|
265
278
|
Do not hand-write wiki trailers unless the hook is unavailable or the generated value needs correction.
|
|
266
279
|
|
|
267
|
-
`--lint` verifies the Codex and
|
|
280
|
+
`--lint` verifies the Codex, Claude, Cursor, and Gemini hook files/settings, Cursor and Gemini instruction files, git hook files, executable bits, trailer phrases, and `core.hooksPath` when the project is a git repository. If `--no-git-config` was used, an unset or different `core.hooksPath` is expected until the project owner configures it manually.
|
|
268
281
|
|
|
269
282
|
## Glossary Mode
|
|
270
283
|
|
|
@@ -297,20 +310,22 @@ Captured inbox entries are not canonical. Fold them into `wiki/canonical/`, `wik
|
|
|
297
310
|
|
|
298
311
|
`--migrate` and `--adopt-existing` are aliases.
|
|
299
312
|
|
|
300
|
-
Migration mode is a reset-and-
|
|
313
|
+
Migration mode is a reset-and-restructure flow:
|
|
301
314
|
|
|
302
315
|
- If `./wiki` exists, renames it to `./wiki_legacy`.
|
|
303
316
|
- If `./wiki_legacy` already exists, preserves both by using a timestamped `wiki_legacy_...` directory for the current wiki.
|
|
304
317
|
- Creates a fresh `./wiki` using the current standard rules.
|
|
305
318
|
- Scans markdown files under the legacy wiki directory.
|
|
306
|
-
- Writes `wiki/migration/inventory.md`, `wiki/migration/plan.md`, and `wiki/migration/verification.md`.
|
|
319
|
+
- Writes `wiki/migration/inventory.md`, `wiki/migration/coverage.md`, `wiki/migration/plan.md`, and `wiki/migration/verification.md`.
|
|
307
320
|
- Writes rewrite inboxes:
|
|
308
321
|
- `wiki/canonical/migration-inbox.md`
|
|
309
322
|
- `wiki/decisions/migration-inbox.md`
|
|
310
323
|
- `wiki/sources/migration-inbox.md`
|
|
311
324
|
- Adds migration routing to `wiki/startup.md` and `wiki/index.md`.
|
|
312
325
|
|
|
313
|
-
After migration mode, inspect inboxes and fold legacy content into canonical docs, Decision Packs, ADRs, source summaries, or meta docs.
|
|
326
|
+
After migration mode, inspect inboxes and fold legacy content into canonical docs, Decision Packs, ADRs, source summaries, or meta docs. Minimize information loss while converting useful legacy meaning to the current wiki structure and rules. Legacy files, sections, blocks, and wording may be retained when review confirms each retained unit belongs in the new topic shape and remains current project truth. Do not link to or cite `wiki_legacy*` from the new wiki; cite current-project evidence when possible, and keep ambiguous material in the migration inbox or mark it `needs-human-review`.
|
|
327
|
+
|
|
328
|
+
`wiki/migration/coverage.md` is the unit-level coverage ledger. It accounts for legacy headings, paragraphs, list items, table rows, and code blocks with stable unit IDs. Every unit should end as `adopted`, `merged`, `superseded`, `rejected`, `resolved`, or `needs-human-review`; `pending` means the unit is still open. `adopted` and `merged` rows require a new-wiki target under `wiki/canonical/`, `wiki/decisions/`, `wiki/sources/`, or `wiki/meta/`. Deleting a unit row is treated as possible information loss and `--migration-lint` reports it as `migration-unaccounted-unit`.
|
|
314
329
|
|
|
315
330
|
Inbox rows use these statuses:
|
|
316
331
|
|
|
@@ -326,10 +341,10 @@ Run semantic review sync after LLM or human processing:
|
|
|
326
341
|
$PROJECT_LIBRARIAN --review-migration
|
|
327
342
|
```
|
|
328
343
|
|
|
329
|
-
`wiki/migration/verification.md` verifies file coverage: every legacy markdown file should be mapped to a new-wiki migration target.
|
|
344
|
+
`wiki/migration/verification.md` verifies file coverage: every legacy markdown file should be mapped to a new-wiki migration target. `wiki/migration/coverage.md` verifies unit coverage: every extracted legacy meaning unit should remain accounted for. Semantic migration is complete only after inbox rows are marked adopted/rejected/resolved and `needs-human-review` is 0, and unit coverage has no unaccounted rows.
|
|
330
345
|
|
|
331
346
|
Human review is not required for every inbox item. LLM may process ordinary rows and close them as adopted/rejected/resolved. Human review is reserved for `needs-human-review`.
|
|
332
347
|
|
|
333
|
-
Run `$PROJECT_LIBRARIAN --doctor` after migration review. `--quality-check` and `--doctor`
|
|
348
|
+
Run `$PROJECT_LIBRARIAN --migration-doctor` after migration review. Normal `--quality-check` and `--doctor` intentionally omit migration-only policy/structure signals so accepted migration decisions do not pollute later non-migration document checks. `--migration-quality-check` and `--migration-doctor` report `migration-legacy-reference` as an error when active project truth links to or cites `wiki_legacy*`. They do not warn merely because a new wiki document copies legacy wording, blocks, whole documents, or filenames; those are acceptable when the result follows the current wiki policy and structure. Use `--migration-lint` and `wiki/migration/coverage.md` to prevent information loss.
|
|
334
349
|
|
|
335
|
-
Do not delete `wiki_legacy` until migration verification passes, semantic review is complete, and migration
|
|
350
|
+
Do not delete `wiki_legacy` until migration verification passes, semantic review is complete, and migration policy/structure diagnostics are clear.
|
package/dist/args.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.issueDraftTitle = exports.issueBodyFile = exports.captureCategory = exports.captureContent = exports.captureTitle = exports.codeIndexScopes = exports.codeParser = exports.codeIndexOutput = exports.codeSearchSymbol = exports.codeReportSection = exports.codeQuerySql = exports.codeImpactTarget = exports.queryTerm = exports.codeSearchSymbolMode = exports.codeQueryMode = exports.codeImpactMode = exports.codeParserMode = exports.codeFilesMode = exports.codeStatusMode = exports.codeReportMode = exports.codeIndexFullMode = exports.codeIndexIncrementalMode = exports.codeIndexMode = exports.noGitConfigMode = exports.reviewMigrationMode = exports.pruneCheckMode = exports.captureInboxMode = exports.refreshIndexMode = exports.issueDraftMode = exports.issueCreateMode = exports.glossaryMode = exports.fixMode = exports.doctorMode = exports.qualityCheckMode = exports.linkCheckMode = exports.lintMode = exports.migrateMode = exports.missingValueOptions = exports.unexpectedValueOptions = exports.unknownOptions = exports.args = exports.commandArgs = exports.command = exports.unknownCommand = exports.helpMode = exports.parsedArgs = exports.rawArgs = void 0;
|
|
3
|
+
exports.issueDraftTitle = exports.issueBodyFile = exports.captureCategory = exports.captureContent = exports.captureTitle = exports.codeIndexScopes = exports.codeParser = exports.codeIndexOutput = exports.codeSearchSymbol = exports.codeReportSection = exports.codeQuerySql = exports.codeImpactTarget = exports.queryTerm = exports.codeSearchSymbolMode = exports.codeQueryMode = exports.codeImpactMode = exports.codeParserMode = exports.codeFilesMode = exports.codeStatusMode = exports.codeReportMode = exports.codeIndexFullMode = exports.codeIndexIncrementalMode = exports.codeIndexMode = exports.noGitConfigMode = exports.reviewMigrationMode = exports.pruneCheckMode = exports.captureInboxMode = exports.refreshIndexMode = exports.issueDraftMode = exports.issueCreateMode = exports.glossaryMode = exports.fixMode = exports.doctorMode = exports.qualityCheckMode = exports.linkCheckMode = exports.migrationQualityCheckMode = exports.migrationLintMode = exports.migrationDoctorMode = exports.lintMode = exports.migrateMode = exports.missingValueOptions = exports.unexpectedValueOptions = exports.unknownOptions = exports.args = exports.commandArgs = exports.command = exports.unknownCommand = exports.helpMode = exports.parsedArgs = exports.rawArgs = void 0;
|
|
4
4
|
exports.parseArgs = parseArgs;
|
|
5
5
|
exports.argValue = argValue;
|
|
6
6
|
exports.argValues = argValues;
|
|
@@ -32,6 +32,9 @@ const flagsWithoutValues = new Set([
|
|
|
32
32
|
"--link-check",
|
|
33
33
|
"--lint",
|
|
34
34
|
"--migrate",
|
|
35
|
+
"--migration-doctor",
|
|
36
|
+
"--migration-lint",
|
|
37
|
+
"--migration-quality-check",
|
|
35
38
|
"--no-git-config",
|
|
36
39
|
"--prune-check",
|
|
37
40
|
"--quality-check",
|
|
@@ -161,6 +164,9 @@ function parseArgs(argv) {
|
|
|
161
164
|
issueDraftTitle: argValue("--issue-title"),
|
|
162
165
|
linkCheckMode: args.has("--link-check"),
|
|
163
166
|
lintMode: args.has("--lint"),
|
|
167
|
+
migrationDoctorMode: args.has("--migration-doctor"),
|
|
168
|
+
migrationLintMode: args.has("--migration-lint"),
|
|
169
|
+
migrationQualityCheckMode: args.has("--migration-quality-check"),
|
|
164
170
|
migrateMode: args.has("--migrate") || args.has("--adopt-existing"),
|
|
165
171
|
missingValueOptions: Array.from(flagsWithValues).filter((flag) => hasFlag(flag) && !flagHasValue(commandArgs, flag)),
|
|
166
172
|
noGitConfigMode: args.has("--no-git-config"),
|
|
@@ -192,6 +198,9 @@ exports.unexpectedValueOptions = exports.parsedArgs.unexpectedValueOptions;
|
|
|
192
198
|
exports.missingValueOptions = exports.parsedArgs.missingValueOptions;
|
|
193
199
|
exports.migrateMode = exports.parsedArgs.migrateMode;
|
|
194
200
|
exports.lintMode = exports.parsedArgs.lintMode;
|
|
201
|
+
exports.migrationDoctorMode = exports.parsedArgs.migrationDoctorMode;
|
|
202
|
+
exports.migrationLintMode = exports.parsedArgs.migrationLintMode;
|
|
203
|
+
exports.migrationQualityCheckMode = exports.parsedArgs.migrationQualityCheckMode;
|
|
195
204
|
exports.linkCheckMode = exports.parsedArgs.linkCheckMode;
|
|
196
205
|
exports.qualityCheckMode = exports.parsedArgs.qualityCheckMode;
|
|
197
206
|
exports.doctorMode = exports.parsedArgs.doctorMode;
|
package/dist/hooks.js
CHANGED
|
@@ -33,10 +33,12 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.gitWikiCommitTrailersScript = exports.gitPrepareCommitMsgHook = exports.hookScript = void 0;
|
|
36
|
+
exports.gitWikiCommitTrailersScript = exports.gitPrepareCommitMsgHook = exports.cursorHookScript = exports.hookScript = void 0;
|
|
37
37
|
exports.upsertGitHooksPath = upsertGitHooksPath;
|
|
38
38
|
exports.upsertHookConfig = upsertHookConfig;
|
|
39
39
|
exports.upsertClaudeHookConfig = upsertClaudeHookConfig;
|
|
40
|
+
exports.upsertGeminiHookConfig = upsertGeminiHookConfig;
|
|
41
|
+
exports.upsertCursorHookConfig = upsertCursorHookConfig;
|
|
40
42
|
const childProcess = __importStar(require("node:child_process"));
|
|
41
43
|
const args_1 = require("./args");
|
|
42
44
|
const workspace_1 = require("./workspace");
|
|
@@ -109,7 +111,33 @@ function upsertHookConfig() {
|
|
|
109
111
|
function upsertClaudeHookConfig() {
|
|
110
112
|
return upsertSessionStartHookConfig(".claude/settings.json", "node .claude/hooks/wiki-session-start.js", ["startup", "resume", "clear", "compact"]);
|
|
111
113
|
}
|
|
112
|
-
|
|
114
|
+
function upsertGeminiHookConfig() {
|
|
115
|
+
return upsertSessionStartHookConfig(".gemini/settings.json", 'node "$GEMINI_PROJECT_DIR/.gemini/hooks/wiki-session-start.js"', ["startup", "resume", "clear"]);
|
|
116
|
+
}
|
|
117
|
+
function isCursorHookCommand(value) {
|
|
118
|
+
return Boolean(value) && typeof value === "object" && typeof value.command === "string";
|
|
119
|
+
}
|
|
120
|
+
function upsertCursorHookConfig() {
|
|
121
|
+
const relativePath = ".cursor/hooks.json";
|
|
122
|
+
const command = "node .cursor/hooks/wiki-session-start.js";
|
|
123
|
+
const config = (0, workspace_1.parseJson)(relativePath, { version: 1, hooks: {} });
|
|
124
|
+
if (typeof config.version !== "number")
|
|
125
|
+
config.version = 1;
|
|
126
|
+
if (!config.hooks || typeof config.hooks !== "object" || Array.isArray(config.hooks)) {
|
|
127
|
+
config.hooks = {};
|
|
128
|
+
}
|
|
129
|
+
const existing = Array.isArray(config.hooks.sessionStart) ? config.hooks.sessionStart.filter(isCursorHookCommand) : [];
|
|
130
|
+
config.hooks.sessionStart = [
|
|
131
|
+
...existing.filter((hook) => hook.command !== command),
|
|
132
|
+
{ command },
|
|
133
|
+
];
|
|
134
|
+
const next = `${JSON.stringify(config, null, 2)}\n`;
|
|
135
|
+
const previous = (0, workspace_1.exists)(relativePath) ? (0, workspace_1.read)(relativePath) : "";
|
|
136
|
+
(0, workspace_1.write)(relativePath, next);
|
|
137
|
+
return previous === next ? "exists" : previous ? "updated" : "created";
|
|
138
|
+
}
|
|
139
|
+
function buildStartupHookScript(output) {
|
|
140
|
+
return `#!/usr/bin/env node
|
|
113
141
|
|
|
114
142
|
const fs = require("fs");
|
|
115
143
|
const path = require("path");
|
|
@@ -127,7 +155,7 @@ function readHookInput() {
|
|
|
127
155
|
}
|
|
128
156
|
|
|
129
157
|
const hookInput = readHookInput();
|
|
130
|
-
const cwd = process.env.CODEX_WORKSPACE_DIR || hookInput.cwd || process.cwd();
|
|
158
|
+
const cwd = process.env.GEMINI_PROJECT_DIR || process.env.CODEX_WORKSPACE_DIR || process.env.CLAUDE_PROJECT_DIR || hookInput.cwd || process.cwd();
|
|
131
159
|
|
|
132
160
|
function readIfExists(relativePath, maxChars) {
|
|
133
161
|
const filePath = path.join(cwd, relativePath);
|
|
@@ -164,10 +192,15 @@ const additionalContext = [
|
|
|
164
192
|
].join("\\n");
|
|
165
193
|
|
|
166
194
|
process.stdout.write(JSON.stringify({
|
|
167
|
-
|
|
168
|
-
hookSpecificOutput: { hookEventName: "SessionStart", additionalContext },
|
|
195
|
+
${output}
|
|
169
196
|
}));
|
|
170
197
|
`;
|
|
198
|
+
}
|
|
199
|
+
exports.hookScript = buildStartupHookScript(` continue: true,
|
|
200
|
+
hookSpecificOutput: { hookEventName: "SessionStart", additionalContext },
|
|
201
|
+
`);
|
|
202
|
+
exports.cursorHookScript = buildStartupHookScript(` additional_context: additionalContext,
|
|
203
|
+
`);
|
|
171
204
|
exports.gitPrepareCommitMsgHook = `#!/bin/sh
|
|
172
205
|
MSG_FILE="$1"
|
|
173
206
|
SOURCE="$2"
|
|
@@ -253,7 +286,10 @@ function wikiScope(files) {
|
|
|
253
286
|
else if (file === "wiki/index.md") add("index");
|
|
254
287
|
else if (file.startsWith(".codex/hooks/") || file === ".codex/hooks.json") add("codex-hooks");
|
|
255
288
|
else if (file.startsWith(".claude/hooks/") || file === ".claude/settings.json") add("claude-hooks");
|
|
256
|
-
else if (file
|
|
289
|
+
else if (file.startsWith(".cursor/hooks/") || file === ".cursor/hooks.json") add("cursor-hooks");
|
|
290
|
+
else if (file.startsWith(".cursor/rules/")) add("cursor-rules");
|
|
291
|
+
else if (file.startsWith(".gemini/hooks/") || file === ".gemini/settings.json") add("gemini-hooks");
|
|
292
|
+
else if (file === "AGENTS.md" || file === "CLAUDE.md" || file === "GEMINI.md") add("agents");
|
|
257
293
|
else if (file.startsWith(".githooks/")) add("git-hooks");
|
|
258
294
|
else if (file.startsWith("tools/project-librarian/")) add("skill");
|
|
259
295
|
}
|
|
@@ -266,15 +302,31 @@ function validationTrailers() {
|
|
|
266
302
|
"tools/project-librarian/dist/init-project-wiki.js",
|
|
267
303
|
path.join(home, ".codex/skills/project-librarian/dist/init-project-wiki.js"),
|
|
268
304
|
path.join(home, ".claude/skills/project-librarian/dist/init-project-wiki.js"),
|
|
305
|
+
path.join(home, ".cursor/skills/project-librarian/dist/init-project-wiki.js"),
|
|
306
|
+
path.join(home, ".gemini/skills/project-librarian/dist/init-project-wiki.js"),
|
|
269
307
|
].find((candidate) => fs.existsSync(candidate));
|
|
270
308
|
const lintOk = Boolean(lintScript) && commandOk("node", [lintScript, "--lint"]);
|
|
271
309
|
const codexSessionHookOk = fs.existsSync(".codex/hooks/wiki-session-start.js") && commandOk("node", [".codex/hooks/wiki-session-start.js"]);
|
|
272
310
|
const claudeSessionHookOk = fs.existsSync(".claude/hooks/wiki-session-start.js") && commandOk("node", [".claude/hooks/wiki-session-start.js"]);
|
|
273
|
-
|
|
311
|
+
const cursorSessionHookOk = fs.existsSync(".cursor/hooks/wiki-session-start.js") && commandOk("node", [".cursor/hooks/wiki-session-start.js"]);
|
|
312
|
+
const cursorHookConfigOk = fs.existsSync(".cursor/hooks.json") && existingFile(".cursor/hooks.json").includes("node .cursor/hooks/wiki-session-start.js");
|
|
313
|
+
const geminiSessionHookOk = fs.existsSync(".gemini/hooks/wiki-session-start.js") && commandOk("node", [".gemini/hooks/wiki-session-start.js"]);
|
|
314
|
+
const geminiHookConfigOk = fs.existsSync(".gemini/settings.json") && existingFile(".gemini/settings.json").includes('node "$GEMINI_PROJECT_DIR/.gemini/hooks/wiki-session-start.js"');
|
|
315
|
+
const geminiInstructionsOk = fs.existsSync("GEMINI.md") && existingFile("GEMINI.md").includes("@AGENTS.md");
|
|
316
|
+
const cursorRuleOk = fs.existsSync(".cursor/rules/project-librarian.mdc") && existingFile(".cursor/rules/project-librarian.mdc").includes("@AGENTS.md");
|
|
317
|
+
if (lintOk && codexSessionHookOk && claudeSessionHookOk && cursorSessionHookOk && cursorHookConfigOk && geminiSessionHookOk && geminiHookConfigOk && geminiInstructionsOk && cursorRuleOk) {
|
|
318
|
+
return { tested: "project wiki lint; Codex, Claude, Cursor, and Gemini wiki session-start hooks; Cursor and Gemini instruction files", notTested: "none" };
|
|
319
|
+
}
|
|
274
320
|
const gaps = [];
|
|
275
321
|
if (!lintOk) gaps.push("project wiki lint");
|
|
276
322
|
if (!codexSessionHookOk) gaps.push("Codex wiki session-start hook");
|
|
277
323
|
if (!claudeSessionHookOk) gaps.push("Claude wiki session-start hook");
|
|
324
|
+
if (!cursorSessionHookOk) gaps.push("Cursor wiki session-start hook");
|
|
325
|
+
if (!cursorHookConfigOk) gaps.push("Cursor hook config");
|
|
326
|
+
if (!geminiSessionHookOk) gaps.push("Gemini wiki SessionStart hook");
|
|
327
|
+
if (!geminiHookConfigOk) gaps.push("Gemini hook config");
|
|
328
|
+
if (!cursorRuleOk) gaps.push("Cursor project rule");
|
|
329
|
+
if (!geminiInstructionsOk) gaps.push("Gemini instructions");
|
|
278
330
|
return { tested: "prepare-commit-msg generated wiki trailers", notTested: gaps.join("; ") || "unknown" };
|
|
279
331
|
}
|
|
280
332
|
|
|
@@ -287,10 +339,16 @@ const wikiFiles = staged.filter((file) => {
|
|
|
287
339
|
return file.startsWith("wiki/")
|
|
288
340
|
|| file === "AGENTS.md"
|
|
289
341
|
|| file === "CLAUDE.md"
|
|
342
|
+
|| file === "GEMINI.md"
|
|
290
343
|
|| file === ".codex/hooks.json"
|
|
291
344
|
|| file.startsWith(".codex/hooks/")
|
|
292
345
|
|| file === ".claude/settings.json"
|
|
293
346
|
|| file.startsWith(".claude/hooks/")
|
|
347
|
+
|| file.startsWith(".cursor/rules/")
|
|
348
|
+
|| file === ".cursor/hooks.json"
|
|
349
|
+
|| file.startsWith(".cursor/hooks/")
|
|
350
|
+
|| file === ".gemini/settings.json"
|
|
351
|
+
|| file.startsWith(".gemini/hooks/")
|
|
294
352
|
|| file.startsWith(".githooks/")
|
|
295
353
|
|| file.startsWith("tools/project-librarian/");
|
|
296
354
|
});
|
|
@@ -15,7 +15,7 @@ function codeIndex() {
|
|
|
15
15
|
function printUsage() {
|
|
16
16
|
console.log(`Usage:
|
|
17
17
|
project-librarian [init] [options]
|
|
18
|
-
project-librarian install-skill [--scope user|project] [--agents codex|claude|both]
|
|
18
|
+
project-librarian install-skill [--scope user|project] [--agents codex|claude|cursor|gemini|all|both]
|
|
19
19
|
|
|
20
20
|
Options:
|
|
21
21
|
--migrate, --adopt-existing Preserve an existing wiki as wiki_legacy and create migration inboxes.
|
|
@@ -24,6 +24,9 @@ Options:
|
|
|
24
24
|
--quality-check Report stale, conflicting, and low-quality wiki document signals.
|
|
25
25
|
--doctor Run lint, link-check, and quality-check together.
|
|
26
26
|
--fix With --doctor, safely refresh generated index routing.
|
|
27
|
+
--migration-lint Validate migration review scaffolding separately from normal lint.
|
|
28
|
+
--migration-quality-check Report migration policy/structure signals separately from normal quality-check.
|
|
29
|
+
--migration-doctor Run migration-lint and migration-quality-check together.
|
|
27
30
|
--issue-create Create a GitHub issue with gh issue create after explicit user approval.
|
|
28
31
|
--issue-draft Print a problem/side-effect GitHub issue body draft.
|
|
29
32
|
--issue-body-file <path> With --issue-create, use an existing Markdown body file.
|
|
@@ -156,6 +159,18 @@ if (args_1.reviewMigrationMode) {
|
|
|
156
159
|
(0, migration_1.runReviewMigrationMode)();
|
|
157
160
|
process.exit(0);
|
|
158
161
|
}
|
|
162
|
+
if (args_1.migrationDoctorMode) {
|
|
163
|
+
(0, modes_1.runMigrationDoctorMode)();
|
|
164
|
+
process.exit(0);
|
|
165
|
+
}
|
|
166
|
+
if (args_1.migrationQualityCheckMode) {
|
|
167
|
+
(0, modes_1.runMigrationQualityCheckMode)();
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
if (args_1.migrationLintMode) {
|
|
171
|
+
(0, modes_1.runMigrationLintMode)();
|
|
172
|
+
process.exit(0);
|
|
173
|
+
}
|
|
159
174
|
if (args_1.doctorMode) {
|
|
160
175
|
(0, modes_1.runDoctorMode)(args_1.fixMode);
|
|
161
176
|
process.exit(0);
|
|
@@ -183,9 +198,14 @@ if (migrationState)
|
|
|
183
198
|
(0, workspace_1.mkdirp)("wiki/sources");
|
|
184
199
|
(0, workspace_1.mkdirp)(".codex/hooks");
|
|
185
200
|
(0, workspace_1.mkdirp)(".claude/hooks");
|
|
201
|
+
(0, workspace_1.mkdirp)(".cursor/hooks");
|
|
202
|
+
(0, workspace_1.mkdirp)(".cursor/rules");
|
|
203
|
+
(0, workspace_1.mkdirp)(".gemini/hooks");
|
|
186
204
|
(0, workspace_1.mkdirp)(".githooks");
|
|
187
205
|
results.push(["AGENTS.md", (0, workspace_1.upsertMarkedSection)("AGENTS.md", "<!-- PROJECT-WIKI-FIRST:START -->", "<!-- PROJECT-WIKI-FIRST:END -->", templates_1.agentsSection)]);
|
|
188
206
|
results.push(["CLAUDE.md", (0, workspace_1.upsertMarkedSection)("CLAUDE.md", "<!-- PROJECT-WIKI-CLAUDE:START -->", "<!-- PROJECT-WIKI-CLAUDE:END -->", templates_1.claudeSection)]);
|
|
207
|
+
results.push(["GEMINI.md", (0, workspace_1.upsertMarkedSection)("GEMINI.md", "<!-- PROJECT-WIKI-GEMINI:START -->", "<!-- PROJECT-WIKI-GEMINI:END -->", templates_1.geminiSection)]);
|
|
208
|
+
results.push([".cursor/rules/project-librarian.mdc", (0, workspace_1.writeManaged)(".cursor/rules/project-librarian.mdc", templates_1.cursorRule)]);
|
|
189
209
|
results.push(["wiki/AGENTS.md", (0, workspace_1.upsertMarkedSection)("wiki/AGENTS.md", "<!-- PROJECT-WIKI-INTERNAL:START -->", "<!-- PROJECT-WIKI-INTERNAL:END -->", templates_1.wikiAgentsSection)]);
|
|
190
210
|
results.push([".githooks/prepare-commit-msg", (0, workspace_1.writeManaged)(".githooks/prepare-commit-msg", hooks_1.gitPrepareCommitMsgHook)]);
|
|
191
211
|
(0, workspace_1.makeExecutable)(".githooks/prepare-commit-msg");
|
|
@@ -196,6 +216,10 @@ results.push([".codex/hooks.json", (0, hooks_1.upsertHookConfig)()]);
|
|
|
196
216
|
results.push([".codex/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".codex/hooks/wiki-session-start.js", hooks_1.hookScript)]);
|
|
197
217
|
results.push([".claude/settings.json", (0, hooks_1.upsertClaudeHookConfig)()]);
|
|
198
218
|
results.push([".claude/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".claude/hooks/wiki-session-start.js", hooks_1.hookScript)]);
|
|
219
|
+
results.push([".cursor/hooks.json", (0, hooks_1.upsertCursorHookConfig)()]);
|
|
220
|
+
results.push([".cursor/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".cursor/hooks/wiki-session-start.js", hooks_1.cursorHookScript)]);
|
|
221
|
+
results.push([".gemini/settings.json", (0, hooks_1.upsertGeminiHookConfig)()]);
|
|
222
|
+
results.push([".gemini/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".gemini/hooks/wiki-session-start.js", hooks_1.hookScript)]);
|
|
199
223
|
results.push(["wiki/startup.md", (0, workspace_1.writeManaged)("wiki/startup.md", (0, wiki_files_1.withPreservedMarkedSections)("wiki/startup.md", templates_1.startup, [["<!-- PROJECT-WIKI-MIGRATION:START -->", "<!-- PROJECT-WIKI-MIGRATION:END -->"]]))]);
|
|
200
224
|
results.push(["wiki/index.md", (0, workspace_1.writeManaged)("wiki/index.md", (0, wiki_files_1.withPreservedMarkedSections)("wiki/index.md", templates_1.index, [
|
|
201
225
|
["<!-- PROJECT-WIKI-MIGRATION:START -->", "<!-- PROJECT-WIKI-MIGRATION:END -->"],
|