project-librarian 0.4.1 → 0.4.3

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.ko.md CHANGED
@@ -52,7 +52,7 @@ Project Librarian은 에이전트에게 두 가지 로컬 정본을 제공합니
52
52
  | 표면 | 에이전트가 얻는 것 |
53
53
  | --- | --- |
54
54
  | `wiki/startup.md` + `wiki/index.md` | 짧은 세션 시작 요약과 라우터. 관련 계획 페이지만 읽습니다. |
55
- | `wiki/canonical/` `wiki/decisions/` | 현재 프로젝트 사실, 제약, 리스크, 패키지 계약, CLI 동작, 지속되는 결정. |
55
+ | `wiki/canonical/`, `wiki/roadmaps/`, `wiki/plans/`, `wiki/decisions/` | 현재 정본은 canonical, 미래 작업은 roadmaps, 상세 실행은 plans, 지속되는 근거는 decisions에 둡니다. |
56
56
  | `wiki/meta/document-taxonomy.md` | PRD, 정책, UX, 데이터, 개발, QA, 릴리즈, 운영 정본을 어디에 둘지 안내하는 서비스 생애주기 분류 지도. |
57
57
  | `.codex/`, `.claude/`, `.cursor/`, `.gemini/` 훅 | 전체 위키를 불러오지 않는 Codex/Claude Code/Cursor/Gemini CLI 시작 컨텍스트. |
58
58
  | `GEMINI.md` 및 `.cursor/rules/` | Gemini CLI와 Cursor를 같은 간결한 위키 우선 계약으로 안내하는 지침 파일. |
@@ -75,17 +75,19 @@ npm run benchmark:release:preview
75
75
  npm run benchmark:release -- --allow-codex-run
76
76
  ```
77
77
 
78
+ 실측 릴리스 실행은 stderr에 `[benchmark:progress]` 줄을 스트리밍하여 시나리오 수, 예상 Codex 실행 총량, 현재 실행 순번, 단계, 프롬프트 ID, 종료 상태, 경과 시간, 원시 JSONL 경로를 보여줍니다. stdout은 최종 JSON 결과 전용으로 유지됩니다.
79
+
78
80
  ### 위키 트랙 (계획 문서 라우팅)
79
81
 
80
82
  비용 가중 토큰, Project Librarian 대 대조군:
81
83
 
82
84
  | 규모 | decision_lookup | aggregation | multi_session (2번째 세션) |
83
85
  | --- | --- | --- | --- |
84
- | 소형 | 43.8% 적음 | 144.5% 많음 | 5.4% 많음 |
85
- | 중형 | 53.4% 적음 | 4.4% 적음 | 68.5% 적음 |
86
- | 대형 | 71.6% 적음* | 12.8% 적음 | 66.0% 적음 |
86
+ | 소형 | 14.4% 적음 | 81.0% 많음 | 22.0% 적음 |
87
+ | 중형 | 52.0% 적음 | 19.0% 적음 | 54.1% 적음 |
88
+ | 대형 | 71.1% 적음 | 29.0% 적음 | 71.8% 적음 |
87
89
 
88
- 최신 합성 위키 트랙 릴리스 후보는 2026-06-16에 `gpt-5.5`로 측정했으며, 42개 시나리오를 각 3회 측정하고 1회 예열했습니다. 전체 주장 게이트는 **실패**했습니다. 42개 41개 시나리오는 정확성 검사를 통과했지만, Project Librarian이 없는 대형 `decision_lookup` 대조군이 3회 2회만 정답이었습니다. 실패한 대조군 실행은 날짜가 붙은 히스토리 파일에서 `2026-05-04`를 골랐고, 기대값은 결정 로그의 최신 벤치마크 근거 결정인 `2026-06-10`이었습니다. 따라서 표는 공개 릴리스 주장이 아니라 진단 근거로만 보아야 하며, 깨끗한 릴리스 실행이 주장 게이트를 통과해야 공개 주장으로 쓸 수 있습니다. 숨기지 않는 한계도 그대로 남습니다. 소형 `aggregation`은 위키를 켰을 때 훨씬 비싸고, 소형 `multi_session`도 약간 비싸며, `aggregation`은 토큰 비용이 줄어드는 규모에서도 실행 시간은 매번 더 느립니다.
90
+ 최신 합성 위키 트랙 릴리스 후보는 2026-06-19에 `gpt-5.5`로 측정했으며, 42개 시나리오를 각 3회 측정하고 1회 예열했습니다. 전체 주장 게이트는 **통과**했습니다. 42/42시나리오가 정확성 검사를 통과했고, 42개 시나리오가 모두 claimable이었으며, 모든 corpus 게이트가 3회 실행 최소 조건을 충족했습니다. 릴리스 주장은 여전히 합성 위키 라우팅 트랙과 표기된 작업 유형에 한정됩니다. 코드 그래프 동작, 실제 저장소, 모든 에이전트 표면, 모든 질문 형태에 대한 주장이 아닙니다. 숨기지 않는 한계도 그대로 남습니다. 소형 `aggregation`은 위키를 켰을 때 여전히 81.0% 비싸고, 전체 보고서의 소형 `release_policy`도 9.4% 비싸며, `aggregation`은 토큰 비용이 줄어드는 규모에서도 실행 시간은 매번 더 느립니다.
89
91
 
90
92
  ### 코드 그래프 트랙 (코드 근거 인덱스, 실제 저장소)
91
93
 
@@ -143,6 +145,8 @@ npx project-librarian install-skill --scope project --agents all
143
145
 
144
146
  `--agents`는 `codex,claude,cursor,gemini`처럼 쉼표로 구분한 값도 받습니다. `all`은 지원하는 모든 에이전트를 대상으로 합니다. `--scope`는 `user` 또는 `project`를 받습니다.
145
147
 
148
+ 프로젝트 설정/갱신 실행기도 `--agents`를 받습니다. 새로 설정할 때는 프로젝트 범위 Project Librarian 스킬 설치가 없을 때만 지원하는 모든 에이전트 표면을 기본으로 만듭니다. 저장소에 이미 `.codex/skills/project-librarian/`, `.claude/skills/project-librarian/` 같은 프로젝트 범위 스킬이 있으면 첫 설정도 그 설치된 에이전트 집합을 기본값으로 사용합니다. 마이그레이션 없는 기존 설정 갱신은 저장소에 이미 있는 에이전트 표면만 보존해서 갱신합니다. 따라서 Codex와 Claude 파일만 있던 저장소는 일반 갱신만으로 Cursor나 Gemini 파일이 새로 생기지 않습니다. 새 표면을 의도적으로 추가하려면 `project-librarian update --agents cursor` 또는 `project-librarian update --agents all`처럼 명시합니다. 목록에 없는 표면을 삭제하지는 않습니다.
149
+
146
150
  ## 실행 경로
147
151
 
148
152
  이 경로들은 주로 에이전트와 자동화를 위한 참조입니다. 설치 후 에이전트는 `npx`가 아니라 설치된 로컬 복사본을 `node`로 실행해야 합니다. 이렇게 하면 제한된 에이전트 환경에서 네트워크 접근과 버전이 고정되지 않은 패키지 실행을 피할 수 있습니다.
@@ -168,6 +172,7 @@ npx project-librarian install-skill --scope project --agents all
168
172
  | --- | --- | --- |
169
173
  | 위키 생성 또는 갱신 | "Project Librarian으로 이 저장소의 계획 위키를 설정하거나 갱신해줘." | `[init]` |
170
174
  | 마이그레이션 없이 기존 설정 갱신 | "위키를 마이그레이션하지 말고 이 저장소의 Project Librarian 설정을 갱신해줘." | `update` |
175
+ | 기존 설정에 특정 에이전트 표면 추가 | "위키 마이그레이션 없이 Cursor Project Librarian 표면을 추가해줘." | `update --agents cursor` |
171
176
  | 기존 문서/위키 마이그레이션 | "Project Librarian으로 기존 docs/wiki 내용을 마이그레이션해줘." | `--migrate` |
172
177
  | 생성된 설정 검증 | "Project Librarian 검증을 실행해줘." | `--lint` |
173
178
  | 링크와 문서 품질 점검 | "Project Librarian 진단을 실행해줘." | `--doctor` |
@@ -188,7 +193,7 @@ npx project-librarian install-skill --scope project --agents all
188
193
  | 증분 갱신 요구 | "Project Librarian 코드 근거 인덱스를 증분 갱신해줘." | `--code-index --incremental` |
189
194
  | 전체 재생성 강제 | "Project Librarian 코드 근거 인덱스를 전체 재생성해줘." | `--code-index --code-index-full` |
190
195
  | 선택적 Tree-sitter 백엔드 사용 | "Tree-sitter 파서로 Project Librarian 코드 근거를 만들어줘." | `--code-index --code-parser tree-sitter` |
191
- | 캐시 호환성 진단 | "Project Librarian 코드 근거 캐시 health를 확인해줘." | `--code-index-health` |
196
+ | 캐시 호환성 진단 | "Project Librarian 코드 근거 캐시 상태와 호환성을 진단해줘." | `--code-index-health` |
192
197
  | 캐시 상태 보기 | "Project Librarian 코드 근거 상태를 보여줘." | `--code-status` |
193
198
  | 인덱싱된 파일 목록 | "Project Librarian 코드 근거에 인덱싱된 파일을 보여줘." | `--code-files` |
194
199
  | 아키텍처/소유권 보고서 출력 | "Project Librarian 코드 보고서를 보여줘." | `--code-report` |
@@ -202,6 +207,8 @@ npx project-librarian install-skill --scope project --agents all
202
207
 
203
208
  ## 설치되는 파일
204
209
 
210
+ 새로 설정할 때는 `--agents`로 좁히지 않았고 프로젝트 범위 Project Librarian 스킬 설치도 없을 때 아래 지원 에이전트 표면을 설치합니다. 마이그레이션 없는 기존 설정 갱신은 기본적으로 감지된 표면만 보존해서 갱신하고, 공통 위키/git 훅 파일은 계속 갱신합니다.
211
+
205
212
  프로젝트 지침 파일:
206
213
 
207
214
  - `AGENTS.md`
@@ -229,6 +236,8 @@ Git 훅 파일:
229
236
  위키 디렉터리:
230
237
 
231
238
  - `wiki/canonical/`
239
+ - `wiki/roadmaps/`
240
+ - `wiki/plans/`
232
241
  - `wiki/decisions/`
233
242
  - `wiki/inbox/`
234
243
  - `wiki/meta/`
@@ -369,6 +378,9 @@ npm install
369
378
  npm run typecheck
370
379
  npm run build
371
380
  npm test
381
+ npm run test:coverage
382
+ npm run benchmark:llm:raw-audit
383
+ npm run benchmark:llm:delta-analysis
372
384
  npm run benchmark:claim-ledger
373
385
  npm run release:check
374
386
  npm pack --dry-run
@@ -376,19 +388,34 @@ npm pack --dry-run
376
388
 
377
389
  `src/` 아래 TypeScript를 수정할 때는 커밋 전에 빌드해 `dist/`를 최신 상태로 유지하세요.
378
390
 
379
- `npm run release:check`는 로컬 전용 관리자 게이트입니다. 테스트, 벤치마크 파서 smoke, 벤치마크 release preview, 벤치마크 claim ledger 분류, package dry-run 검사, dist 실행 가능 여부, README 벤치마크 claim 경계 문구를 확인합니다. publish하지 않고 measured Codex 벤치마크도 실행하지 않습니다.
391
+ `npm run test:coverage`는 Node 내장 test coverage에 보수적인 line, branch, function threshold를 적용하므로 coverage를 단순 보고서가 아니라 회귀 게이트로 사용합니다.
392
+
393
+ `npm run release:check`는 로컬 전용 관리자 게이트입니다. 테스트, Node 내장 coverage, 벤치마크 파서 smoke, real-corpus 오프라인 데모, 벤치마크 release preview, 벤치마크 claim ledger 분류, raw 보관 상태 감사, package dry-run 검사, dist 실행 가능 여부, README 벤치마크 claim 경계 문구를 확인합니다. publish하지 않고 raw 벤치마크 산출물을 삭제하지 않으며 measured Codex 벤치마크도 실행하지 않습니다.
394
+
395
+ `release:check` 통과는 런타임 보증이 아니라 재현 가능한 릴리스 준비 근거로 봐야 합니다. 현재 checkout에서 위 로컬 게이트를 통과했음을 증명하며, package dry run이 예상 publish 경계(`agents/`, `dist/`, `LICENSE`, `README.md`, `README.ko.md`, `SKILL.md`) 안에 머물고 소스 파일, 테스트, 저장소 로컬 위키/워크플로 상태, raw 벤치마크 출력, 로컬 캐시를 제외하는지도 확인합니다.
396
+
397
+ 배포는 GitHub Release가 published 상태가 된 뒤 `.github/workflows/publish.yml`에서 처리합니다. 이 워크플로는 GitHub OIDC 기반 npm trusted publishing(`id-token: write`)과 `npm publish --access public`을 사용하므로 npm provenance가 자동 생성됩니다. `NODE_AUTH_TOKEN`이나 npm token secret을 쓰면 안 되며, 릴리스 핵심 GitHub 공식 Actions는 전체 commit SHA로 고정합니다. `release:check`는 이 워크플로 계약도 로컬에서 검사합니다.
398
+
399
+ trusted publishing과 npm provenance는 패키지가 이 GitHub OIDC 워크플로를 통해 게시되었음을 증명합니다. 벤치마크 정확성, 최종 사용자 저장소의 코드 근거 freshness, 보안 감사를 증명하지는 않으며, 그런 항목은 별도의 근거 트랙으로 다룹니다.
380
400
 
381
401
  관리자 벤치마크 명령은 [benchmarks/README.md](benchmarks/README.md)에 있습니다. 이 명령은 릴리스 근거와 공개 주장 검증을 위한 것이며, 일반 사용자 설정 절차가 아닙니다.
382
402
 
383
- 코드 근거 런타임/스토리지 점검에는 `npm run perf:code-efficiency`를 사용합니다. 이 명령은 3k/10k/50k 픽스처를 생성하고 `benchmarks/reports/code-performance-efficiency/current.json`과 `.md`를 작성합니다. 명령 시간에는 CLI 시작과 freshness 확인이 포함되며, `query_groups` 섹션은 대표 file/symbol/route/import/edge 쿼리의 직접 DB 시간을 따로 보고합니다. 보고서에는 `mixed-monorepo`를 포함한 체크인 샘플 corpus도 합성 scale fixture와 분리해 포함됩니다.
403
+ 코드 근거 런타임/스토리지 점검에는 `npm run perf:code-efficiency`를 사용합니다. 이 명령은 3k/10k/50k 픽스처를 생성하고 `benchmarks/reports/code-performance-efficiency/current.json`과 `.md`를 작성합니다. 명령 시간에는 CLI 시작과 freshness 확인이 포함되며, `query_groups` 섹션은 대표 file/symbol/route/import/edge 쿼리의 직접 DB 시간을 따로 보고합니다. 보고서는 `mixed-monorepo`, `web-service`, `python-cli`, `docs-heavy` 체크인 corpus도 합성 scale fixture와 분리해 측정합니다.
384
404
 
385
- 무시된 오래된 LLM 벤치마크 raw 출력은 격리 Codex home을 삭제하기 전에 dry-run-first 헬퍼로 먼저 감사할 수 있습니다.
405
+ 측정형 LLM 벤치마크 실행은 1일보다 오래된 이전 raw run 디렉터리와 격리 Codex home을 자동 삭제하고, claimable 실행 실패 시에도 현재 실행의 home을 삭제한 뒤 종료합니다. raw JSONL, stderr, 보고서, manifest는 보존 기간 안의 실행에 대해서만 감사용으로 유지됩니다. 무시된 오래된 raw 출력은 격리 Codex home을 삭제하기 전에 dry-run-first 헬퍼로 여전히 먼저 감사할 수 있습니다.
386
406
 
387
407
  ```bash
408
+ npm run benchmark:llm:raw-audit -- --older-than-days 14
388
409
  npm run benchmark:llm:prune-raw -- --older-than-days 14
389
410
  npm run benchmark:llm:prune-raw -- --older-than-days 14 --execute
390
411
  ```
391
412
 
413
+ `npm run benchmark:llm:delta-analysis`는 체크인된 measured LLM 보고서를 읽고 Codex를 실행하지 않은 채 cost-weighted regression을 순위화합니다. 대표 raw JSONL command trace와 broad-search/router-read driver 분류까지 보려면 `-- --include-traces`를 붙입니다. 작은 scale aggregation처럼 약한 셀을 새 공개 claim보다 먼저 진단하는 첫 경로입니다.
414
+
415
+ 측정형 LLM 실행은 기본적으로 `--scenario-order run-major-balanced`를 사용합니다. 각 measured run index마다 선택된 모든 scenario를 실행하고 반복마다 순서를 뒤집어, 반복 실행에서 with/without 조건이 한쪽으로 몰리지 않게 합니다. 이전의 scenario별 묶음 실행 진단을 재현할 때만 `--scenario-order scenario-major`를 사용하세요.
416
+
417
+ `npm run typecheck:ts7`은 opt-in TypeScript 7 RC 호환성 probe입니다. `npx`를 사용하며, compiler API와 이 프로젝트 TypeScript extractor의 parity 기록이 생기기 전까지 `test`, `release:check`, CI 게이트 밖에 둡니다.
418
+
392
419
  ## 영감
393
420
 
394
421
  이 프로젝트는 Andrej Karpathy의 [LLM Wiki](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) 패턴에서 영감을 받았습니다. 긴 대화 기록에서 프로젝트 상태를 재구성하는 대신, 지속되는 markdown 컨텍스트를 작업 가까이에 둡니다.
package/README.md CHANGED
@@ -52,7 +52,7 @@ Project Librarian gives agents two local sources of truth:
52
52
  | Surface | What It Gives The Agent |
53
53
  | --- | --- |
54
54
  | `wiki/startup.md` + `wiki/index.md` | A compact session-start summary and router, so only the relevant planning pages are read. |
55
- | `wiki/canonical/` and `wiki/decisions/` | Current project facts, constraints, risks, package contracts, CLI behavior, and durable decisions. |
55
+ | `wiki/canonical/`, `wiki/roadmaps/`, `wiki/plans/`, and `wiki/decisions/` | Current truth stays in canonical pages, broad future work stays in roadmaps, detailed execution stays in plans, and durable rationale stays in decisions. |
56
56
  | `wiki/meta/document-taxonomy.md` | A service-lifecycle classification map that tells agents where PRD, policy, UX, data, engineering, QA, release, and operations truth should live. |
57
57
  | `.codex/`, `.claude/`, `.cursor/`, and `.gemini/` hooks | Automatic startup context for Codex, Claude Code, Cursor, and Gemini CLI without loading the full wiki. |
58
58
  | `GEMINI.md` and `.cursor/rules/` | Gemini CLI and Cursor instruction files that route agents to the same compact wiki-first contract. |
@@ -75,17 +75,19 @@ npm run benchmark:release:preview
75
75
  npm run benchmark:release -- --allow-codex-run
76
76
  ```
77
77
 
78
+ Measured release runs stream `[benchmark:progress]` lines to stderr for the scenario count, expected Codex exec total, current exec ordinal, phase, prompt id, exit status, elapsed time, and raw JSONL path. stdout stays reserved for the final JSON result.
79
+
78
80
  ### Wiki track (planning-doc routing)
79
81
 
80
82
  Cost-weighted tokens, Project Librarian vs control:
81
83
 
82
84
  | Scale | decision_lookup | aggregation | multi_session (2nd session) |
83
85
  | --- | --- | --- | --- |
84
- | Small | 43.8% less | 144.5% more | 5.4% more |
85
- | Medium | 53.4% less | 4.4% less | 68.5% less |
86
- | Large | 71.6% less* | 12.8% less | 66.0% less |
86
+ | Small | 14.4% less | 81.0% more | 22.0% less |
87
+ | Medium | 52.0% less | 19.0% less | 54.1% less |
88
+ | Large | 71.1% less | 29.0% less | 71.8% less |
87
89
 
88
- Latest synthetic wiki-track release candidate: 2026-06-16, `gpt-5.5`, 42 scenarios, 3 measured runs plus 1 warmup each. The overall claim gate **failed**: 41/42 scenarios passed correctness, but `decision_lookup` at large scale on the no-Project-Librarian control had only 2/3 correct measured runs. The failed control run selected `2026-05-04` from a dated history file instead of the expected latest benchmark-evidence decision `2026-06-10` from the decision log. Treat this table as diagnostic evidence, not a public release claim, until a clean release run passes the claim gate. Published boundaries remain visible: small `aggregation` is much more expensive with the wiki, small `multi_session` is slightly more expensive, and `aggregation` stays slower at every scale even when token cost drops.
90
+ Latest synthetic wiki-track release candidate: 2026-06-19, `gpt-5.5`, 42 scenarios, 3 measured runs plus 1 warmup each. The overall claim gate **passed**: 42/42 scenarios passed correctness, all 42 scenarios were claimable, and every corpus gate met the 3-run minimum. The release claim is still bounded to the synthetic wiki-routing track and the listed task families; it is not a claim about code-graph behavior, real repositories, every agent surface, or every question shape. Published boundaries remain visible: small `aggregation` still costs 81.0% more with the wiki, small `release_policy` costs 9.4% more in the full report, and `aggregation` stays slower at every scale even when token cost drops.
89
91
 
90
92
  ### Code-graph track (code evidence index, real repositories)
91
93
 
@@ -143,6 +145,8 @@ npx project-librarian install-skill --scope project --agents all
143
145
 
144
146
  `--agents` also accepts comma-separated values such as `codex,claude,cursor,gemini`. `all` targets every supported agent. `--scope` accepts `user` or `project`.
145
147
 
148
+ The project setup/update runner also accepts `--agents`. Fresh setup defaults to all supported agent surfaces only when no project-scoped Project Librarian skill install is present. If the repository already has project-scoped skills such as `.codex/skills/project-librarian/` and `.claude/skills/project-librarian/`, the first setup uses that installed agent set by default. Existing non-migration updates preserve the agent surfaces already present in the repository, so a repo that has only Codex and Claude files will not gain Cursor or Gemini files on a plain update. Use `project-librarian update --agents cursor` or `project-librarian update --agents all` when you intentionally want to add newly supported surfaces; unlisted surfaces are not deleted.
149
+
146
150
  ## Runner Paths
147
151
 
148
152
  These paths are mainly for agents and automation. After installation, agents should run the installed local copy with `node`, not `npx`. This avoids network access and unpinned package execution in restricted agent environments.
@@ -168,6 +172,7 @@ Wiki setup and maintenance:
168
172
  | --- | --- | --- |
169
173
  | Create or update the wiki | "Use Project Librarian to set up or update this repository's planning wiki." | `[init]` |
170
174
  | Update existing setup without migration | "Update this repository's Project Librarian setup without migrating the wiki." | `update` |
175
+ | Add a specific agent surface to an existing setup | "Add the Cursor Project Librarian surface without migrating the wiki." | `update --agents cursor` |
171
176
  | Migrate existing docs/wiki content | "Use Project Librarian to migrate the existing docs/wiki content." | `--migrate` |
172
177
  | Validate generated setup | "Run Project Librarian validation." | `--lint` |
173
178
  | Check links and document quality | "Run Project Librarian diagnostics." | `--doctor` |
@@ -188,6 +193,7 @@ Code evidence:
188
193
  | Require incremental update | "Update the Project Librarian code evidence index incrementally." | `--code-index --incremental` |
189
194
  | Force a full rebuild | "Fully rebuild the Project Librarian code evidence index." | `--code-index --code-index-full` |
190
195
  | Use optional Tree-sitter backend | "Build Project Librarian code evidence with the Tree-sitter parser." | `--code-index --code-parser tree-sitter` |
196
+ | Inspect cache compatibility | "Inspect Project Librarian code evidence cache health." | `--code-index-health` |
191
197
  | Show cache status | "Show Project Librarian code evidence status." | `--code-status` |
192
198
  | List indexed files | "List files in the Project Librarian code evidence index." | `--code-files` |
193
199
  | Print architecture and ownership report | "Show the Project Librarian code report." | `--code-report` |
@@ -201,6 +207,8 @@ Only one code evidence mode can run at a time. `--incremental`, `--code-index-fu
201
207
 
202
208
  ## What Gets Installed
203
209
 
210
+ Fresh setup installs the supported agent surfaces below unless you pass `--agents` or the repository already has project-scoped Project Librarian skills for a narrower agent set. Existing non-migration updates preserve the detected surface set by default and update only those selected surfaces plus the common wiki/git-hook files.
211
+
204
212
  Project instruction files:
205
213
 
206
214
  - `AGENTS.md`
@@ -228,6 +236,8 @@ Git hook files:
228
236
  Wiki directories:
229
237
 
230
238
  - `wiki/canonical/`
239
+ - `wiki/roadmaps/`
240
+ - `wiki/plans/`
231
241
  - `wiki/decisions/`
232
242
  - `wiki/inbox/`
233
243
  - `wiki/meta/`
@@ -368,6 +378,9 @@ npm install
368
378
  npm run typecheck
369
379
  npm run build
370
380
  npm test
381
+ npm run test:coverage
382
+ npm run benchmark:llm:raw-audit
383
+ npm run benchmark:llm:delta-analysis
371
384
  npm run benchmark:claim-ledger
372
385
  npm run release:check
373
386
  npm pack --dry-run
@@ -375,19 +388,34 @@ npm pack --dry-run
375
388
 
376
389
  When editing TypeScript under `src/`, rebuild before committing so `dist/` stays current.
377
390
 
378
- `npm run release:check` is a local-only maintainer gate: it runs tests, benchmark parser smoke, benchmark release preview, benchmark claim-ledger classification, package dry-run inspection, dist executable checks, and README benchmark-claim boundary checks. It never publishes and never launches a measured Codex benchmark.
391
+ `npm run test:coverage` uses Node's native test coverage with conservative line, branch, and function thresholds so coverage is a regression gate, not only a report.
392
+
393
+ `npm run release:check` is a local-only maintainer gate: it runs tests, native Node coverage, benchmark parser smoke, the real-corpus offline demo, benchmark release preview, benchmark claim-ledger classification, raw hygiene audit, package dry-run inspection, dist executable checks, and README benchmark-claim boundary checks. It never publishes, never deletes raw benchmark artifacts, and never launches a measured Codex benchmark.
394
+
395
+ Treat a green `release:check` as a reproducible release-readiness bundle, not a runtime guarantee: it proves those local gates on the current checkout, including that the package dry run stays inside the expected publish boundary (`agents/`, `dist/`, `LICENSE`, `README.md`, `README.ko.md`, and `SKILL.md`) and excludes source files, tests, repo-local wiki/workflow state, raw benchmark output, and local caches.
396
+
397
+ Publishing is handled by `.github/workflows/publish.yml` after a GitHub Release is published. The workflow uses npm trusted publishing through GitHub OIDC (`id-token: write`) and `npm publish --access public`, which generates npm provenance automatically; it must not use `NODE_AUTH_TOKEN` or npm token secrets, and release-critical first-party GitHub Actions are pinned to full commit SHAs. `release:check` verifies this workflow contract locally.
398
+
399
+ Trusted publishing and npm provenance prove the package was published through that GitHub OIDC workflow. They do not prove benchmark correctness, code-evidence freshness in an end-user repository, or a security audit; those remain separate evidence tracks.
379
400
 
380
401
  Maintainer benchmark commands live in [benchmarks/README.md](benchmarks/README.md). They are for release evidence and public claim validation, not normal end-user setup.
381
402
 
382
- For code-evidence runtime/storage checks, `npm run perf:code-efficiency` generates 3k/10k/50k fixtures and writes `benchmarks/reports/code-performance-efficiency/current.json` plus `.md`. Command timings include CLI startup and freshness checks; the `query_groups` section reports direct DB timings for representative file/symbol/route/import/edge queries. The report also includes checked-in sample corpora, including `mixed-monorepo`, separately from synthetic scale fixtures.
403
+ For code-evidence runtime/storage checks, `npm run perf:code-efficiency` generates 3k/10k/50k fixtures and writes `benchmarks/reports/code-performance-efficiency/current.json` plus `.md`. Command timings include CLI startup and freshness checks; the `query_groups` section reports direct DB timings for representative file/symbol/route/import/edge queries. The report also measures checked-in `mixed-monorepo`, `web-service`, `python-cli`, and `docs-heavy` corpora separately from synthetic scale fixtures.
383
404
 
384
- Old ignored LLM benchmark raw output can be audited with the dry-run-first helper before deleting retained isolated Codex homes:
405
+ Measured LLM benchmark runs automatically prune stale prior raw run directories and isolated Codex homes older than 1 day, then prune the current run's homes even on claimable-run failure; raw JSONL, stderr, reports, and manifests remain for runs inside the retention window. Old ignored raw output can still be audited with the dry-run-first helper before deleting retained isolated Codex homes:
385
406
 
386
407
  ```bash
408
+ npm run benchmark:llm:raw-audit -- --older-than-days 14
387
409
  npm run benchmark:llm:prune-raw -- --older-than-days 14
388
410
  npm run benchmark:llm:prune-raw -- --older-than-days 14 --execute
389
411
  ```
390
412
 
413
+ `npm run benchmark:llm:delta-analysis` reads the checked-in measured LLM report and ranks cost-weighted regressions without launching Codex. Add `-- --include-traces` to include representative raw JSONL command traces and classify broad-search/router-read drivers. It is the first diagnostic stop for weak cells such as small-scale aggregation before adding new benchmark claims.
414
+
415
+ Measured LLM runs default to `--scenario-order run-major-balanced`: each measured run index executes all selected scenarios, reversing the order on alternating repetitions so with/without pairs are not grouped by condition across repeated runs. Use `--scenario-order scenario-major` only when reproducing older scenario-grouped diagnostics.
416
+
417
+ `npm run typecheck:ts7` is an opt-in TypeScript 7 RC compatibility probe. It uses `npx` and is intentionally outside `test`, `release:check`, and CI gates until the compiler API and this project's TypeScript extractor have a measured parity record.
418
+
391
419
  ## Inspiration
392
420
 
393
421
  This project is inspired by Andrej Karpathy's [LLM Wiki](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) pattern: keep persistent markdown context close to the work instead of reconstructing project state from long chat history.
package/SKILL.md CHANGED
@@ -200,6 +200,7 @@ Execution contract:
200
200
  3. Separate evidence mapping from canonical truth:
201
201
  - Code structure, entrypoints, module relationships, execution flows, read-on-demand routes, and evidence paths belong under `wiki/meta/` with descriptive project-specific filenames chosen by the LLM.
202
202
  - Code-backed current project behavior, features, policies, constraints, terminology, domain rules, and operational facts belong under `wiki/canonical/`.
203
+ - Broad future work belongs under `wiki/roadmaps/`; detailed execution plans belong under `wiki/plans/`. After completion, update canonical truth and remove completed roadmap/plan content after rationale and evidence are preserved.
203
204
  - Important design rationale or tradeoffs inferred from code may belong under `wiki/decisions/` when they meet the decision policy.
204
205
  - Unclear, conflicting, or low-confidence interpretations belong in `wiki/inbox/` or a focused canonical questions page created for the topic, not directly in canonical truth.
205
206
  4. Do not use fixed canonical filenames. Choose or create files from topic boundaries, expected read frequency, and token budget.
@@ -228,6 +229,8 @@ It installs:
228
229
  - `wiki/startup.md` compact session-start context.
229
230
  - `wiki/index.md` router with read/update/token-budget hints.
230
231
  - `wiki/canonical/` directory for project-current-truth documents, created only when real content exists.
232
+ - `wiki/roadmaps/` for broad future scope and priority queues, created only when real content exists.
233
+ - `wiki/plans/` for detailed future execution plans, created only when real content exists.
231
234
  - Optional `wiki/canonical/glossary.md` project terminology contract when `--glossary-init` is used.
232
235
  - `wiki/decisions/` project-decision directory and lightweight decision ledgers.
233
236
  - `wiki/meta/` wiki operating rules, project decision policy, and wiki-operations Decision Pack.
@@ -247,7 +250,7 @@ Project canonical wiki content should not default to Korean or English. Choose t
247
250
 
248
251
  ## Boundary Rule
249
252
 
250
- `wiki/canonical/` and `wiki/decisions/` are for project planning only. Do not store wiki operating decisions, hook/bootstrap/lint/migration details, LLM collaboration preferences, assistant reminders, or non-project workflow memory there.
253
+ `wiki/canonical/`, `wiki/roadmaps/`, `wiki/plans/`, and `wiki/decisions/` are for project planning only. Do not store wiki operating decisions, hook/bootstrap/lint/migration details, LLM collaboration preferences, assistant reminders, or non-project workflow memory there.
251
254
 
252
255
  Use:
253
256
 
@@ -255,6 +258,8 @@ Use:
255
258
  - Root `AGENTS.md`, hooks, or skills for durable project-wide LLM instructions and collaboration memory.
256
259
  - `wiki/AGENTS.md` for wiki-internal editing rules that should apply only under `wiki/`.
257
260
  - `wiki/canonical/` only for current project truth.
261
+ - `wiki/roadmaps/` only for broad future scope, priority queues, and milestone sequences.
262
+ - `wiki/plans/` only for detailed future execution plans.
258
263
  - `wiki/decisions/` only for project decision history.
259
264
 
260
265
  Every wiki markdown file should include a compact metadata header with `status`, `updated`, `scope`, `read_budget`, `decision_ref`, and `review_trigger`.
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.agentSurfaceRequiredFiles = exports.allAgentSurfaces = void 0;
4
+ exports.parseAgentSurfaceValues = parseAgentSurfaceValues;
5
+ exports.hasProjectLibrarianInstall = hasProjectLibrarianInstall;
6
+ exports.activeAgentSurfaces = activeAgentSurfaces;
7
+ exports.resolveBootstrapAgentSurfaces = resolveBootstrapAgentSurfaces;
8
+ exports.includesAgentSurface = includesAgentSurface;
9
+ exports.allAgentSurfaces = ["codex", "claude", "cursor", "gemini"];
10
+ exports.agentSurfaceRequiredFiles = {
11
+ codex: [".codex/hooks/wiki-session-start.js", ".codex/hooks.json"],
12
+ claude: ["CLAUDE.md", ".claude/hooks/wiki-session-start.js", ".claude/settings.json"],
13
+ cursor: [".cursor/rules/project-librarian.mdc", ".cursor/hooks/wiki-session-start.js", ".cursor/hooks.json"],
14
+ gemini: ["GEMINI.md", ".gemini/hooks/wiki-session-start.js", ".gemini/settings.json"],
15
+ };
16
+ const agentSurfaceProjectSkillFiles = {
17
+ codex: [".codex/skills/project-librarian/SKILL.md"],
18
+ claude: [".claude/skills/project-librarian/SKILL.md"],
19
+ cursor: [".cursor/skills/project-librarian/SKILL.md"],
20
+ gemini: [".gemini/skills/project-librarian/SKILL.md"],
21
+ };
22
+ const projectLibrarianCommonInstallFiles = [
23
+ "wiki/startup.md",
24
+ "wiki/index.md",
25
+ "wiki/AGENTS.md",
26
+ ];
27
+ function parseAgentSurfaceValues(values) {
28
+ const surfaces = new Set();
29
+ const invalid = [];
30
+ for (const value of values) {
31
+ if (value === "all") {
32
+ for (const surface of exports.allAgentSurfaces)
33
+ surfaces.add(surface);
34
+ }
35
+ else if (exports.allAgentSurfaces.includes(value)) {
36
+ surfaces.add(value);
37
+ }
38
+ else {
39
+ invalid.push(value);
40
+ }
41
+ }
42
+ return { surfaces: Array.from(surfaces), invalid };
43
+ }
44
+ function hasProjectLibrarianInstall(fileExists, readFile) {
45
+ if (projectLibrarianCommonInstallFiles.some((file) => fileExists(file)))
46
+ return true;
47
+ if (exports.allAgentSurfaces.some((surface) => agentSurfaceProjectSkillFiles[surface].some((file) => fileExists(file))))
48
+ return true;
49
+ if (fileExists("AGENTS.md") && readFile) {
50
+ return readFile("AGENTS.md").includes("PROJECT-WIKI-FIRST:START");
51
+ }
52
+ return false;
53
+ }
54
+ function activeAgentSurfaces(fileExists) {
55
+ return exports.allAgentSurfaces.filter((surface) => (exports.agentSurfaceRequiredFiles[surface].some((file) => fileExists(file))
56
+ || agentSurfaceProjectSkillFiles[surface].some((file) => fileExists(file))));
57
+ }
58
+ function resolveBootstrapAgentSurfaces(explicitSurfaces, fileExists, readFile) {
59
+ if (explicitSurfaces.length > 0)
60
+ return Array.from(explicitSurfaces);
61
+ if (hasProjectLibrarianInstall(fileExists, readFile))
62
+ return activeAgentSurfaces(fileExists);
63
+ return Array.from(exports.allAgentSurfaces);
64
+ }
65
+ function includesAgentSurface(surfaces, surface) {
66
+ return surfaces.includes(surface);
67
+ }
package/dist/args.js CHANGED
@@ -1,80 +1,74 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.codeSearchSymbol = exports.codeReportSection = exports.codeQuerySql = exports.codeImpactTarget = exports.codeContextPackTarget = exports.wikiVisualizeOutput = exports.wikiVisualizeMode = exports.wikiImpactTarget = exports.wikiImpactMode = exports.queryTerm = exports.codeSearchSymbolMode = exports.codeQueryMode = exports.codeImpactMode = exports.codeParserMode = exports.codeContextPackMode = exports.codeFilesMode = exports.codeStatusMode = exports.codeReportMode = exports.codeIndexHealthMode = exports.codeIndexFullMode = exports.codeIndexIncrementalMode = exports.codeIndexMode = exports.acknowledgeSmallRepoMode = 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
- exports.issueDraftTitle = exports.issueBodyFile = exports.captureCategory = exports.captureContent = exports.captureTitle = exports.codeIndexScopes = exports.codeParser = exports.codeIndexOutput = void 0;
3
+ exports.codeQuerySql = exports.codeImpactTarget = exports.codeContextPackTarget = exports.wikiVisualizeOutput = exports.wikiVisualizeMode = exports.wikiImpactTarget = exports.wikiImpactMode = exports.queryTerm = exports.codeSearchSymbolMode = exports.codeQueryMode = exports.codeImpactMode = exports.codeParserMode = exports.codeContextPackMode = exports.codeFilesMode = exports.codeStatusMode = exports.codeReportMode = exports.codeIndexHealthMode = exports.codeIndexFullMode = exports.codeIndexIncrementalMode = exports.codeIndexMode = exports.acknowledgeSmallRepoMode = 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.invalidAgentTargets = exports.missingValueOptions = exports.unexpectedValueOptions = exports.unknownOptions = exports.args = exports.commandArgs = exports.command = exports.unknownCommand = exports.helpMode = exports.agentTargets = exports.parsedArgs = exports.rawArgs = void 0;
4
+ exports.issueDraftTitle = exports.issueBodyFile = exports.captureCategory = exports.captureContent = exports.captureTitle = exports.codeIndexScopes = exports.codeParser = exports.codeIndexOutput = exports.codeSearchSymbol = exports.codeReportSection = void 0;
5
5
  exports.parseArgs = parseArgs;
6
6
  exports.argValue = argValue;
7
7
  exports.argValues = argValues;
8
+ const agent_surfaces_1 = require("./agent-surfaces");
8
9
  exports.rawArgs = process.argv.slice(2);
9
10
  const knownCommands = new Set(["init", "update", "install-skill", "mcp"]);
10
- const flagsWithoutValues = new Set([
11
- "--acknowledge-small-repo",
12
- "--adopt-existing",
13
- "--capture-inbox",
14
- "--code-evidence-files",
15
- "--code-evidence-index",
16
- "--code-evidence-status",
17
- "--code-files",
18
- "--code-incremental",
19
- "--code-index",
20
- "--code-index-full",
21
- "--code-index-health",
22
- "--code-index-incremental",
23
- "--code-evidence-index-full",
24
- "--code-evidence-index-incremental",
25
- "--code-report",
26
- "--code-status",
27
- "--code-evidence-report",
28
- "--dry-run",
29
- "--glossary-init",
30
- "--doctor",
31
- "--fix",
32
- "--issue-create",
33
- "--issue-draft",
34
- "--incremental",
35
- "--link-check",
36
- "--lint",
37
- "--migrate",
38
- "--migration-doctor",
39
- "--migration-lint",
40
- "--migration-quality-check",
41
- "--no-git-config",
42
- "--prune-check",
43
- "--quality-check",
44
- "--refresh-index",
45
- "--review-migration",
46
- "--semantic-migrate",
47
- "--wiki-graph-html",
48
- "--wiki-visualize",
49
- ]);
50
- const flagsWithValues = new Set([
51
- "--agents",
52
- "--category",
53
- "--code-evidence-context-pack",
54
- "--code-evidence-impact",
55
- "--code-context-pack",
56
- "--code-evidence-out",
57
- "--code-evidence-parser",
58
- "--code-evidence-query",
59
- "--code-evidence-report-section",
60
- "--code-evidence-scope",
61
- "--code-evidence-symbol",
62
- "--code-impact",
63
- "--code-index-out",
64
- "--code-parser",
65
- "--code-query",
66
- "--code-report-section",
67
- "--code-scope",
68
- "--code-search-symbol",
69
- "--content",
70
- "--issue-body-file",
71
- "--issue-title",
72
- "--query",
73
- "--scope",
74
- "--title",
75
- "--wiki-impact",
76
- "--wiki-visualize-out",
77
- ]);
11
+ const flagDefinitions = [
12
+ { name: "--acknowledge-small-repo", value: "none" },
13
+ { name: "--adopt-existing", value: "none" },
14
+ { name: "--agents", value: "value" },
15
+ { name: "--capture-inbox", value: "none" },
16
+ { name: "--category", value: "value" },
17
+ { name: "--code-context-pack", value: "value", aliases: ["--code-evidence-context-pack"] },
18
+ { name: "--code-files", value: "none", aliases: ["--code-evidence-files"] },
19
+ { name: "--code-impact", value: "value", aliases: ["--code-evidence-impact"] },
20
+ { name: "--code-index", value: "none", aliases: ["--code-evidence-index"] },
21
+ { name: "--code-index-full", value: "none", aliases: ["--code-evidence-index-full"] },
22
+ { name: "--code-index-health", value: "none" },
23
+ { name: "--code-index-incremental", value: "none", aliases: ["--incremental", "--code-incremental", "--code-evidence-index-incremental"] },
24
+ { name: "--code-index-out", value: "value", aliases: ["--code-evidence-out"] },
25
+ { name: "--code-parser", value: "value", aliases: ["--code-evidence-parser"] },
26
+ { name: "--code-query", value: "value", aliases: ["--code-evidence-query"] },
27
+ { name: "--code-report", value: "none", aliases: ["--code-evidence-report"] },
28
+ { name: "--code-report-section", value: "value", aliases: ["--code-evidence-report-section"] },
29
+ { name: "--code-scope", value: "value", aliases: ["--code-evidence-scope"] },
30
+ { name: "--code-search-symbol", value: "value", aliases: ["--code-evidence-symbol"] },
31
+ { name: "--code-status", value: "none", aliases: ["--code-evidence-status"] },
32
+ { name: "--content", value: "value" },
33
+ { name: "--doctor", value: "none" },
34
+ { name: "--dry-run", value: "none" },
35
+ { name: "--fix", value: "none" },
36
+ { name: "--glossary-init", value: "none" },
37
+ { name: "--issue-body-file", value: "value" },
38
+ { name: "--issue-create", value: "none" },
39
+ { name: "--issue-draft", value: "none" },
40
+ { name: "--issue-title", value: "value" },
41
+ { name: "--link-check", value: "none" },
42
+ { name: "--lint", value: "none" },
43
+ { name: "--migrate", value: "none" },
44
+ { name: "--migration-doctor", value: "none" },
45
+ { name: "--migration-lint", value: "none" },
46
+ { name: "--migration-quality-check", value: "none" },
47
+ { name: "--no-git-config", value: "none" },
48
+ { name: "--prune-check", value: "none" },
49
+ { name: "--quality-check", value: "none" },
50
+ { name: "--query", value: "value" },
51
+ { name: "--refresh-index", value: "none" },
52
+ { name: "--review-migration", value: "none", aliases: ["--semantic-migrate"] },
53
+ { name: "--scope", value: "value" },
54
+ { name: "--title", value: "value" },
55
+ { name: "--wiki-graph-html", value: "none" },
56
+ { name: "--wiki-impact", value: "value" },
57
+ { name: "--wiki-visualize", value: "none" },
58
+ { name: "--wiki-visualize-out", value: "value" },
59
+ ];
60
+ function definitionNames(definition) {
61
+ return [definition.name, ...(definition.aliases ?? [])];
62
+ }
63
+ function flagNamesByPolicy(value) {
64
+ return flagDefinitions.filter((definition) => definition.value === value).flatMap(definitionNames);
65
+ }
66
+ function namesForFlag(name) {
67
+ const definition = flagDefinitions.find((candidate) => definitionNames(candidate).includes(name));
68
+ return definition ? definitionNames(definition) : [name];
69
+ }
70
+ const flagsWithoutValues = new Set(flagNamesByPolicy("none"));
71
+ const flagsWithValues = new Set(flagNamesByPolicy("value"));
78
72
  const knownFlags = new Set([...flagsWithoutValues, ...flagsWithValues, "--help", "-h"]);
79
73
  function flagName(arg) {
80
74
  return arg.startsWith("--") ? arg.split("=", 1)[0] ?? arg : arg;
@@ -135,37 +129,42 @@ function parseArgs(argv) {
135
129
  const hasFlag = (name) => hasFlagIn(commandArgs, name);
136
130
  const argValue = (name) => argValueFrom(commandArgs, name);
137
131
  const argValues = (name) => argValuesFrom(commandArgs, name);
138
- const codeImpactTarget = argValue("--code-impact") || argValue("--code-evidence-impact");
139
- const codeContextPackTarget = argValue("--code-context-pack") || argValue("--code-evidence-context-pack");
140
- const codeQuerySql = argValue("--code-query") || argValue("--code-evidence-query");
141
- const codeSearchSymbol = argValue("--code-search-symbol") || argValue("--code-evidence-symbol");
132
+ const hasAnyFlag = (name) => namesForFlag(name).some(hasFlag);
133
+ const argValueFromAny = (name) => namesForFlag(name).map(argValue).find(Boolean) ?? "";
134
+ const argValuesFromAny = (name) => namesForFlag(name).flatMap(argValues);
135
+ const codeImpactTarget = argValueFromAny("--code-impact");
136
+ const codeContextPackTarget = argValueFromAny("--code-context-pack");
137
+ const codeQuerySql = argValueFromAny("--code-query");
138
+ const codeSearchSymbol = argValueFromAny("--code-search-symbol");
139
+ const parsedAgentTargets = (0, agent_surfaces_1.parseAgentSurfaceValues)(argValues("--agents"));
142
140
  return {
143
141
  acknowledgeSmallRepoMode: args.has("--acknowledge-small-repo"),
142
+ agentTargets: parsedAgentTargets.surfaces,
144
143
  args,
145
144
  captureCategory: argValue("--category") || "project-candidate",
146
145
  captureContent: argValue("--content"),
147
146
  captureInboxMode: args.has("--capture-inbox"),
148
147
  captureTitle: argValue("--title"),
149
- codeContextPackMode: hasFlag("--code-context-pack") || hasFlag("--code-evidence-context-pack"),
148
+ codeContextPackMode: hasAnyFlag("--code-context-pack"),
150
149
  codeContextPackTarget,
151
- codeFilesMode: args.has("--code-files") || args.has("--code-evidence-files"),
152
- codeImpactMode: hasFlag("--code-impact") || hasFlag("--code-evidence-impact"),
150
+ codeFilesMode: hasAnyFlag("--code-files"),
151
+ codeImpactMode: hasAnyFlag("--code-impact"),
153
152
  codeImpactTarget,
154
- codeIndexFullMode: args.has("--code-index-full") || args.has("--code-evidence-index-full"),
153
+ codeIndexFullMode: hasAnyFlag("--code-index-full"),
155
154
  codeIndexHealthMode: args.has("--code-index-health"),
156
- codeIndexIncrementalMode: args.has("--incremental") || args.has("--code-incremental") || args.has("--code-index-incremental") || args.has("--code-evidence-index-incremental"),
157
- codeIndexMode: args.has("--code-index") || args.has("--code-evidence-index"),
158
- codeIndexOutput: argValue("--code-index-out") || argValue("--code-evidence-out") || ".project-wiki/code-evidence.sqlite",
159
- codeIndexScopes: [...argValues("--code-scope"), ...argValues("--code-evidence-scope")],
160
- codeParser: argValue("--code-parser") || argValue("--code-evidence-parser") || "default",
161
- codeParserMode: hasFlag("--code-parser") || hasFlag("--code-evidence-parser"),
162
- codeQueryMode: hasFlag("--code-query") || hasFlag("--code-evidence-query"),
155
+ codeIndexIncrementalMode: hasAnyFlag("--code-index-incremental"),
156
+ codeIndexMode: hasAnyFlag("--code-index"),
157
+ codeIndexOutput: argValueFromAny("--code-index-out") || ".project-wiki/code-evidence.sqlite",
158
+ codeIndexScopes: argValuesFromAny("--code-scope"),
159
+ codeParser: argValueFromAny("--code-parser") || "default",
160
+ codeParserMode: hasAnyFlag("--code-parser"),
161
+ codeQueryMode: hasAnyFlag("--code-query"),
163
162
  codeQuerySql,
164
- codeReportMode: args.has("--code-report") || args.has("--code-evidence-report"),
165
- codeReportSection: argValue("--code-report-section") || argValue("--code-evidence-report-section"),
163
+ codeReportMode: hasAnyFlag("--code-report"),
164
+ codeReportSection: argValueFromAny("--code-report-section"),
166
165
  codeSearchSymbol,
167
- codeSearchSymbolMode: hasFlag("--code-search-symbol") || hasFlag("--code-evidence-symbol"),
168
- codeStatusMode: args.has("--code-status") || args.has("--code-evidence-status"),
166
+ codeSearchSymbolMode: hasAnyFlag("--code-search-symbol"),
167
+ codeStatusMode: hasAnyFlag("--code-status"),
169
168
  command,
170
169
  commandArgs,
171
170
  doctorMode: args.has("--doctor"),
@@ -176,6 +175,7 @@ function parseArgs(argv) {
176
175
  issueCreateMode: args.has("--issue-create"),
177
176
  issueDraftMode: args.has("--issue-draft"),
178
177
  issueDraftTitle: argValue("--issue-title"),
178
+ invalidAgentTargets: parsedAgentTargets.invalid,
179
179
  linkCheckMode: args.has("--link-check"),
180
180
  lintMode: args.has("--lint"),
181
181
  migrationDoctorMode: args.has("--migration-doctor"),
@@ -189,7 +189,7 @@ function parseArgs(argv) {
189
189
  queryTerm: argValue("--query"),
190
190
  rawArgs: argv,
191
191
  refreshIndexMode: args.has("--refresh-index"),
192
- reviewMigrationMode: args.has("--review-migration") || args.has("--semantic-migrate"),
192
+ reviewMigrationMode: hasAnyFlag("--review-migration"),
193
193
  unexpectedValueOptions: Array.from(new Set(commandArgs
194
194
  .filter((arg) => arg.startsWith("--") && arg.includes("="))
195
195
  .map(flagName)
@@ -206,6 +206,7 @@ function parseArgs(argv) {
206
206
  };
207
207
  }
208
208
  exports.parsedArgs = parseArgs(exports.rawArgs);
209
+ exports.agentTargets = exports.parsedArgs.agentTargets;
209
210
  exports.helpMode = exports.parsedArgs.helpMode;
210
211
  exports.unknownCommand = exports.parsedArgs.unknownCommand;
211
212
  exports.command = exports.parsedArgs.command;
@@ -214,6 +215,7 @@ exports.args = exports.parsedArgs.args;
214
215
  exports.unknownOptions = exports.parsedArgs.unknownOptions;
215
216
  exports.unexpectedValueOptions = exports.parsedArgs.unexpectedValueOptions;
216
217
  exports.missingValueOptions = exports.parsedArgs.missingValueOptions;
218
+ exports.invalidAgentTargets = exports.parsedArgs.invalidAgentTargets;
217
219
  exports.migrateMode = exports.parsedArgs.migrateMode;
218
220
  exports.lintMode = exports.parsedArgs.lintMode;
219
221
  exports.migrationDoctorMode = exports.parsedArgs.migrationDoctorMode;
@@ -60,7 +60,13 @@ function printJson(value) {
60
60
  function requireCompatibleDatabase(database, runtime) {
61
61
  const schemaVersion = (0, schema_1.readMetaValue)(database, "schema_version");
62
62
  if (schemaVersion !== schema_1.codeIndexSchemaVersion) {
63
- runtime.fail(`code evidence index schema version ${schemaVersion || "(missing)"} is incompatible with ${schema_1.codeIndexSchemaVersion}; rebuild with --code-index`);
63
+ const databasePath = runtime.codeEvidenceDatabasePath();
64
+ runtime.fail([
65
+ `code evidence index schema version ${schemaVersion || "(missing)"} is incompatible with ${schema_1.codeIndexSchemaVersion}`,
66
+ `inspect: project-librarian --code-index-health`,
67
+ `rebuild: project-librarian --code-index --code-index-full`,
68
+ `database: ${databasePath.relativePath}`,
69
+ ].join("\n"));
64
70
  }
65
71
  }
66
72
  function runCodeIndexMode(runtime) {
@@ -2,6 +2,7 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const args_1 = require("./args");
5
+ const agent_surfaces_1 = require("./agent-surfaces");
5
6
  const hooks_1 = require("./hooks");
6
7
  const install_skill_1 = require("./install-skill");
7
8
  const modes_1 = require("./modes");
@@ -39,6 +40,7 @@ Options:
39
40
  --refresh-index Update the managed auto-discovered wiki index block.
40
41
  --capture-inbox Append a candidate note with --title, --content, and optional --category.
41
42
  --glossary-init Create and route the optional glossary page.
43
+ --agents <list> With init/update, write only selected agent surfaces: codex, claude, cursor, gemini, or all. Existing project skill/setup surfaces are preserved by default.
42
44
  --prune-check Report active pages with stale or unresolved signals.
43
45
  --review-migration Sync unit coverage and compatible inbox statuses into migration review files.
44
46
  --no-git-config Install hook files without changing git core.hooksPath.
@@ -107,6 +109,11 @@ if (args_1.missingValueOptions.length > 0) {
107
109
  printUsage();
108
110
  process.exit(1);
109
111
  }
112
+ if (args_1.invalidAgentTargets.length > 0) {
113
+ console.error(`invalid --agents entr${args_1.invalidAgentTargets.length === 1 ? "y" : "ies"}: ${args_1.invalidAgentTargets.join(", ")}; expected codex, claude, cursor, gemini, or all`);
114
+ printUsage();
115
+ process.exit(1);
116
+ }
110
117
  if (args_1.command === "update" && args_1.migrateMode) {
111
118
  console.error("update cannot be combined with --migrate or --adopt-existing; use project-librarian --migrate for migration.");
112
119
  process.exit(1);
@@ -247,6 +254,16 @@ function runInitCommand() {
247
254
  runRefreshIndexOnlyMode();
248
255
  process.exit(0);
249
256
  }
257
+ const selectedAgentSurfaces = args_1.agentTargets.length > 0
258
+ ? args_1.agentTargets
259
+ : args_1.migrateMode
260
+ ? Array.from(agent_surfaces_1.allAgentSurfaces)
261
+ : (0, agent_surfaces_1.resolveBootstrapAgentSurfaces)(args_1.agentTargets, workspace_1.exists, workspace_1.read);
262
+ const shouldWriteSurface = (surface) => (0, agent_surfaces_1.includesAgentSurface)(selectedAgentSurfaces, surface);
263
+ const writeCodexSurface = shouldWriteSurface("codex");
264
+ const writeClaudeSurface = shouldWriteSurface("claude");
265
+ const writeCursorSurface = shouldWriteSurface("cursor");
266
+ const writeGeminiSurface = shouldWriteSurface("gemini");
250
267
  const migrationState = args_1.migrateMode ? (0, migration_1.prepareMigrationMode)() : null;
251
268
  const results = [];
252
269
  if (migrationState)
@@ -256,11 +273,16 @@ function runInitCommand() {
256
273
  (0, workspace_1.mkdirp)("wiki/inbox");
257
274
  (0, workspace_1.mkdirp)("wiki/meta");
258
275
  (0, workspace_1.mkdirp)("wiki/sources");
259
- (0, workspace_1.mkdirp)(".codex/hooks");
260
- (0, workspace_1.mkdirp)(".claude/hooks");
261
- (0, workspace_1.mkdirp)(".cursor/hooks");
262
- (0, workspace_1.mkdirp)(".cursor/rules");
263
- (0, workspace_1.mkdirp)(".gemini/hooks");
276
+ if (writeCodexSurface)
277
+ (0, workspace_1.mkdirp)(".codex/hooks");
278
+ if (writeClaudeSurface)
279
+ (0, workspace_1.mkdirp)(".claude/hooks");
280
+ if (writeCursorSurface) {
281
+ (0, workspace_1.mkdirp)(".cursor/hooks");
282
+ (0, workspace_1.mkdirp)(".cursor/rules");
283
+ }
284
+ if (writeGeminiSurface)
285
+ (0, workspace_1.mkdirp)(".gemini/hooks");
264
286
  (0, workspace_1.mkdirp)(".githooks");
265
287
  // B1 fallback: sync the CURRENT startup.md TL;DR into the managed AGENTS.md block
266
288
  // so non-interactive `codex exec` (which does not run SessionStart hooks) still
@@ -271,23 +293,34 @@ function runInitCommand() {
271
293
  const startupForSync = (0, workspace_1.exists)("wiki/startup.md") ? (0, workspace_1.read)("wiki/startup.md") : templates_1.startup;
272
294
  const startupTldrForAgents = (0, templates_1.extractStartupTldr)(startupForSync);
273
295
  results.push(["AGENTS.md", (0, workspace_1.upsertMarkedSection)("AGENTS.md", "<!-- PROJECT-WIKI-FIRST:START -->", "<!-- PROJECT-WIKI-FIRST:END -->", (0, templates_1.agentsSection)(startupTldrForAgents))]);
274
- results.push(["CLAUDE.md", (0, workspace_1.upsertMarkedSection)("CLAUDE.md", "<!-- PROJECT-WIKI-CLAUDE:START -->", "<!-- PROJECT-WIKI-CLAUDE:END -->", templates_1.claudeSection)]);
275
- results.push(["GEMINI.md", (0, workspace_1.upsertMarkedSection)("GEMINI.md", "<!-- PROJECT-WIKI-GEMINI:START -->", "<!-- PROJECT-WIKI-GEMINI:END -->", templates_1.geminiSection)]);
276
- results.push([".cursor/rules/project-librarian.mdc", (0, workspace_1.writeManaged)(".cursor/rules/project-librarian.mdc", templates_1.cursorRule)]);
296
+ if (writeClaudeSurface)
297
+ results.push(["CLAUDE.md", (0, workspace_1.upsertMarkedSection)("CLAUDE.md", "<!-- PROJECT-WIKI-CLAUDE:START -->", "<!-- PROJECT-WIKI-CLAUDE:END -->", templates_1.claudeSection)]);
298
+ if (writeGeminiSurface)
299
+ results.push(["GEMINI.md", (0, workspace_1.upsertMarkedSection)("GEMINI.md", "<!-- PROJECT-WIKI-GEMINI:START -->", "<!-- PROJECT-WIKI-GEMINI:END -->", templates_1.geminiSection)]);
300
+ if (writeCursorSurface)
301
+ results.push([".cursor/rules/project-librarian.mdc", (0, workspace_1.writeManaged)(".cursor/rules/project-librarian.mdc", templates_1.cursorRule)]);
277
302
  results.push(["wiki/AGENTS.md", (0, workspace_1.upsertMarkedSection)("wiki/AGENTS.md", "<!-- PROJECT-WIKI-INTERNAL:START -->", "<!-- PROJECT-WIKI-INTERNAL:END -->", templates_1.wikiAgentsSection)]);
278
303
  results.push([".githooks/prepare-commit-msg", (0, workspace_1.writeManaged)(".githooks/prepare-commit-msg", hooks_1.gitPrepareCommitMsgHook)]);
279
304
  (0, workspace_1.makeExecutable)(".githooks/prepare-commit-msg");
280
305
  results.push([".githooks/wiki-commit-trailers.js", (0, workspace_1.writeManaged)(".githooks/wiki-commit-trailers.js", hooks_1.gitWikiCommitTrailersScript)]);
281
306
  (0, workspace_1.makeExecutable)(".githooks/wiki-commit-trailers.js");
282
307
  results.push(["git core.hooksPath", (0, hooks_1.upsertGitHooksPath)()]);
283
- results.push([".codex/hooks.json", (0, hooks_1.upsertHookConfig)()]);
284
- results.push([".codex/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".codex/hooks/wiki-session-start.js", hooks_1.hookScript)]);
285
- results.push([".claude/settings.json", (0, hooks_1.upsertClaudeHookConfig)()]);
286
- results.push([".claude/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".claude/hooks/wiki-session-start.js", hooks_1.hookScript)]);
287
- results.push([".cursor/hooks.json", (0, hooks_1.upsertCursorHookConfig)()]);
288
- results.push([".cursor/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".cursor/hooks/wiki-session-start.js", hooks_1.cursorHookScript)]);
289
- results.push([".gemini/settings.json", (0, hooks_1.upsertGeminiHookConfig)()]);
290
- results.push([".gemini/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".gemini/hooks/wiki-session-start.js", hooks_1.hookScript)]);
308
+ if (writeCodexSurface) {
309
+ results.push([".codex/hooks.json", (0, hooks_1.upsertHookConfig)()]);
310
+ results.push([".codex/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".codex/hooks/wiki-session-start.js", hooks_1.hookScript)]);
311
+ }
312
+ if (writeClaudeSurface) {
313
+ results.push([".claude/settings.json", (0, hooks_1.upsertClaudeHookConfig)()]);
314
+ results.push([".claude/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".claude/hooks/wiki-session-start.js", hooks_1.hookScript)]);
315
+ }
316
+ if (writeCursorSurface) {
317
+ results.push([".cursor/hooks.json", (0, hooks_1.upsertCursorHookConfig)()]);
318
+ results.push([".cursor/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".cursor/hooks/wiki-session-start.js", hooks_1.cursorHookScript)]);
319
+ }
320
+ if (writeGeminiSurface) {
321
+ results.push([".gemini/settings.json", (0, hooks_1.upsertGeminiHookConfig)()]);
322
+ results.push([".gemini/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".gemini/hooks/wiki-session-start.js", hooks_1.hookScript)]);
323
+ }
291
324
  // Bootstrap-managed MCP registration (preservation-first, idempotent). Claude
292
325
  // Code reads `.mcp.json`, Cursor reads `.cursor/mcp.json`, and Gemini reads
293
326
  // `mcpServers` inside `.gemini/settings.json`. Codex only supports user-level MCP
@@ -296,16 +329,24 @@ function runInitCommand() {
296
329
  // Registration is scale-gated (2026-06-12 decision): below the measured
297
330
  // file-count threshold with no existing .project-wiki index, the rows report the
298
331
  // skip reason instead of writing config; an existing index registers regardless.
299
- const mcpGate = (0, hooks_1.mcpRegistrationGate)();
300
- if (mcpGate.register) {
301
- results.push([".mcp.json", (0, hooks_1.upsertClaudeMcpConfig)()]);
302
- results.push([".cursor/mcp.json", (0, hooks_1.upsertCursorMcpConfig)()]);
303
- results.push([".gemini/settings.json mcpServers", (0, hooks_1.upsertGeminiMcpConfig)()]);
304
- }
305
- else {
306
- results.push([".mcp.json", mcpGate.reason]);
307
- results.push([".cursor/mcp.json", mcpGate.reason]);
308
- results.push([".gemini/settings.json mcpServers", mcpGate.reason]);
332
+ if (writeClaudeSurface || writeCursorSurface || writeGeminiSurface) {
333
+ const mcpGate = (0, hooks_1.mcpRegistrationGate)();
334
+ if (mcpGate.register) {
335
+ if (writeClaudeSurface)
336
+ results.push([".mcp.json", (0, hooks_1.upsertClaudeMcpConfig)()]);
337
+ if (writeCursorSurface)
338
+ results.push([".cursor/mcp.json", (0, hooks_1.upsertCursorMcpConfig)()]);
339
+ if (writeGeminiSurface)
340
+ results.push([".gemini/settings.json mcpServers", (0, hooks_1.upsertGeminiMcpConfig)()]);
341
+ }
342
+ else {
343
+ if (writeClaudeSurface)
344
+ results.push([".mcp.json", mcpGate.reason]);
345
+ if (writeCursorSurface)
346
+ results.push([".cursor/mcp.json", mcpGate.reason]);
347
+ if (writeGeminiSurface)
348
+ results.push([".gemini/settings.json mcpServers", mcpGate.reason]);
349
+ }
309
350
  }
310
351
  // Routers accumulate user-maintained project state after bootstrap, so they are
311
352
  // starter files: templates are written only when the file is absent, never rebuilt.
@@ -37,9 +37,9 @@ exports.runInstallSkillMode = runInstallSkillMode;
37
37
  const fs = __importStar(require("node:fs"));
38
38
  const os = __importStar(require("node:os"));
39
39
  const path = __importStar(require("node:path"));
40
+ const agent_surfaces_1 = require("./agent-surfaces");
40
41
  const args_1 = require("./args");
41
42
  const skillName = "project-librarian";
42
- const allAgentTargets = ["codex", "claude", "cursor", "gemini"];
43
43
  const packageFiles = [
44
44
  "SKILL.md",
45
45
  "dist",
@@ -65,10 +65,10 @@ function installAgents() {
65
65
  const agents = new Set();
66
66
  for (const part of parts) {
67
67
  if (part === "all") {
68
- for (const agent of allAgentTargets)
68
+ for (const agent of agent_surfaces_1.allAgentSurfaces)
69
69
  agents.add(agent);
70
70
  }
71
- else if (allAgentTargets.includes(part)) {
71
+ else if (agent_surfaces_1.allAgentSurfaces.includes(part)) {
72
72
  agents.add(part);
73
73
  }
74
74
  else {
package/dist/modes.js CHANGED
@@ -57,6 +57,7 @@ const fs = __importStar(require("node:fs"));
57
57
  const childProcess = __importStar(require("node:child_process"));
58
58
  const os = __importStar(require("node:os"));
59
59
  const path = __importStar(require("node:path"));
60
+ const agent_surfaces_1 = require("./agent-surfaces");
60
61
  const args_1 = require("./args");
61
62
  const workspace_1 = require("./workspace");
62
63
  const templates_1 = require("./templates");
@@ -66,6 +67,7 @@ const wiki_graph_1 = require("./wiki-graph");
66
67
  const wiki_corpus_1 = require("./wiki-corpus");
67
68
  const wiki_diagnostics_1 = require("./wiki-diagnostics");
68
69
  const scopedAutoIndexThreshold = 40;
70
+ const scopedAutoIndexCharLimit = 7600;
69
71
  const scopedAutoIndexMarker = "<!-- PROJECT-WIKI-SCOPED-AUTO-INDEX -->";
70
72
  function isScopedAutoIndex(file) {
71
73
  return /^wiki\/indexes\/auto-[a-z0-9-]+\.md$/.test(file);
@@ -89,16 +91,18 @@ function routeAreaForWikiFile(file) {
89
91
  return slugPart(directory);
90
92
  return "misc";
91
93
  }
92
- function scopedIndexPath(area) {
93
- return `wiki/indexes/auto-${slugPart(area)}.md`;
94
+ function scopedIndexPath(area, partIndex = 0, partCount = 1) {
95
+ const slug = slugPart(area);
96
+ return partCount <= 1 ? `wiki/indexes/auto-${slug}.md` : `wiki/indexes/auto-${slug}-${partIndex + 1}.md`;
94
97
  }
95
- function scopedIndexContent(area, files) {
98
+ function scopedIndexContent(area, files, partIndex = 0, partCount = 1) {
99
+ const title = partCount <= 1 ? area : `${area} (${partIndex + 1}/${partCount})`;
96
100
  const rows = files.map((file) => {
97
101
  const meta = (0, wiki_files_1.metadataSummary)(file, (0, workspace_1.read)(file));
98
102
  return `| ${(0, wiki_files_1.wikiLinkForFile)(file)} | ${meta.scope} | ${meta.status} | ${meta.budget} |`;
99
103
  }).join("\n");
100
104
  return `${(0, templates_1.metadata)("wiki-router", "medium", "wiki/meta/wiki-ops-v1-decisions.md", "auto-discovered scoped routes change")}${scopedAutoIndexMarker}
101
- # Auto Index: ${area}
105
+ # Auto Index: ${title}
102
106
 
103
107
  ## TL;DR
104
108
 
@@ -110,6 +114,23 @@ function scopedIndexContent(area, files) {
110
114
  ${rows}
111
115
  `;
112
116
  }
117
+ function splitScopedIndexFiles(area, files) {
118
+ const parts = [];
119
+ let current = [];
120
+ for (const file of files) {
121
+ const candidate = [...current, file];
122
+ if (current.length > 0 && scopedIndexContent(area, candidate).length > scopedAutoIndexCharLimit) {
123
+ parts.push(current);
124
+ current = [file];
125
+ }
126
+ else {
127
+ current = candidate;
128
+ }
129
+ }
130
+ if (current.length > 0)
131
+ parts.push(current);
132
+ return parts;
133
+ }
113
134
  function removeStaleScopedAutoIndexes(keepPaths) {
114
135
  if (!(0, workspace_1.exists)("wiki/indexes"))
115
136
  return;
@@ -126,16 +147,23 @@ function syncScopedAutoIndexes(files) {
126
147
  const area = routeAreaForWikiFile(file);
127
148
  groups.set(area, [...(groups.get(area) ?? []), file]);
128
149
  }
129
- const summaries = Array.from(groups.entries()).map(([area, areaFiles]) => ({
130
- area,
131
- count: areaFiles.length,
132
- file: scopedIndexPath(area),
133
- files: areaFiles.sort(),
134
- })).sort((left, right) => right.count - left.count || left.area.localeCompare(right.area));
150
+ const summaries = Array.from(groups.entries()).flatMap(([area, areaFiles]) => {
151
+ const sortedFiles = areaFiles.sort();
152
+ const parts = splitScopedIndexFiles(area, sortedFiles);
153
+ return parts.map((files, partIndex) => ({
154
+ area: parts.length <= 1 ? area : `${area} ${partIndex + 1}`,
155
+ baseArea: area,
156
+ count: files.length,
157
+ file: scopedIndexPath(area, partIndex, parts.length),
158
+ files,
159
+ partIndex,
160
+ partCount: parts.length,
161
+ }));
162
+ }).sort((left, right) => right.count - left.count || left.area.localeCompare(right.area));
135
163
  const keepPaths = new Set(summaries.map((summary) => summary.file));
136
164
  removeStaleScopedAutoIndexes(keepPaths);
137
165
  for (const summary of summaries)
138
- (0, workspace_1.write)(summary.file, scopedIndexContent(summary.area, summary.files));
166
+ (0, workspace_1.write)(summary.file, scopedIndexContent(summary.baseArea, summary.files, summary.partIndex, summary.partCount));
139
167
  return summaries.map(({ area, count, file }) => ({ area, count, file }));
140
168
  }
141
169
  function buildRefreshIndexBlock() {
@@ -149,8 +177,6 @@ function buildRefreshIndexBlock() {
149
177
  return `<!-- PROJECT-WIKI-AUTO-INDEX:START -->
150
178
  ## Auto-Discovered Pages
151
179
 
152
- This block is managed by \`--refresh-index\`. Large route sets are split into scoped generated routers to keep \`wiki/index.md\` within startup-hook budget.
153
-
154
180
  | Scoped Router | Area | Pages |
155
181
  | --- | --- | ---: |
156
182
  ${rows}
@@ -192,6 +218,10 @@ function scoreQueryBlock(block, terms) {
192
218
  function hasMigrationQueryIntent(terms) {
193
219
  return terms.some((term) => /^(migrat|legacy|coverage|unit|ledger|review)/.test(term));
194
220
  }
221
+ function hasDeepReferenceQueryIntent(terms) {
222
+ return hasMigrationQueryIntent(terms)
223
+ || terms.some((term) => /^(archive|audit|decision|detail|history|ledger|raw|record|source|trace|verification)/.test(term));
224
+ }
195
225
  function isMigrationSurface(file, meta) {
196
226
  return file.startsWith("wiki/migration/")
197
227
  || /(?:^|-)migration(?:-|$)/.test(file)
@@ -204,6 +234,9 @@ function querySurfaceScore(file, meta, rawScore, terms) {
204
234
  return Math.max(1, Math.floor(rawScore * 0.25) - 20);
205
235
  }
206
236
  let score = rawScore;
237
+ if (meta.budget === "on-demand" && !hasDeepReferenceQueryIntent(terms)) {
238
+ score = Math.max(1, Math.min(Math.floor(score * 0.5), 24));
239
+ }
207
240
  if (file.startsWith("wiki/canonical/") && meta.status === "active")
208
241
  score += 12;
209
242
  else if (meta.status === "active")
@@ -889,15 +922,9 @@ const commonLintRequiredFiles = [
889
922
  ".githooks/prepare-commit-msg",
890
923
  ".githooks/wiki-commit-trailers.js",
891
924
  ];
892
- const agentLintRequiredFiles = {
893
- codex: [".codex/hooks/wiki-session-start.js", ".codex/hooks.json"],
894
- claude: ["CLAUDE.md", ".claude/hooks/wiki-session-start.js", ".claude/settings.json"],
895
- cursor: [".cursor/rules/project-librarian.mdc", ".cursor/hooks/wiki-session-start.js", ".cursor/hooks.json"],
896
- gemini: ["GEMINI.md", ".gemini/hooks/wiki-session-start.js", ".gemini/settings.json"],
897
- };
898
925
  function activeLintAgentSurfaces() {
899
926
  const active = new Set();
900
- for (const [agent, files] of Object.entries(agentLintRequiredFiles)) {
927
+ for (const [agent, files] of Object.entries(agent_surfaces_1.agentSurfaceRequiredFiles)) {
901
928
  if (files.some((file) => (0, workspace_1.exists)(file)))
902
929
  active.add(agent);
903
930
  }
@@ -909,7 +936,7 @@ function runLintMode(corpus) {
909
936
  const activeAgents = activeLintAgentSurfaces();
910
937
  const requiredFiles = [
911
938
  ...commonLintRequiredFiles,
912
- ...Array.from(activeAgents).flatMap((agent) => agentLintRequiredFiles[agent]),
939
+ ...Array.from(activeAgents).flatMap((agent) => agent_surfaces_1.agentSurfaceRequiredFiles[agent]),
913
940
  ];
914
941
  for (const file of requiredFiles) {
915
942
  if (!(0, workspace_1.exists)(file))
package/dist/templates.js CHANGED
@@ -70,7 +70,7 @@ At the start of every session:
70
70
 
71
71
  1. Review \`wiki/startup.md\` for compact current context.
72
72
  2. Review \`wiki/index.md\` as the router for which files to read next.
73
- 3. Read detailed \`wiki/canonical/\`, \`wiki/decisions/\`, \`wiki/meta/\`, and \`wiki/sources/\` files on demand only when the current question needs them.
73
+ 3. Read detailed \`wiki/canonical/\`, \`wiki/roadmaps/\`, \`wiki/plans/\`, \`wiki/decisions/\`, \`wiki/meta/\`, and \`wiki/sources/\` files on demand only when the current question needs them.
74
74
 
75
75
  ### ${exports.startupTldrSyncLabel}
76
76
 
@@ -133,12 +133,14 @@ Language policy:
133
133
  Reading rules:
134
134
 
135
135
  - Treat \`startup.md\` as compact session context and \`index.md\` as the router.
136
- - Read detailed \`canonical/\`, \`decisions/\`, \`meta/\`, and \`sources/\` files on demand only when the current question needs them.
136
+ - Read detailed \`canonical/\`, \`roadmaps/\`, \`plans/\`, \`decisions/\`, \`meta/\`, and \`sources/\` files on demand only when the current question needs them.
137
137
  - Prefer each file's TL;DR and metadata before reading the full body.
138
138
 
139
139
  Storage boundaries:
140
140
 
141
141
  - \`canonical/\` contains current project-planning truth only.
142
+ - \`roadmaps/\` contains broad future scope, priority queues, and milestone sequences only; it is not canonical truth.
143
+ - \`plans/\` contains detailed execution plans for roadmap items only; it is not canonical truth.
142
144
  - \`decisions/\` contains project decision history only.
143
145
  - \`meta/\` contains wiki operating rules, decision policy, bootstrap, lint, hook, and migration decisions.
144
146
  - \`sources/\` contains external reference summaries and source notes.
@@ -150,6 +152,8 @@ Classification rules:
150
152
 
151
153
  - Before adding or consolidating project content, classify it with \`meta/document-taxonomy.md\`.
152
154
  - Write current agreement to the narrowest durable canonical document that fits the taxonomy; do not append unrelated material to \`canonical/project-brief.md\`.
155
+ - Put broad future work in \`roadmaps/\` and detailed execution plans in \`plans/\`, not \`canonical/\`.
156
+ - When roadmap or plan work is completed, update canonical truth first, preserve rationale/evidence where needed, then remove the completed roadmap/plan content.
153
157
  - If one input crosses several lifecycle areas, split it into separate canonical updates and link the related pages.
154
158
  - If the input explains why a direction changed, update the relevant decision log or Decision Pack in addition to canonical truth.
155
159
  - If an external artifact is the better source of truth (for example Figma, OpenAPI, ERD, issue tracker, or code), keep a concise canonical summary and link the external source as the authoritative location.
@@ -187,10 +191,11 @@ exports.startup = `${(0, exports.metadata)("startup-router", "short", "wiki/meta
187
191
  ## TL;DR
188
192
 
189
193
  - This project is in an initial planning state unless the canonical wiki says otherwise.
190
- - Project truth lives in \`wiki/canonical/\`, project decision history lives in \`wiki/decisions/\`, and source summaries live in \`wiki/sources/\`.
194
+ - Project truth lives in \`wiki/canonical/\`, future work in \`wiki/roadmaps/\` and \`wiki/plans/\`, project decisions in \`wiki/decisions/\`, and sources in \`wiki/sources/\`.
191
195
  - Wiki operating rules and wiki operating decisions live in \`wiki/meta/\`.
192
196
  - At session start, read only this file and \`wiki/index.md\` first; read detailed files on demand.
193
197
  - Project canonical content language is not fixed by this bootstrap. The LLM should choose the language that best matches the user and project context.
198
+ - Completed roadmaps/plans are removed after truth/rationale/evidence capture.
194
199
  - Update the wiki in the same turn when project-planning content changes.
195
200
  - Classify new project-planning content with \`wiki/meta/document-taxonomy.md\` before writing or consolidating it.
196
201
 
@@ -239,7 +244,9 @@ This file is a router, not a file to expand into every answer. Read only the fil
239
244
 
240
245
  ## Boundary Rule
241
246
 
242
- - \`wiki/canonical/\` and \`wiki/decisions/\` contain project-planning content only.
247
+ - \`wiki/canonical/\`: current accepted project truth only.
248
+ - \`wiki/roadmaps/\`: broad future scope only; \`wiki/plans/\`: detailed execution only.
249
+ - \`wiki/decisions/\`: project decision history only.
243
250
  - Wiki operating rules and wiki operating decisions live in \`wiki/meta/\`.
244
251
  - Non-project LLM memory, collaboration reminders, and workflow instructions belong in \`AGENTS.md\`, \`wiki/AGENTS.md\`, hooks, or skills, not in project canonical/decision docs.
245
252
 
@@ -254,7 +261,7 @@ This file is a router, not a file to expand into every answer. Read only the fil
254
261
 
255
262
  No empty canonical starter pages are created by default. Create focused pages under \`wiki/canonical/\` only when durable project truth exists, then route them here or with \`--refresh-index\`.
256
263
 
257
- ## Project Decisions
264
+ ## Decisions
258
265
 
259
266
  - [[decisions/recent]]
260
267
  - Read: recent important project decisions.
@@ -335,6 +342,7 @@ exports.wikiOperatingModel = `${(0, exports.metadata)("wiki-meta", "medium", "wi
335
342
  - This wiki keeps project-planning knowledge as durable markdown.
336
343
  - Codex, Claude Code, Cursor, and Gemini CLI session-start hooks inject only \`wiki/startup.md\` and \`wiki/index.md\`.
337
344
  - Detailed canonical and decision files are read on demand.
345
+ - Roadmaps and plans are separate from canonical truth; canonical pages keep the current accepted state.
338
346
  - Root \`AGENTS.md\` keeps the project-wide wiki-first contract; \`wiki/AGENTS.md\` keeps detailed wiki editing rules.
339
347
  - Operating documents generated by bootstrap are English by default.
340
348
  - Project canonical content language is selected from user/project context, not hardcoded by this bootstrap.
@@ -352,24 +360,28 @@ Karpathy's LLM Wiki pattern favors a continuously maintained markdown wiki over
352
360
  ## Layers
353
361
 
354
362
  1. Sources: external docs, links, user notes, and evidence summaries.
355
- 2. Canonical project truth: current valid planning content under \`wiki/canonical/\`.
356
- 3. Project decisions: rationale, rejected alternatives, and revisit triggers under \`wiki/decisions/\`.
357
- 4. Startup context: compact session summary in \`wiki/startup.md\`.
358
- 5. Router: read/update/token-budget guidance in \`wiki/index.md\`.
359
- 6. Wiki meta: operating rules, decision policy, bootstrap, migration, lint, and language policy under \`wiki/meta/\`.
363
+ 2. Canonical project truth: current accepted specs, contracts, policies, and operating state under \`wiki/canonical/\`.
364
+ 3. Roadmaps: broad future scope, priority queues, and milestone sequences under \`wiki/roadmaps/\` or an external tracker.
365
+ 4. Plans: detailed execution plans for roadmap items under \`wiki/plans/\` or an external tracker.
366
+ 5. Project decisions: rationale, rejected alternatives, and revisit triggers under \`wiki/decisions/\`.
367
+ 6. Startup context: compact session summary in \`wiki/startup.md\`.
368
+ 7. Router: read/update/token-budget guidance in \`wiki/index.md\`.
369
+ 8. Wiki meta: operating rules, decision policy, bootstrap, migration, lint, and language policy under \`wiki/meta/\`.
360
370
 
361
371
  ## Content Classification Procedure
362
372
 
363
373
  Before writing or reorganizing project-planning content:
364
374
 
365
375
  1. Identify the content's lifecycle area with [[meta/document-taxonomy]].
366
- 2. Decide whether the content is current truth, decision rationale, source evidence, an unresolved candidate, or a wiki operating rule.
367
- 3. Write current truth to the narrowest relevant \`canonical/\` page, decision rationale to \`decisions/\`, source notes to \`sources/\`, candidates to \`inbox/\`, and wiki operating rules to \`meta/\`.
376
+ 2. Decide whether the content is current truth, roadmap, detailed plan, decision rationale, source evidence, an unresolved candidate, or a wiki operating rule.
377
+ 3. Write current truth to the narrowest relevant \`canonical/\` page, broad future scope to \`roadmaps/\`, detailed execution plans to \`plans/\`, decision rationale to \`decisions/\`, source notes to \`sources/\`, candidates to \`inbox/\`, and wiki operating rules to \`meta/\`.
368
378
  4. Split multi-area inputs instead of making one catch-all document.
369
379
  5. Link upstream and downstream pages when the content derives from another artifact or produces another artifact.
370
380
 
371
381
  Do not treat \`canonical/project-brief.md\` as a default dumping ground. It should summarize direction, audience, scope, and success criteria; detailed product, policy, UX, data, engineering, QA, release, or operations truth should move into focused pages when it grows.
372
382
 
383
+ Do not treat \`wiki/canonical/\` as a plan archive. If a whole document is mainly about future scope, implementation sequence, migration wave, branch status, or work result log, keep it outside canonical truth and link it from the relevant current-spec page only when readers need that context. When the work is done, update canonical truth and then remove completed roadmap/plan content after rationale and evidence are preserved in their proper places.
384
+
373
385
  ## Language Policy
374
386
 
375
387
  - Bootstrap-generated operating documents are English.
@@ -448,14 +460,15 @@ exports.documentTaxonomy = `${(0, exports.metadata)("wiki-meta", "medium", "wiki
448
460
  ## TL;DR
449
461
 
450
462
  - Classify new project-planning content before writing it into the wiki.
451
- - Use this page to classify content into \`canonical/\`, \`decisions/\`, \`sources/\`, \`inbox/\`, or \`meta/\`.
452
- - Keep \`canonical/project-brief.md\` compact; move detailed truth into focused canonical pages.
463
+ - Classify into \`canonical/\`, \`roadmaps/\`, \`plans/\`, \`decisions/\`, \`sources/\`, \`inbox/\`, or \`meta/\`.
464
+ - Keep \`canonical/project-brief.md\` compact; move details into focused pages.
465
+ - Keep future work outside canonical; canonical pages may include brief change pointers.
453
466
  - Preserve derivation links: evidence -> strategy -> requirements -> design/data/engineering -> QA -> release/operations -> feedback.
454
467
 
455
468
  ## Top-Level Flow
456
469
 
457
470
  \`\`\`text
458
- 0. Source-of-truth governance
471
+ 0. Governance
459
472
  -> 1. Research and evidence
460
473
  -> 2. Strategy and business model
461
474
  -> 3. Product scope and requirements
@@ -469,27 +482,37 @@ exports.documentTaxonomy = `${(0, exports.metadata)("wiki-meta", "medium", "wiki
469
482
  -> 11. Release and operations
470
483
  -> 12. Business operations
471
484
  -> 13. Improvement, migration, and end-of-life
472
- -> next product scope, policy, or roadmap change
485
+ -> roadmap -> plan -> canonical update
473
486
  \`\`\`
474
487
 
475
488
  ## Storage Decision
476
489
 
477
490
  | Content Type | Store In | Notes |
478
491
  | --- | --- | --- |
479
- | Current valid project truth | \`wiki/canonical/\` | Split by topic and read frequency. |
492
+ | Current project truth | \`wiki/canonical/\` | Accepted spec, contract, policy, or operating state. |
493
+ | Roadmap, milestone sequence, or priority queue | \`wiki/roadmaps/\` or tracker | Broad future scope, not canonical truth. |
494
+ | Detailed plan, proposal, migration, or task sequence | \`wiki/plans/\` or external tracker | Execution detail, not canonical truth. |
480
495
  | Why a choice was made | \`wiki/decisions/\` | Use log, Decision Pack, or ADR by impact. |
481
496
  | Source material or summarized evidence | \`wiki/sources/\` | Keep links, checked dates, and applicability. |
482
497
  | Unreviewed or ambiguous material | \`wiki/inbox/\` | Do not treat as canonical truth. |
483
498
  | Wiki operation, taxonomy, hooks, migration, lint, language rules | \`wiki/meta/\` | Keep outside project canonical truth. |
484
499
  | Better external source of truth | External artifact plus a concise wiki route | Examples: Figma, OpenAPI, ERD, Jira, code. |
485
500
 
501
+ ## Canonical vs Roadmap vs Plan Boundary
502
+
503
+ \`wiki/canonical/\` is for the state readers should treat as true now. A page mainly about future change, implementation sequence, migration wave, branch status, or work log is not canonical truth.
504
+
505
+ Use \`wiki/roadmaps/\` for broad ordered future work. Use \`wiki/plans/\` for one roadmap item's details. Put only short planned-change notes in canonical pages.
506
+
507
+ After acceptance or release, rewrite canonical truth. Move rationale to \`wiki/decisions/\` and evidence to \`wiki/sources/\`, release notes, or reports. Then delete completed roadmap/plan content unless external retention is required.
508
+
486
509
  ## Lifecycle Areas
487
510
 
488
511
  | Area | Put Here | Usually Derives From | Usually Produces |
489
512
  | --- | --- | --- | --- |
490
513
  | 0. Governance | source-of-truth map, owners, RACI, approval flow, change rules, glossary, state dictionary, assumptions, risk register | team/process constraints | routing, ownership, conflict resolution |
491
514
  | 1. Research | market, competitor, user interviews, VOC, analytics, legal/regulatory, technical feasibility, cost, vendor, accessibility research | raw discovery | strategy, risks, sources |
492
- | 2. Strategy | service overview, vision, problem, target users, personas, jobs-to-be-done, value offer, positioning, business model, KPI/OKR, success/stop criteria, roadmap, MVP, non-goals | research | PRD, roadmap, scope |
515
+ | 2. Strategy | service overview, vision, problem, target users, personas, jobs-to-be-done, value offer, positioning, business model, KPI/OKR, success/stop criteria, committed roadmap summary, MVP, non-goals | research | PRD, roadmap, scope |
493
516
  | 3. Product | PRD, user stories, use cases, priorities, backlog rules, acceptance criteria, feature spec, exceptions, state definitions, notification rules, search/filter/sort rules, admin requirements | strategy and policy | UX, API, data, QA |
494
517
  | 4. Policy | operations policy, auth/account, permissions, pricing, payment/refund, coupon/credit, content moderation, notifications, retention/deletion, abuse response, support, EOL | business model, law, risks | feature constraints, API rules, CS/ops |
495
518
  | 5. UX and Content | IA, sitemap, user flow, task flow, screen list, wireframes, screen specs, content model, UX writing, empty/error states, help/FAQ, localization, SEO, accessibility criteria | product and policy | design, frontend, QA |
@@ -498,7 +521,7 @@ exports.documentTaxonomy = `${(0, exports.metadata)("wiki-meta", "medium", "wiki
498
521
  | 8. Engineering | architecture, technology decisions, API/OpenAPI, integrations, webhooks/idempotency, state machines, jobs/cron, error codes, env vars, secrets, local dev, conventions, branch/release strategy, CI/CD, feature flags, dependencies, migrations, performance, scalability, FinOps | product, UX, data, policy | implementation and verification |
499
522
  | 9. Security/Legal | security requirements, threat model, privacy rules, privacy impact, terms, privacy policy, audit logs, permission history, internal access controls, key rotation, vulnerability response, licenses, vendor and DPA documents | data, architecture, law | controls, tests, release gates |
500
523
  | 10. QA | test strategy, QA scenarios, test cases, regression checklist, UAT, browser/device matrix, accessibility tests, performance tests, security tests, data quality tests, design QA, quality gates | requirements, design, engineering | release approval |
501
- | 11. Release/Ops | release plan, deployment procedure, rollback, release notes, operator manual, runbooks, monitoring, observability, SLO/SLA, on-call/escalation, incident response, backup/restore, DR/BCP, recurring checks | QA and infrastructure | stable operation |
524
+ | 11. Release/Ops | current release policy, deployment procedure, rollback, release notes, operator manual, runbooks, monitoring, observability, SLO/SLA, on-call/escalation, incident response, backup/restore, DR/BCP, recurring checks | QA and infrastructure | stable operation |
502
525
  | 12. Business Ops | CS macros, support policy, training, sales/adoption guide, CRM rules, onboarding playbook, churn/offboarding, admin operations, communication templates, revenue recognition, tax/invoice, partner operations | policy, release, sales motion | customer-facing operation |
503
526
  | 13. Improvement/EOL | VOC summary, retrospectives, experiments, experiment results, cohort/retention analysis, feature deprecation, migration/data transfer, service end-of-life | operations and analytics | next PRD, policy, roadmap |
504
527
 
@@ -507,11 +530,14 @@ exports.documentTaxonomy = `${(0, exports.metadata)("wiki-meta", "medium", "wiki
507
530
  When a new note arrives:
508
531
 
509
532
  1. Identify the lifecycle area and storage location.
510
- 2. Update an existing focused page when the topic already has a canonical home.
511
- 3. Create a new focused page only when the topic is durable, likely to be read independently, or too large for its current page.
512
- 4. Add an \`index.md\` route when the page becomes durable.
513
- 5. Add upstream/downstream links in prose or tables when one artifact derives from another.
514
- 6. Record decision rationale separately when the change explains why the project chose one option over another.
533
+ 2. Decide whether content is current truth, roadmap, plan, decision rationale, evidence, candidate, or wiki operating rule.
534
+ 3. Update an existing focused canonical page only when the content changes current truth.
535
+ 4. Create a new focused page only when the topic is durable, likely to be read independently, or too large for its current page.
536
+ 5. If the document is future-oriented, store broad scope in \`roadmaps/\` and detailed execution in \`plans/\`.
537
+ 6. Add an \`index.md\` route when the page becomes durable.
538
+ 7. Add upstream/downstream links in prose or tables when one artifact derives from another.
539
+ 8. Record decision rationale separately when the change explains why the project chose one option over another.
540
+ 9. When roadmap/plan work is done, update canonical truth, preserve rationale/evidence, then remove completed roadmap/plan content.
515
541
 
516
542
  ## Page Shape
517
543
 
@@ -670,7 +696,7 @@ No project decisions yet.
670
696
  ## TL;DR
671
697
 
672
698
  - This Decision Pack records accepted wiki operating choices for project-librarian.
673
- - It covers wiki structure, document taxonomy, startup hook scope, metadata, language policy, git hook behavior, migration review, and inbox handling.
699
+ - It covers wiki structure, document taxonomy, startup hook scope, metadata, language policy, git hook behavior, migration review, inbox handling, and canonical/roadmap/plan boundaries.
674
700
  - Project product decisions belong in \`wiki/decisions/\`, while these operating decisions stay in \`wiki/meta/\`.
675
701
 
676
702
  Status: accepted
@@ -685,6 +711,8 @@ Canonical: [[meta/operating-model]], [[meta/decision-policy]], [[meta/document-t
685
711
  | ${workspace_1.today} | Inject only \`startup.md\` and \`index.md\` through Codex, Claude Code, Cursor, and Gemini CLI startup hooks; route detailed files Read On Demand. | Full canonical and decision bodies waste startup tokens. | Always read detailed canonical and decision files first. | Important context is repeatedly missed at startup. | [[startup]], [[index]] |
686
712
  | ${workspace_1.today} | Use metadata headers on wiki knowledge pages. | Agents and humans can quickly judge status, scope, budget, and review triggers. | Body-only conventions. | Header maintenance costs more than it saves. | [[meta/operating-model]] |
687
713
  | ${workspace_1.today} | Keep wiki operating docs in \`wiki/meta/\`. | Project truth stays focused on product/project content. | Store operating docs in \`canonical/\` or \`decisions/\`. | Meta docs become hard to discover. | [[meta/operating-model]] |
714
+ | ${workspace_1.today} | Split future work into \`roadmaps/\` and \`plans/\`, outside canonical truth. | Roadmaps list broad future scope and sequencing; plans describe detailed execution for one roadmap item; canonical pages should show only the current accepted spec, contract, policy, or operating state. | Store roadmap, improvement, migration, and implementation plans directly in \`canonical/\` as if they were current truth, or mix roadmaps and detailed plans in one directory. | Teams need a different planning directory convention, or plan artifacts become the authoritative source for current behavior. | [[meta/document-taxonomy]], [[meta/operating-model]] |
715
+ | ${workspace_1.today} | Remove completed roadmap and plan content after canonical truth, rationale, and evidence are updated. | Completed future-work documents become stale logs once their outcome is reflected in canonical pages, decisions, and evidence artifacts. | Keep completed roadmap/plan documents indefinitely inside the wiki. | Audit, legal, or release process requires retaining completed plan artifacts in a dedicated external system. | [[meta/document-taxonomy]], [[meta/operating-model]] |
688
716
  | ${workspace_1.today} | Bootstrap-generated operating documents are English by default. | Repository entry points and operating contracts are easier for public users to inspect. | Generate operating docs in a fixed non-English language. | The project intentionally targets a single-language local audience. | [[meta/operating-model]] |
689
717
  | ${workspace_1.today} | Project canonical content language is chosen from user/project context. | User language and source material should drive project truth, not the bootstrap tool. | Hardcode Korean or English as the canonical content language. | A team requires a fixed language policy. | [[startup]], [[index]] |
690
718
  | ${workspace_1.today} | Install git hook files but preserve existing \`core.hooksPath\` values and allow \`--no-git-config\`. | Public users may already have a hook chain such as Husky. | Always replace \`core.hooksPath\`. | Users prefer automatic setup and accept the side effect. | [[meta/operating-model]] |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-librarian",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Create and maintain compact project context for humans and LLM coding agents.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -41,19 +41,25 @@
41
41
  "benchmark:ci": "npm run benchmark:ci-smoke",
42
42
  "benchmark:ci-smoke": "npm run benchmark:llm:parse-smoke && npm run benchmark:llm:dry-run",
43
43
  "benchmark:llm": "npm run build && node benchmarks/codex-llm-metrics.js",
44
+ "benchmark:llm:delta-analysis": "node benchmarks/tools/analyze-llm-deltas.js",
44
45
  "benchmark:llm:dry-run": "npm run build && node benchmarks/codex-llm-metrics.js --dry-run",
45
46
  "benchmark:llm:parse-smoke": "node tests/validators/codex-llm-benchmark-smoke.js",
46
47
  "benchmark:llm:prune-raw": "node benchmarks/tools/prune-llm-raw.js",
48
+ "benchmark:llm:raw-audit": "node benchmarks/tools/audit-llm-raw.js",
47
49
  "benchmark:injection-sentinel": "node benchmarks/tools/injection-sentinel.js",
50
+ "benchmark:agent-surface-smoke": "node benchmarks/tools/agent-surface-smoke.js",
48
51
  "benchmark:claim-ledger": "node benchmarks/tools/benchmark-claim-ledger.js benchmarks/llm/samples/codex-measured-report.json benchmarks/reports/llm/payload-preview.json",
49
52
  "benchmark:real-corpus:demo": "npm run build && node benchmarks/tools/real-corpus-offline-demo.js",
50
53
  "benchmark:release:preview": "npm run benchmark:llm -- --payload-preview benchmarks/reports/llm/payload-preview.json --sanitized-pack --full-matrix --runs 3 --warmup-runs 1 --min-runs-for-claim 3 --require-clean --require-claimable --model gpt-5.5",
54
+ "benchmark:release:diagnose": "npm run benchmark:llm -- --sanitized-pack --runs 1 --warmup-runs 0 --model gpt-5.5 --out benchmarks/reports/llm/diagnostic-current.json --markdown benchmarks/reports/llm/diagnostic-current.md",
51
55
  "benchmark:release": "npm run benchmark:llm -- --sanitized-pack --full-matrix --runs 3 --warmup-runs 1 --min-runs-for-claim 3 --require-clean --require-claimable --model gpt-5.5 --out benchmarks/reports/llm/current.json --markdown benchmarks/reports/llm/current.md",
52
56
  "build": "tsc && chmod +x dist/init-project-wiki.js",
53
57
  "perf:code-efficiency": "node benchmarks/tools/code-performance-efficiency.js --full",
54
58
  "release:check": "node benchmarks/tools/release-readiness.js",
55
59
  "typecheck": "tsc --noEmit",
60
+ "typecheck:ts7": "npx --yes -p typescript@rc tsc --noEmit --project tsconfig.json",
56
61
  "unit": "node --test tests/unit/*.test.js",
62
+ "test:coverage": "node --test --experimental-test-coverage --test-coverage-include=dist/**/*.js --test-coverage-include=benchmarks/**/*.js --test-coverage-lines=65 --test-coverage-branches=65 --test-coverage-functions=65 tests/unit/*.test.js",
57
63
  "test": "npm run build && npm run typecheck && npm run unit && bash tests/smoke.sh",
58
64
  "prepack": "npm run build"
59
65
  },