project-librarian 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SKILL.md ADDED
@@ -0,0 +1,335 @@
1
+ ---
2
+ name: project-librarian
3
+ description: Bootstrap, update, migrate, or code-canonicalize a token-efficient project planning wiki. Use when the user asks to initialize, install, create, update, improve, migrate, adopt existing docs, analyze existing code into project wiki truth, or apply the reusable ./wiki + AGENTS.md + compact SessionStart hook setup for project planning, canonical docs, decision logs, startup summaries, or Karpathy-style LLM wiki workflow.
4
+ metadata:
5
+ short-description: Bootstrap project planning wiki
6
+ ---
7
+
8
+ # Project Librarian
9
+
10
+ Use this skill to install, update, validate, search, migrate, or code-canonicalize a token-efficient planning wiki in the current project.
11
+
12
+ Users should normally interact with this skill through natural language, or through `/project-librarian` in Claude Code. Do not ask users to run lifecycle flags directly unless they explicitly want shell commands; resolve a local project-librarian runner and execute the matching operation yourself from the project root.
13
+
14
+ Supported actions:
15
+
16
+ - Bootstrap or update the project wiki and generated agent/hook files.
17
+ - Validate the wiki setup.
18
+ - Diagnose wiki links, duplicate routes, orphan pages, and document quality gaps.
19
+ - Search project wiki content.
20
+ - Refresh the wiki index.
21
+ - Capture a candidate note into the wiki inbox.
22
+ - Check for pending, stale, proposed, or undecided wiki pages.
23
+ - Draft a GitHub issue body for problems or side effects found while using the skill.
24
+ - Initialize a project glossary.
25
+ - Analyze existing code and canonicalize code-backed project behavior, features, policies, constraints, terminology, domain rules, and open questions into the wiki.
26
+ - Build and query an optional SQLite code evidence index for large repositories.
27
+ - Migrate an existing wiki/docs structure.
28
+ - Review processed migration inbox state.
29
+ - Install hook files without changing git config.
30
+
31
+ ## Workflow
32
+
33
+ 1. Resolve the project-librarian runner before executing lifecycle operations.
34
+
35
+ Prefer an already installed local runner over network package execution:
36
+
37
+ - In the project-librarian source repository, use `node dist/init-project-wiki.js` when `dist/init-project-wiki.js` exists.
38
+ - In a target repository with a project-scoped Codex skill install, use `node .codex/skills/project-librarian/dist/init-project-wiki.js`.
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 user-scoped Codex skill install, use `node ~/.codex/skills/project-librarian/dist/init-project-wiki.js`.
41
+ - In a user-scoped Claude skill install, use `node ~/.claude/skills/project-librarian/dist/init-project-wiki.js`.
42
+
43
+ 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
+
45
+ If the resolved runner fails, report the real error and stop or fix the cause. Do not manually recreate bootstrap or migration output as a fallback.
46
+
47
+ 2. For project bootstrap requests, choose the matching command and run it from the project root. The examples below use `$PROJECT_LIBRARIAN` to mean the resolved runner from step 1:
48
+
49
+ ```bash
50
+ $PROJECT_LIBRARIAN
51
+ ```
52
+
53
+ Use the command variants as follows:
54
+
55
+ - New project wiki or normal update: `$PROJECT_LIBRARIAN`.
56
+ - Existing wiki/docs need migration: `$PROJECT_LIBRARIAN --migrate`.
57
+ - Install hook files without changing git config: `$PROJECT_LIBRARIAN --no-git-config`.
58
+
59
+ When project terminology becomes important, initialize the optional glossary:
60
+
61
+ ```bash
62
+ $PROJECT_LIBRARIAN --glossary-init
63
+ ```
64
+
65
+ Map lifecycle requests to these internal operations:
66
+
67
+ - Validate/check the wiki: `$PROJECT_LIBRARIAN --lint`.
68
+ - Check wiki links and routing: `$PROJECT_LIBRARIAN --link-check`.
69
+ - Check document quality signals: `$PROJECT_LIBRARIAN --quality-check`.
70
+ - Run all wiki diagnostics: `$PROJECT_LIBRARIAN --doctor`.
71
+ - Safely refresh generated routing before diagnostics: `$PROJECT_LIBRARIAN --doctor --fix`.
72
+ - Search the wiki: `$PROJECT_LIBRARIAN --query "search terms"`.
73
+ - Refresh wiki routing/index: `$PROJECT_LIBRARIAN --refresh-index`.
74
+ - Capture a project candidate: `$PROJECT_LIBRARIAN --capture-inbox --title "Candidate title" --content "Candidate content"`.
75
+ - Check stale/pending pages: `$PROJECT_LIBRARIAN --prune-check`.
76
+ - Draft a GitHub issue body for a skill problem or side effect: `$PROJECT_LIBRARIAN --issue-draft --issue-title "Issue title"`.
77
+ - After explicit user approval in a GitHub-backed repository, create the issue through GitHub CLI: `$PROJECT_LIBRARIAN --issue-create --issue-title "Issue title"`.
78
+ - Review migrated inbox state: `$PROJECT_LIBRARIAN --review-migration`.
79
+
80
+ Skill problem reporting contract:
81
+
82
+ - If you discover a project-librarian bug, regression, confusing generated behavior, unintended side effect, or mismatch between this skill's promised workflow and the implementation while using this skill, run `$PROJECT_LIBRARIAN --issue-draft --issue-title "..."` before the final response unless the user explicitly asked not to generate a draft.
83
+ - Run the issue draft even when you can also fix the problem locally. The draft is read-only and preserves the problem report; it does not replace the code/wiki fix.
84
+ - If the user explicitly approves filing a GitHub issue and the repository has GitHub CLI `gh` authenticated, run `$PROJECT_LIBRARIAN --issue-create --issue-title "..."` or use `gh issue create --title "..." --body-file <draft.md>`. If `gh`, authentication, the GitHub remote, or network access fails, report the real error and do not silently fall back.
85
+ - Choose a concise issue title that names the observed problem, not the fix. Summarize the generated draft path or key output in the final response.
86
+
87
+ 3. Verify:
88
+
89
+ ```bash
90
+ node .codex/hooks/wiki-session-start.js
91
+ node .claude/hooks/wiki-session-start.js
92
+ $PROJECT_LIBRARIAN --lint
93
+ $PROJECT_LIBRARIAN --doctor
94
+ node -e 'JSON.parse(require("fs").readFileSync(".codex/hooks.json","utf8")); JSON.parse(require("fs").readFileSync(".claude/settings.json","utf8")); console.log("project librarian ok")'
95
+ ```
96
+
97
+ 4. Report the files created or updated.
98
+
99
+ ## Behavior
100
+
101
+ The script is idempotent. It creates missing files, updates the managed startup/hook/index operating files, and preserves project-specific planning files unless adding a missing TL;DR.
102
+
103
+ Existing root instruction files are preservation-first:
104
+
105
+ - Existing `AGENTS.md`, `CLAUDE.md`, and `wiki/AGENTS.md` files are not overwritten wholesale.
106
+ - If no managed project-wiki section exists, bootstrap appends its marker-bounded section to the existing file.
107
+ - On rerun, bootstrap replaces only content between its own `PROJECT-WIKI-*` markers and preserves surrounding project-specific content.
108
+
109
+ Use `--lint` for read-only validation:
110
+
111
+ ```bash
112
+ $PROJECT_LIBRARIAN --lint
113
+ ```
114
+
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.
116
+
117
+ 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
+
119
+ ## Code-Informed Canonicalization
120
+
121
+ Use this workflow when the user asks to analyze existing code and turn what the code proves into project wiki truth. This is a skill workflow, not a separate CLI flag.
122
+
123
+ For large repositories or repeated analysis, build a regenerable SQLite code evidence index before canonicalization:
124
+
125
+ ```bash
126
+ $PROJECT_LIBRARIAN --code-index
127
+ ```
128
+
129
+ `--code-evidence-index` is an equivalent explicit alias. Use the old `--code-index` form only as the short compatibility name.
130
+
131
+ Pass user-requested code scopes internally with `--code-scope`:
132
+
133
+ ```bash
134
+ $PROJECT_LIBRARIAN --code-index --code-scope src --code-scope packages/api
135
+ ```
136
+
137
+ Use the optional Tree-sitter backend only when stronger multi-language structural extraction is intended and optional packages are installed:
138
+
139
+ ```bash
140
+ $PROJECT_LIBRARIAN --code-index --code-parser tree-sitter --code-scope src
141
+ ```
142
+
143
+ Require a compatible existing cache for changed-file-only updates with `--incremental`:
144
+
145
+ ```bash
146
+ $PROJECT_LIBRARIAN --code-index --incremental --code-scope src
147
+ ```
148
+
149
+ Run read-only SQL over the cache with `--code-query`:
150
+
151
+ ```bash
152
+ $PROJECT_LIBRARIAN --code-query "select path, language from files order by path"
153
+ ```
154
+
155
+ Use the built-in inspection surfaces before writing custom SQL when they are enough:
156
+
157
+ ```bash
158
+ $PROJECT_LIBRARIAN --code-status
159
+ $PROJECT_LIBRARIAN --code-files
160
+ $PROJECT_LIBRARIAN --code-report --code-report-section parsers
161
+ $PROJECT_LIBRARIAN --code-report --code-report-section workspaces
162
+ $PROJECT_LIBRARIAN --code-report --code-report-section workspace-graph
163
+ $PROJECT_LIBRARIAN --code-report --code-report-section routes
164
+ $PROJECT_LIBRARIAN --code-impact Auth
165
+ $PROJECT_LIBRARIAN --code-search-symbol Auth
166
+ ```
167
+
168
+ The code evidence index lives at `.project-wiki/code-evidence.sqlite`. It is not canonical wiki content, should not be copied into `wiki/`, and can be deleted and regenerated.
169
+
170
+ Treat the index as evidence support, not as a complete language-support guarantee. Strong extraction profiles can support code-proven claims; lightweight inventory and heuristic findings are pointers for follow-up reading.
171
+
172
+ Safety and runtime boundaries:
173
+
174
+ - Keep custom cache output under `.project-wiki/`; do not write disposable evidence databases into `wiki/` canonical content or elsewhere in the repository.
175
+ - Keep code scopes inside the project root.
176
+ - In git repositories, the indexer respects `.gitignore` through `git ls-files --cached --others --exclude-standard`.
177
+ - `.env*` files are excluded from the index, except `.env.example`.
178
+ - Obvious sensitive config filenames containing secret, credential, token, private, or key terms are excluded from the index.
179
+ - Project Librarian requires Node 22.13+ for the installed runner because code evidence indexing uses stable `node:sqlite` without experimental flags; if the runtime is older, report the real runtime error instead of recreating output manually.
180
+ - `--code-parser tree-sitter` requires the optional `@sengac/tree-sitter*` package family for JS/TS/TSX/Python/Go/Rust/Java/PHP/Kotlin/Swift/C/C++/C# extraction; if unavailable, report the package error instead of silently using the default backend.
181
+
182
+ Scope selection is handled through the user's natural-language request:
183
+
184
+ - Whole repository if the user asks for all code or gives no narrower scope.
185
+ - One or more explicit directories, packages, apps, services, or files when the user names them.
186
+ - Exclude generated files, vendored files, lockfiles, build output, and tests unless they are needed to understand behavior, contracts, or risk.
187
+
188
+ Execution contract:
189
+
190
+ 1. Bootstrap the wiki first if the project wiki is missing.
191
+ 2. Inspect the requested code scope using normal repository-reading tools.
192
+ 3. Separate evidence mapping from canonical truth:
193
+ - 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.
194
+ - Code-backed current project behavior, features, policies, constraints, terminology, domain rules, and operational facts belong under `wiki/canonical/`.
195
+ - Important design rationale or tradeoffs inferred from code may belong under `wiki/decisions/` when they meet the decision policy.
196
+ - Unclear, conflicting, or low-confidence interpretations belong in `wiki/inbox/` or `wiki/canonical/open-questions.md`, not directly in canonical truth.
197
+ 4. Do not use fixed canonical filenames beyond existing starter docs. Choose or create files from topic boundaries, expected read frequency, and token budget.
198
+ 5. Split large subjects into focused documents when a single file would force agents to read unrelated content.
199
+ 6. Cite concrete evidence with repository-relative paths and distinguish code-proven facts from inference.
200
+ 7. Update `wiki/startup.md` and `wiki/index.md` only with compact routing hints, not large code summaries.
201
+ 8. Run `$PROJECT_LIBRARIAN --refresh-index` and `$PROJECT_LIBRARIAN --lint` after wiki edits when practical.
202
+
203
+ It installs:
204
+
205
+ - `AGENTS.md` compact project-wide wiki-first planning instructions.
206
+ - `CLAUDE.md` compact Claude Code compatibility file that imports `AGENTS.md`.
207
+ - `wiki/AGENTS.md` detailed wiki-internal editing and boundary rules.
208
+ - `.githooks/prepare-commit-msg` wiki commit trailer hook.
209
+ - `.githooks/wiki-commit-trailers.js` staged-file based trailer generator.
210
+ - `.codex/hooks.json` `SessionStart` hook.
211
+ - `.codex/hooks/wiki-session-start.js` compact startup context injector.
212
+ - `.claude/settings.json` Claude Code `SessionStart` hook.
213
+ - `.claude/hooks/wiki-session-start.js` compact startup context injector for Claude Code.
214
+ - `wiki/startup.md` compact session-start context.
215
+ - `wiki/index.md` router with read/update/token-budget hints.
216
+ - `wiki/canonical/` project-current-truth starter documents.
217
+ - Optional `wiki/canonical/glossary.md` project terminology contract when `--glossary-init` is used.
218
+ - `wiki/decisions/` project-decision starter documents and ADR templates.
219
+ - `wiki/meta/` wiki operating rules, project decision policy, and wiki-operations Decision Pack.
220
+ - `wiki/sources/` source summary starter documents.
221
+
222
+ The Codex and Claude Code 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`. `CLAUDE.md` still imports `AGENTS.md` so Claude Code shares 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
+
224
+ 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
+
226
+ ## Language Policy
227
+
228
+ The public repository README is English by default and may link to localized documentation such as `README.ko.md`.
229
+
230
+ Generated operating documents are English by default, including root `AGENTS.md`, `wiki/AGENTS.md`, `wiki/startup.md`, `wiki/index.md`, migration operating pages, and wiki meta pages.
231
+
232
+ Project canonical wiki content should not default to Korean or English. Choose the language from explicit user instruction, existing project language, source documents, and team context. When no signal exists, prefer the language already used in the current interaction or repository.
233
+
234
+ ## Boundary Rule
235
+
236
+ `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.
237
+
238
+ Use:
239
+
240
+ - `wiki/meta/` for the wiki operating contract and wiki-operations decisions.
241
+ - Root `AGENTS.md`, hooks, or skills for durable project-wide LLM instructions and collaboration memory.
242
+ - `wiki/AGENTS.md` for wiki-internal editing rules that should apply only under `wiki/`.
243
+ - `wiki/canonical/` only for current project truth.
244
+ - `wiki/decisions/` only for project decision history.
245
+
246
+ Every wiki markdown file should include a compact metadata header with `status`, `updated`, `scope`, `read_budget`, `decision_ref`, and `review_trigger`.
247
+
248
+ ## Commit Automation
249
+
250
+ Wiki-specific commit trailers are automated through `.githooks/prepare-commit-msg`.
251
+
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/`.
253
+
254
+ It appends these trailers when they are missing:
255
+
256
+ - `Wiki-scope`
257
+ - `Canonical-updated`
258
+ - `Decision-ref`
259
+ - `Startup-updated`
260
+ - `Index-updated`
261
+ - `Migration-status`
262
+ - `Tested`
263
+ - `Not-tested`
264
+
265
+ Do not hand-write wiki trailers unless the hook is unavailable or the generated value needs correction.
266
+
267
+ `--lint` verifies the Codex and Claude hook files/settings, 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
+
269
+ ## Glossary Mode
270
+
271
+ `--glossary-init` creates `wiki/canonical/glossary.md` only when terminology has become useful. It also adds glossary routing to `wiki/index.md` without adding glossary content to startup hook context.
272
+
273
+ Use glossary mode when:
274
+
275
+ - The same concept has two or more name candidates.
276
+ - Domain or business terms repeat.
277
+ - Roles, states, permissions, events, entities, API names, DB names, or UI labels appear.
278
+ - A term needs a canonical name before it enters API, DB, UI, or policy text.
279
+
280
+ The glossary is a project terminology contract, not a general notes file. It excludes wiki operating terms and LLM collaboration memory.
281
+
282
+ `--lint` validates glossary metadata/table shape when the glossary exists, and warns when canonical docs show naming/model signals but no glossary exists.
283
+
284
+ ## Lifecycle Modes
285
+
286
+ These modes preserve this project's stricter source-of-truth boundaries:
287
+
288
+ - `--query "terms"`: read-only keyword search over wiki paths, metadata, titles, and bodies. It does not use embeddings.
289
+ - `--issue-draft --issue-title "..."`: read-only Markdown problem-report draft for skill failures, side effects, confusing behavior, or generated-file surprises. It does not create a GitHub issue or require network access.
290
+ - `--refresh-index`: updates a managed auto-discovered block in `wiki/index.md` for wiki files not routed by the hand-written index.
291
+ - `--capture-inbox --title "..." --content "..."`: appends a project-candidate row to `wiki/inbox/project-candidates.md` and routes the inbox from `wiki/index.md`.
292
+ - `--prune-check`: read-only report of active wiki pages with pending/proposed/stale review signals.
293
+
294
+ Captured inbox entries are not canonical. Fold them into `wiki/canonical/`, `wiki/decisions/`, `wiki/sources/`, or `wiki/meta/` only after review.
295
+
296
+ ## Migration Mode
297
+
298
+ `--migrate` and `--adopt-existing` are aliases.
299
+
300
+ Migration mode is a reset-and-rewrite flow:
301
+
302
+ - If `./wiki` exists, renames it to `./wiki_legacy`.
303
+ - If `./wiki_legacy` already exists, preserves both by using a timestamped `wiki_legacy_...` directory for the current wiki.
304
+ - Creates a fresh `./wiki` using the current standard rules.
305
+ - Scans markdown files under the legacy wiki directory.
306
+ - Writes `wiki/migration/inventory.md`, `wiki/migration/plan.md`, and `wiki/migration/verification.md`.
307
+ - Writes rewrite inboxes:
308
+ - `wiki/canonical/migration-inbox.md`
309
+ - `wiki/decisions/migration-inbox.md`
310
+ - `wiki/sources/migration-inbox.md`
311
+ - Adds migration routing to `wiki/startup.md` and `wiki/index.md`.
312
+
313
+ After migration mode, inspect inboxes and fold legacy content into canonical docs, Decision Packs, ADRs, source summaries, or meta docs. Do not copy legacy markdown files directly into `wiki/canonical/`, `wiki/decisions/`, or `wiki/sources/`; rewrite only the useful project meaning, cite current-project evidence when possible, and keep ambiguous material in the migration inbox or mark it `needs-human-review`.
314
+
315
+ Inbox rows use these statuses:
316
+
317
+ - `pending`: not processed yet.
318
+ - `adopted`: content was absorbed into the new wiki.
319
+ - `rejected`: content was intentionally not migrated.
320
+ - `resolved`: content was already covered or made obsolete by another migrated item.
321
+ - `needs-human-review`: LLM should not close this automatically because the item has important ambiguity, conflict, deletion risk, or product/API/security/policy/data-model impact.
322
+
323
+ Run semantic review sync after LLM or human processing:
324
+
325
+ ```bash
326
+ $PROJECT_LIBRARIAN --review-migration
327
+ ```
328
+
329
+ `wiki/migration/verification.md` verifies file coverage: every legacy markdown file should be mapped to a new-wiki migration target. This is not a semantic-completeness proof. Semantic migration is complete only after inbox rows are marked adopted/rejected/resolved and `needs-human-review` is 0.
330
+
331
+ 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
+
333
+ Run `$PROJECT_LIBRARIAN --doctor` after migration review. `--quality-check` and `--doctor` report `migration-copy-risk` when a new project wiki document appears to be copied from `wiki_legacy*`, and report `migration-filename-reuse` when a legacy filename is reused and needs rewrite verification.
334
+
335
+ Do not delete `wiki_legacy` until migration verification passes, semantic review is complete, and migration copy diagnostics are clear.
@@ -0,0 +1,3 @@
1
+ display_name: Project Librarian
2
+ short_description: Installs a token-efficient planning wiki, AGENTS.md rules, and compact startup hook.
3
+ default_prompt: Initialize this project with a token-efficient planning wiki setup.
package/dist/args.js ADDED
@@ -0,0 +1,235 @@
1
+ "use strict";
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;
4
+ exports.parseArgs = parseArgs;
5
+ exports.argValue = argValue;
6
+ exports.argValues = argValues;
7
+ exports.rawArgs = process.argv.slice(2);
8
+ const knownCommands = new Set(["init", "install-skill"]);
9
+ const flagsWithoutValues = new Set([
10
+ "--adopt-existing",
11
+ "--capture-inbox",
12
+ "--code-evidence-files",
13
+ "--code-evidence-index",
14
+ "--code-evidence-status",
15
+ "--code-files",
16
+ "--code-incremental",
17
+ "--code-index",
18
+ "--code-index-full",
19
+ "--code-index-incremental",
20
+ "--code-evidence-index-full",
21
+ "--code-evidence-index-incremental",
22
+ "--code-report",
23
+ "--code-status",
24
+ "--code-evidence-report",
25
+ "--dry-run",
26
+ "--glossary-init",
27
+ "--doctor",
28
+ "--fix",
29
+ "--issue-create",
30
+ "--issue-draft",
31
+ "--incremental",
32
+ "--link-check",
33
+ "--lint",
34
+ "--migrate",
35
+ "--no-git-config",
36
+ "--prune-check",
37
+ "--quality-check",
38
+ "--refresh-index",
39
+ "--review-migration",
40
+ "--semantic-migrate",
41
+ ]);
42
+ const flagsWithValues = new Set([
43
+ "--agents",
44
+ "--category",
45
+ "--code-evidence-impact",
46
+ "--code-evidence-out",
47
+ "--code-evidence-parser",
48
+ "--code-evidence-query",
49
+ "--code-evidence-report-section",
50
+ "--code-evidence-scope",
51
+ "--code-evidence-symbol",
52
+ "--code-impact",
53
+ "--code-index-out",
54
+ "--code-parser",
55
+ "--code-query",
56
+ "--code-report-section",
57
+ "--code-scope",
58
+ "--code-search-symbol",
59
+ "--content",
60
+ "--issue-body-file",
61
+ "--issue-title",
62
+ "--query",
63
+ "--scope",
64
+ "--title",
65
+ ]);
66
+ const knownFlags = new Set([...flagsWithoutValues, ...flagsWithValues, "--help", "-h"]);
67
+ function flagName(arg) {
68
+ return arg.startsWith("--") ? arg.split("=", 1)[0] ?? arg : arg;
69
+ }
70
+ function hasFlagIn(commandArgs, name) {
71
+ const prefix = `${name}=`;
72
+ return commandArgs.some((arg) => arg === name || arg.startsWith(prefix));
73
+ }
74
+ function flagHasValue(commandArgs, name) {
75
+ const prefix = `${name}=`;
76
+ for (let index = 0; index < commandArgs.length; index += 1) {
77
+ const arg = commandArgs[index];
78
+ if (!arg)
79
+ continue;
80
+ if (arg.startsWith(prefix))
81
+ return arg.slice(prefix.length).trim().length > 0;
82
+ if (arg === name) {
83
+ const next = commandArgs[index + 1];
84
+ return Boolean(next && !next.startsWith("-"));
85
+ }
86
+ }
87
+ return true;
88
+ }
89
+ function argValueFrom(commandArgs, name) {
90
+ const prefix = `${name}=`;
91
+ const inline = commandArgs.find((arg) => arg.startsWith(prefix));
92
+ if (inline)
93
+ return inline.slice(prefix.length);
94
+ const index = commandArgs.indexOf(name);
95
+ const next = index >= 0 ? commandArgs[index + 1] : undefined;
96
+ if (next && !next.startsWith("--")) {
97
+ return next;
98
+ }
99
+ return "";
100
+ }
101
+ function argValuesFrom(commandArgs, name) {
102
+ const prefix = `${name}=`;
103
+ const values = [];
104
+ for (let index = 0; index < commandArgs.length; index += 1) {
105
+ const arg = commandArgs[index];
106
+ if (!arg)
107
+ continue;
108
+ if (arg.startsWith(prefix)) {
109
+ values.push(arg.slice(prefix.length));
110
+ }
111
+ else if (arg === name) {
112
+ const next = commandArgs[index + 1];
113
+ if (next && !next.startsWith("--"))
114
+ values.push(next);
115
+ }
116
+ }
117
+ return values.flatMap((value) => value.split(",").map((part) => part.trim()).filter(Boolean));
118
+ }
119
+ function parseArgs(argv) {
120
+ const command = knownCommands.has(argv[0] ?? "") ? argv[0] : "init";
121
+ const commandArgs = command === argv[0] ? argv.slice(1) : argv;
122
+ const args = new Set(commandArgs);
123
+ const hasFlag = (name) => hasFlagIn(commandArgs, name);
124
+ const argValue = (name) => argValueFrom(commandArgs, name);
125
+ const argValues = (name) => argValuesFrom(commandArgs, name);
126
+ const codeImpactTarget = argValue("--code-impact") || argValue("--code-evidence-impact");
127
+ const codeQuerySql = argValue("--code-query") || argValue("--code-evidence-query");
128
+ const codeSearchSymbol = argValue("--code-search-symbol") || argValue("--code-evidence-symbol");
129
+ return {
130
+ args,
131
+ captureCategory: argValue("--category") || "project-candidate",
132
+ captureContent: argValue("--content"),
133
+ captureInboxMode: args.has("--capture-inbox"),
134
+ captureTitle: argValue("--title"),
135
+ codeFilesMode: args.has("--code-files") || args.has("--code-evidence-files"),
136
+ codeImpactMode: hasFlag("--code-impact") || hasFlag("--code-evidence-impact"),
137
+ codeImpactTarget,
138
+ codeIndexFullMode: args.has("--code-index-full") || args.has("--code-evidence-index-full"),
139
+ codeIndexIncrementalMode: args.has("--incremental") || args.has("--code-incremental") || args.has("--code-index-incremental") || args.has("--code-evidence-index-incremental"),
140
+ codeIndexMode: args.has("--code-index") || args.has("--code-evidence-index"),
141
+ codeIndexOutput: argValue("--code-index-out") || argValue("--code-evidence-out") || ".project-wiki/code-evidence.sqlite",
142
+ codeIndexScopes: [...argValues("--code-scope"), ...argValues("--code-evidence-scope")],
143
+ codeParser: argValue("--code-parser") || argValue("--code-evidence-parser") || "default",
144
+ codeParserMode: hasFlag("--code-parser") || hasFlag("--code-evidence-parser"),
145
+ codeQueryMode: hasFlag("--code-query") || hasFlag("--code-evidence-query"),
146
+ codeQuerySql,
147
+ codeReportMode: args.has("--code-report") || args.has("--code-evidence-report"),
148
+ codeReportSection: argValue("--code-report-section") || argValue("--code-evidence-report-section"),
149
+ codeSearchSymbol,
150
+ codeSearchSymbolMode: hasFlag("--code-search-symbol") || hasFlag("--code-evidence-symbol"),
151
+ codeStatusMode: args.has("--code-status") || args.has("--code-evidence-status"),
152
+ command,
153
+ commandArgs,
154
+ doctorMode: args.has("--doctor"),
155
+ fixMode: args.has("--fix"),
156
+ glossaryMode: args.has("--glossary-init"),
157
+ helpMode: argv.includes("--help") || argv.includes("-h"),
158
+ issueBodyFile: argValue("--issue-body-file"),
159
+ issueCreateMode: args.has("--issue-create"),
160
+ issueDraftMode: args.has("--issue-draft"),
161
+ issueDraftTitle: argValue("--issue-title"),
162
+ linkCheckMode: args.has("--link-check"),
163
+ lintMode: args.has("--lint"),
164
+ migrateMode: args.has("--migrate") || args.has("--adopt-existing"),
165
+ missingValueOptions: Array.from(flagsWithValues).filter((flag) => hasFlag(flag) && !flagHasValue(commandArgs, flag)),
166
+ noGitConfigMode: args.has("--no-git-config"),
167
+ pruneCheckMode: args.has("--prune-check"),
168
+ qualityCheckMode: args.has("--quality-check"),
169
+ queryTerm: argValue("--query"),
170
+ rawArgs: argv,
171
+ refreshIndexMode: args.has("--refresh-index"),
172
+ reviewMigrationMode: args.has("--review-migration") || args.has("--semantic-migrate"),
173
+ unexpectedValueOptions: Array.from(new Set(commandArgs
174
+ .filter((arg) => arg.startsWith("--") && arg.includes("="))
175
+ .map(flagName)
176
+ .filter((arg) => flagsWithoutValues.has(arg)))),
177
+ unknownCommand: argv[0] && !argv[0].startsWith("-") && !knownCommands.has(argv[0]) ? argv[0] : "",
178
+ unknownOptions: Array.from(new Set(commandArgs
179
+ .filter((arg) => arg.startsWith("-"))
180
+ .map(flagName)
181
+ .filter((arg) => !knownFlags.has(arg)))),
182
+ };
183
+ }
184
+ exports.parsedArgs = parseArgs(exports.rawArgs);
185
+ exports.helpMode = exports.parsedArgs.helpMode;
186
+ exports.unknownCommand = exports.parsedArgs.unknownCommand;
187
+ exports.command = exports.parsedArgs.command;
188
+ exports.commandArgs = exports.parsedArgs.commandArgs;
189
+ exports.args = exports.parsedArgs.args;
190
+ exports.unknownOptions = exports.parsedArgs.unknownOptions;
191
+ exports.unexpectedValueOptions = exports.parsedArgs.unexpectedValueOptions;
192
+ exports.missingValueOptions = exports.parsedArgs.missingValueOptions;
193
+ exports.migrateMode = exports.parsedArgs.migrateMode;
194
+ exports.lintMode = exports.parsedArgs.lintMode;
195
+ exports.linkCheckMode = exports.parsedArgs.linkCheckMode;
196
+ exports.qualityCheckMode = exports.parsedArgs.qualityCheckMode;
197
+ exports.doctorMode = exports.parsedArgs.doctorMode;
198
+ exports.fixMode = exports.parsedArgs.fixMode;
199
+ exports.glossaryMode = exports.parsedArgs.glossaryMode;
200
+ exports.issueCreateMode = exports.parsedArgs.issueCreateMode;
201
+ exports.issueDraftMode = exports.parsedArgs.issueDraftMode;
202
+ exports.refreshIndexMode = exports.parsedArgs.refreshIndexMode;
203
+ exports.captureInboxMode = exports.parsedArgs.captureInboxMode;
204
+ exports.pruneCheckMode = exports.parsedArgs.pruneCheckMode;
205
+ exports.reviewMigrationMode = exports.parsedArgs.reviewMigrationMode;
206
+ exports.noGitConfigMode = exports.parsedArgs.noGitConfigMode;
207
+ exports.codeIndexMode = exports.parsedArgs.codeIndexMode;
208
+ exports.codeIndexIncrementalMode = exports.parsedArgs.codeIndexIncrementalMode;
209
+ exports.codeIndexFullMode = exports.parsedArgs.codeIndexFullMode;
210
+ exports.codeReportMode = exports.parsedArgs.codeReportMode;
211
+ exports.codeStatusMode = exports.parsedArgs.codeStatusMode;
212
+ exports.codeFilesMode = exports.parsedArgs.codeFilesMode;
213
+ exports.codeParserMode = exports.parsedArgs.codeParserMode;
214
+ exports.codeImpactMode = exports.parsedArgs.codeImpactMode;
215
+ exports.codeQueryMode = exports.parsedArgs.codeQueryMode;
216
+ exports.codeSearchSymbolMode = exports.parsedArgs.codeSearchSymbolMode;
217
+ function argValue(name) {
218
+ return argValueFrom(exports.commandArgs, name);
219
+ }
220
+ function argValues(name) {
221
+ return argValuesFrom(exports.commandArgs, name);
222
+ }
223
+ exports.queryTerm = exports.parsedArgs.queryTerm;
224
+ exports.codeImpactTarget = exports.parsedArgs.codeImpactTarget;
225
+ exports.codeQuerySql = exports.parsedArgs.codeQuerySql;
226
+ exports.codeReportSection = exports.parsedArgs.codeReportSection;
227
+ exports.codeSearchSymbol = exports.parsedArgs.codeSearchSymbol;
228
+ exports.codeIndexOutput = exports.parsedArgs.codeIndexOutput;
229
+ exports.codeParser = exports.parsedArgs.codeParser;
230
+ exports.codeIndexScopes = exports.parsedArgs.codeIndexScopes;
231
+ exports.captureTitle = exports.parsedArgs.captureTitle;
232
+ exports.captureContent = exports.parsedArgs.captureContent;
233
+ exports.captureCategory = exports.parsedArgs.captureCategory;
234
+ exports.issueBodyFile = exports.parsedArgs.issueBodyFile;
235
+ exports.issueDraftTitle = exports.parsedArgs.issueDraftTitle;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.codeEvidenceNodeRuntimeRequirement = void 0;
4
+ exports.loadDatabaseSync = loadDatabaseSync;
5
+ exports.openDatabase = openDatabase;
6
+ exports.codeEvidenceNodeRuntimeRequirement = "Node.js 22.13+ or 24+; node:sqlite was added in Node.js 22.5.0 and became available without --experimental-sqlite in Node.js 22.13.0";
7
+ function loadDatabaseSync(fail) {
8
+ const previousListeners = process.listeners("warning");
9
+ const suppressExperimentalSqliteWarning = (warning) => {
10
+ if (warning.name !== "ExperimentalWarning" || !warning.message.includes("SQLite")) {
11
+ for (const listener of previousListeners)
12
+ listener.call(process, warning);
13
+ }
14
+ };
15
+ try {
16
+ process.removeAllListeners("warning");
17
+ process.on("warning", suppressExperimentalSqliteWarning);
18
+ const sqlite = require("node:sqlite");
19
+ return sqlite.DatabaseSync;
20
+ }
21
+ catch (error) {
22
+ const message = error instanceof Error ? error.message : String(error);
23
+ return fail(`code evidence index requires Node.js 22.13+ because it uses node:sqlite without experimental flags; current Node is ${process.version}. Runtime policy: ${exports.codeEvidenceNodeRuntimeRequirement}. Error: ${message}`);
24
+ }
25
+ finally {
26
+ process.removeAllListeners("warning");
27
+ for (const listener of previousListeners)
28
+ process.on("warning", listener);
29
+ }
30
+ }
31
+ function openDatabase(databasePath, fail) {
32
+ const DatabaseSync = loadDatabaseSync(fail);
33
+ return new DatabaseSync(databasePath);
34
+ }