project-librarian 0.2.0 → 0.3.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/README.ko.md +260 -120
- package/README.md +203 -114
- package/SKILL.md +38 -18
- package/dist/args.js +20 -2
- package/dist/code-index-file-policy.js +107 -2
- package/dist/code-index.js +77 -59
- package/dist/hooks.js +143 -7
- package/dist/init-project-wiki.js +237 -145
- package/dist/install-skill.js +24 -12
- package/dist/mcp-server.js +449 -0
- package/dist/migration.js +1064 -50
- package/dist/modes.js +324 -149
- package/dist/taxonomy.js +193 -0
- package/dist/templates.js +241 -42
- package/dist/wiki-files.js +24 -28
- package/dist/wiki-graph.js +141 -0
- package/package.json +11 -8
- package/README.ja.md +0 -227
- package/README.zh.md +0 -227
|
@@ -8,34 +8,39 @@ const modes_1 = require("./modes");
|
|
|
8
8
|
const migration_1 = require("./migration");
|
|
9
9
|
const templates_1 = require("./templates");
|
|
10
10
|
const workspace_1 = require("./workspace");
|
|
11
|
-
const wiki_files_1 = require("./wiki-files");
|
|
12
11
|
function codeIndex() {
|
|
13
12
|
return require("./code-index");
|
|
14
13
|
}
|
|
15
14
|
function printUsage() {
|
|
16
15
|
console.log(`Usage:
|
|
17
16
|
project-librarian [init] [options]
|
|
18
|
-
project-librarian install-skill [--scope user|project] [--agents codex|claude|
|
|
17
|
+
project-librarian install-skill [--scope user|project] [--agents codex|claude|cursor|gemini|all]
|
|
18
|
+
project-librarian mcp
|
|
19
19
|
|
|
20
20
|
Options:
|
|
21
|
-
--migrate, --adopt-existing Preserve an existing wiki as wiki_legacy and create migration inboxes.
|
|
21
|
+
--migrate, --adopt-existing Preserve an existing wiki as wiki_legacy and create unit-level migration map, split plan, coverage ledger, review files, and inboxes.
|
|
22
22
|
--lint Validate the generated project wiki setup without editing files.
|
|
23
23
|
--link-check Report broken wiki links, duplicate routes, and orphan pages.
|
|
24
24
|
--quality-check Report stale, conflicting, and low-quality wiki document signals.
|
|
25
25
|
--doctor Run lint, link-check, and quality-check together.
|
|
26
26
|
--fix With --doctor, safely refresh generated index routing.
|
|
27
|
+
--migration-lint Validate migration review scaffolding separately from normal lint.
|
|
28
|
+
--migration-quality-check Report migration policy/structure signals separately from normal quality-check.
|
|
29
|
+
--migration-doctor Run migration-lint and migration-quality-check together.
|
|
27
30
|
--issue-create Create a GitHub issue with gh issue create after explicit user approval.
|
|
28
31
|
--issue-draft Print a problem/side-effect GitHub issue body draft.
|
|
29
32
|
--issue-body-file <path> With --issue-create, use an existing Markdown body file.
|
|
30
33
|
--issue-title <title> Override the generated issue draft title.
|
|
31
|
-
--query <terms> Search wiki paths, metadata, titles, and bodies.
|
|
34
|
+
--query <terms> Search wiki paths, metadata, titles, and bodies (answer-shaped, capped output).
|
|
35
|
+
--wiki-impact <page-or-term> Show wiki backlinks, decision_ref citations, and router depth for matching pages.
|
|
32
36
|
--refresh-index Update the managed auto-discovered wiki index block.
|
|
33
37
|
--capture-inbox Append a candidate note with --title, --content, and optional --category.
|
|
34
38
|
--glossary-init Create and route the optional glossary page.
|
|
35
39
|
--prune-check Report active pages with stale or unresolved signals.
|
|
36
|
-
--review-migration Sync
|
|
40
|
+
--review-migration Sync unit coverage and compatible inbox statuses into migration review files.
|
|
37
41
|
--no-git-config Install hook files without changing git core.hooksPath.
|
|
38
42
|
--code-index Build the disposable .project-wiki code evidence index.
|
|
43
|
+
--acknowledge-small-repo With --code-index, proceed below the small-repo scale gate after its cost warning.
|
|
39
44
|
--incremental With --code-index, require an existing compatible index and update only changes.
|
|
40
45
|
--code-index-full With --code-index, force a full rebuild even when incremental update is possible.
|
|
41
46
|
--code-parser <mode> With --code-index, use parser mode default or tree-sitter.
|
|
@@ -45,8 +50,19 @@ Options:
|
|
|
45
50
|
--code-report-section <section> With --code-report, print one section: coverage, ownership, languages, parsers, workspaces, workspace-graph, routes, hotspots, configs, or edges.
|
|
46
51
|
--code-impact <term> Show file, symbol, route, import, and edge impact evidence for a term.
|
|
47
52
|
--code-search-symbol <term> Search indexed symbols.
|
|
53
|
+
|
|
54
|
+
Commands:
|
|
55
|
+
mcp Run the stdio MCP server exposing answer-shaped code-evidence tools (code_impact, code_ownership, code_workspace_graph, code_search, code_status) over the existing .project-wiki index.
|
|
56
|
+
|
|
48
57
|
--help Show this help.`);
|
|
49
58
|
}
|
|
59
|
+
// console.log queues asynchronously on pipes; an immediate process.exit() discards
|
|
60
|
+
// anything past the first ~64KB pipe chunk (observed truncating a large
|
|
61
|
+
// --code-report on an 11k-file repo). Exiting from a zero-length write callback
|
|
62
|
+
// guarantees everything queued before it has drained.
|
|
63
|
+
function exitAfterStdoutDrain(code) {
|
|
64
|
+
process.stdout.write("", () => process.exit(code));
|
|
65
|
+
}
|
|
50
66
|
if (args_1.helpMode) {
|
|
51
67
|
printUsage();
|
|
52
68
|
process.exit(0);
|
|
@@ -87,6 +103,10 @@ if (args_1.codeIndexIncrementalMode && !args_1.codeIndexMode) {
|
|
|
87
103
|
console.error("--incremental is only supported with --code-index.");
|
|
88
104
|
process.exit(1);
|
|
89
105
|
}
|
|
106
|
+
if (args_1.acknowledgeSmallRepoMode && !args_1.codeIndexMode) {
|
|
107
|
+
console.error("--acknowledge-small-repo is only supported with --code-index.");
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
90
110
|
if (args_1.codeIndexFullMode && !args_1.codeIndexMode) {
|
|
91
111
|
console.error("--code-index-full is only supported with --code-index.");
|
|
92
112
|
process.exit(1);
|
|
@@ -103,144 +123,216 @@ if (args_1.command === "install-skill") {
|
|
|
103
123
|
(0, install_skill_1.runInstallSkillMode)();
|
|
104
124
|
process.exit(0);
|
|
105
125
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
process.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
if (args_1.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
if (args_1.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
(
|
|
180
|
-
(0,
|
|
181
|
-
(0
|
|
182
|
-
|
|
183
|
-
(
|
|
184
|
-
(0,
|
|
185
|
-
(0
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
(0
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
results
|
|
213
|
-
|
|
214
|
-
results.push(["
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
126
|
+
if (args_1.command === "mcp") {
|
|
127
|
+
// Hand-rolled stdio MCP server over the existing code-evidence index. Lazy
|
|
128
|
+
// require keeps the server (and its node:sqlite dependency) out of the normal
|
|
129
|
+
// bootstrap path. The server roots at process.cwd() and runs until stdin ends,
|
|
130
|
+
// exiting from inside runMcpServerMode; the init flow below must not run.
|
|
131
|
+
require("./mcp-server").runMcpServerMode();
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
runInitCommand();
|
|
135
|
+
}
|
|
136
|
+
function runInitCommand() {
|
|
137
|
+
const activeCodeModes = [args_1.codeQueryMode, args_1.codeReportMode, args_1.codeStatusMode, args_1.codeFilesMode, args_1.codeImpactMode, args_1.codeSearchSymbolMode, args_1.codeIndexMode].filter(Boolean).length;
|
|
138
|
+
if (activeCodeModes > 1) {
|
|
139
|
+
console.error("Use one code evidence mode at a time: --code-index, --code-query, --code-report, --code-status, --code-files, --code-impact, or --code-search-symbol.");
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
if (args_1.codeQueryMode) {
|
|
143
|
+
codeIndex().runCodeQueryMode();
|
|
144
|
+
exitAfterStdoutDrain(0);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (args_1.codeReportMode) {
|
|
148
|
+
codeIndex().runCodeReportMode();
|
|
149
|
+
exitAfterStdoutDrain(0);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (args_1.codeStatusMode) {
|
|
153
|
+
codeIndex().runCodeStatusMode();
|
|
154
|
+
exitAfterStdoutDrain(0);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (args_1.codeFilesMode) {
|
|
158
|
+
codeIndex().runCodeFilesMode();
|
|
159
|
+
exitAfterStdoutDrain(0);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (args_1.codeImpactMode) {
|
|
163
|
+
codeIndex().runCodeImpactMode();
|
|
164
|
+
exitAfterStdoutDrain(0);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (args_1.codeSearchSymbolMode) {
|
|
168
|
+
codeIndex().runCodeSearchSymbolMode();
|
|
169
|
+
exitAfterStdoutDrain(0);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (args_1.codeIndexMode) {
|
|
173
|
+
codeIndex().runCodeIndexMode();
|
|
174
|
+
process.exit(0);
|
|
175
|
+
}
|
|
176
|
+
if (args_1.wikiImpactMode) {
|
|
177
|
+
(0, modes_1.runWikiImpactMode)();
|
|
178
|
+
exitAfterStdoutDrain(0);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (args_1.queryTerm) {
|
|
182
|
+
(0, modes_1.runQueryMode)();
|
|
183
|
+
exitAfterStdoutDrain(0);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (args_1.issueCreateMode) {
|
|
187
|
+
(0, modes_1.runIssueCreateMode)();
|
|
188
|
+
process.exit(0);
|
|
189
|
+
}
|
|
190
|
+
if (args_1.issueDraftMode) {
|
|
191
|
+
(0, modes_1.runIssueDraftMode)();
|
|
192
|
+
exitAfterStdoutDrain(0);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (args_1.pruneCheckMode) {
|
|
196
|
+
(0, modes_1.runPruneCheckMode)();
|
|
197
|
+
process.exit(0);
|
|
198
|
+
}
|
|
199
|
+
if (args_1.reviewMigrationMode) {
|
|
200
|
+
(0, migration_1.runReviewMigrationMode)();
|
|
201
|
+
process.exit(0);
|
|
202
|
+
}
|
|
203
|
+
if (args_1.migrationDoctorMode) {
|
|
204
|
+
(0, modes_1.runMigrationDoctorMode)();
|
|
205
|
+
process.exit(0);
|
|
206
|
+
}
|
|
207
|
+
if (args_1.migrationQualityCheckMode) {
|
|
208
|
+
(0, modes_1.runMigrationQualityCheckMode)();
|
|
209
|
+
process.exit(0);
|
|
210
|
+
}
|
|
211
|
+
if (args_1.migrationLintMode) {
|
|
212
|
+
(0, modes_1.runMigrationLintMode)();
|
|
213
|
+
process.exit(0);
|
|
214
|
+
}
|
|
215
|
+
if (args_1.doctorMode) {
|
|
216
|
+
(0, modes_1.runDoctorMode)(args_1.fixMode);
|
|
217
|
+
process.exit(0);
|
|
218
|
+
}
|
|
219
|
+
if (args_1.linkCheckMode) {
|
|
220
|
+
(0, modes_1.runLinkCheckMode)();
|
|
221
|
+
process.exit(0);
|
|
222
|
+
}
|
|
223
|
+
if (args_1.qualityCheckMode) {
|
|
224
|
+
(0, modes_1.runQualityCheckMode)();
|
|
225
|
+
process.exit(0);
|
|
226
|
+
}
|
|
227
|
+
if (args_1.lintMode) {
|
|
228
|
+
(0, modes_1.runLintMode)();
|
|
229
|
+
process.exit(0);
|
|
230
|
+
}
|
|
231
|
+
const migrationState = args_1.migrateMode ? (0, migration_1.prepareMigrationMode)() : null;
|
|
232
|
+
const results = [];
|
|
233
|
+
if (migrationState)
|
|
234
|
+
results.push(["migration prepare", migrationState.note]);
|
|
235
|
+
(0, workspace_1.mkdirp)("wiki/canonical");
|
|
236
|
+
(0, workspace_1.mkdirp)("wiki/decisions");
|
|
237
|
+
(0, workspace_1.mkdirp)("wiki/inbox");
|
|
238
|
+
(0, workspace_1.mkdirp)("wiki/meta");
|
|
239
|
+
(0, workspace_1.mkdirp)("wiki/sources");
|
|
240
|
+
(0, workspace_1.mkdirp)(".codex/hooks");
|
|
241
|
+
(0, workspace_1.mkdirp)(".claude/hooks");
|
|
242
|
+
(0, workspace_1.mkdirp)(".cursor/hooks");
|
|
243
|
+
(0, workspace_1.mkdirp)(".cursor/rules");
|
|
244
|
+
(0, workspace_1.mkdirp)(".gemini/hooks");
|
|
245
|
+
(0, workspace_1.mkdirp)(".githooks");
|
|
246
|
+
// B1 fallback: sync the CURRENT startup.md TL;DR into the managed AGENTS.md block
|
|
247
|
+
// so non-interactive `codex exec` (which does not run SessionStart hooks) still
|
|
248
|
+
// gets compact startup context. Routers are starter files written later in this
|
|
249
|
+
// flow, so on a fresh bootstrap startup.md does not exist yet; fall back to the
|
|
250
|
+
// template TL;DR that bootstrap is about to write. A missing "## TL;DR" section in
|
|
251
|
+
// an existing startup.md fails loudly inside extractStartupTldr (no fallback).
|
|
252
|
+
const startupForSync = (0, workspace_1.exists)("wiki/startup.md") ? (0, workspace_1.read)("wiki/startup.md") : templates_1.startup;
|
|
253
|
+
const startupTldrForAgents = (0, templates_1.extractStartupTldr)(startupForSync);
|
|
254
|
+
results.push(["AGENTS.md", (0, workspace_1.upsertMarkedSection)("AGENTS.md", "<!-- PROJECT-WIKI-FIRST:START -->", "<!-- PROJECT-WIKI-FIRST:END -->", (0, templates_1.agentsSection)(startupTldrForAgents))]);
|
|
255
|
+
results.push(["CLAUDE.md", (0, workspace_1.upsertMarkedSection)("CLAUDE.md", "<!-- PROJECT-WIKI-CLAUDE:START -->", "<!-- PROJECT-WIKI-CLAUDE:END -->", templates_1.claudeSection)]);
|
|
256
|
+
results.push(["GEMINI.md", (0, workspace_1.upsertMarkedSection)("GEMINI.md", "<!-- PROJECT-WIKI-GEMINI:START -->", "<!-- PROJECT-WIKI-GEMINI:END -->", templates_1.geminiSection)]);
|
|
257
|
+
results.push([".cursor/rules/project-librarian.mdc", (0, workspace_1.writeManaged)(".cursor/rules/project-librarian.mdc", templates_1.cursorRule)]);
|
|
258
|
+
results.push(["wiki/AGENTS.md", (0, workspace_1.upsertMarkedSection)("wiki/AGENTS.md", "<!-- PROJECT-WIKI-INTERNAL:START -->", "<!-- PROJECT-WIKI-INTERNAL:END -->", templates_1.wikiAgentsSection)]);
|
|
259
|
+
results.push([".githooks/prepare-commit-msg", (0, workspace_1.writeManaged)(".githooks/prepare-commit-msg", hooks_1.gitPrepareCommitMsgHook)]);
|
|
260
|
+
(0, workspace_1.makeExecutable)(".githooks/prepare-commit-msg");
|
|
261
|
+
results.push([".githooks/wiki-commit-trailers.js", (0, workspace_1.writeManaged)(".githooks/wiki-commit-trailers.js", hooks_1.gitWikiCommitTrailersScript)]);
|
|
262
|
+
(0, workspace_1.makeExecutable)(".githooks/wiki-commit-trailers.js");
|
|
263
|
+
results.push(["git core.hooksPath", (0, hooks_1.upsertGitHooksPath)()]);
|
|
264
|
+
results.push([".codex/hooks.json", (0, hooks_1.upsertHookConfig)()]);
|
|
265
|
+
results.push([".codex/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".codex/hooks/wiki-session-start.js", hooks_1.hookScript)]);
|
|
266
|
+
results.push([".claude/settings.json", (0, hooks_1.upsertClaudeHookConfig)()]);
|
|
267
|
+
results.push([".claude/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".claude/hooks/wiki-session-start.js", hooks_1.hookScript)]);
|
|
268
|
+
results.push([".cursor/hooks.json", (0, hooks_1.upsertCursorHookConfig)()]);
|
|
269
|
+
results.push([".cursor/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".cursor/hooks/wiki-session-start.js", hooks_1.cursorHookScript)]);
|
|
270
|
+
results.push([".gemini/settings.json", (0, hooks_1.upsertGeminiHookConfig)()]);
|
|
271
|
+
results.push([".gemini/hooks/wiki-session-start.js", (0, workspace_1.writeManaged)(".gemini/hooks/wiki-session-start.js", hooks_1.hookScript)]);
|
|
272
|
+
// Bootstrap-managed MCP registration (preservation-first, idempotent). Claude
|
|
273
|
+
// Code reads `.mcp.json`, Cursor reads `.cursor/mcp.json`, and Gemini reads
|
|
274
|
+
// `mcpServers` inside `.gemini/settings.json`. Codex only supports user-level MCP
|
|
275
|
+
// config (`codex mcp add` -> ~/.codex/config.toml), so it is intentionally not
|
|
276
|
+
// registered at project level; the README documents the manual user-level step.
|
|
277
|
+
// Registration is scale-gated (2026-06-12 decision): below the measured
|
|
278
|
+
// file-count threshold with no existing .project-wiki index, the rows report the
|
|
279
|
+
// skip reason instead of writing config; an existing index registers regardless.
|
|
280
|
+
const mcpGate = (0, hooks_1.mcpRegistrationGate)();
|
|
281
|
+
if (mcpGate.register) {
|
|
282
|
+
results.push([".mcp.json", (0, hooks_1.upsertClaudeMcpConfig)()]);
|
|
283
|
+
results.push([".cursor/mcp.json", (0, hooks_1.upsertCursorMcpConfig)()]);
|
|
284
|
+
results.push([".gemini/settings.json mcpServers", (0, hooks_1.upsertGeminiMcpConfig)()]);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
results.push([".mcp.json", mcpGate.reason]);
|
|
288
|
+
results.push([".cursor/mcp.json", mcpGate.reason]);
|
|
289
|
+
results.push([".gemini/settings.json mcpServers", mcpGate.reason]);
|
|
290
|
+
}
|
|
291
|
+
// Routers accumulate user-maintained project state after bootstrap, so they are
|
|
292
|
+
// starter files: templates are written only when the file is absent, never rebuilt.
|
|
293
|
+
results.push(["wiki/startup.md", (0, workspace_1.writeStarter)("wiki/startup.md", templates_1.startup)]);
|
|
294
|
+
results.push(["wiki/index.md", (0, workspace_1.writeStarter)("wiki/index.md", templates_1.index)]);
|
|
295
|
+
results.push(["wiki/meta/operating-model.md", (0, workspace_1.writeManaged)("wiki/meta/operating-model.md", templates_1.wikiOperatingModel)]);
|
|
296
|
+
results.push(["wiki/meta/decision-policy.md", (0, workspace_1.writeManaged)("wiki/meta/decision-policy.md", templates_1.decisionPolicy)]);
|
|
297
|
+
results.push(["wiki/canonical/wiki-operating-model.md", (0, workspace_1.deleteIfGenerated)("wiki/canonical/wiki-operating-model.md", ["# Wiki Operating Model"])]);
|
|
298
|
+
results.push(["wiki/canonical/decision-policy.md", (0, workspace_1.deleteIfGenerated)("wiki/canonical/decision-policy.md", ["# Decision Policy"])]);
|
|
299
|
+
results.push(["wiki/decisions/wiki-v1-decisions.md", (0, workspace_1.deleteIfGenerated)("wiki/decisions/wiki-v1-decisions.md", ["# Wiki v1 Decisions", "# Wiki Operations v1 Decisions"])]);
|
|
300
|
+
for (const [relativePath, content] of Object.entries(templates_1.starterFiles)) {
|
|
301
|
+
if (!templates_1.defaultStarterFilePaths.has(relativePath))
|
|
302
|
+
continue;
|
|
303
|
+
results.push([relativePath, (0, workspace_1.writeStarter)(relativePath, content)]);
|
|
304
|
+
}
|
|
305
|
+
results.push(["wiki/meta/wiki-ops-v1-decisions.md", (0, workspace_1.writeManaged)("wiki/meta/wiki-ops-v1-decisions.md", templates_1.starterFiles["wiki/meta/wiki-ops-v1-decisions.md"])]);
|
|
306
|
+
if (args_1.glossaryMode) {
|
|
307
|
+
results.push(["wiki/canonical/glossary.md", (0, workspace_1.writeStarter)("wiki/canonical/glossary.md", templates_1.glossary)]);
|
|
308
|
+
results.push(["wiki/index.md glossary router", (0, workspace_1.upsertMarkedSection)("wiki/index.md", "<!-- PROJECT-WIKI-GLOSSARY:START -->", "<!-- PROJECT-WIKI-GLOSSARY:END -->", templates_1.glossaryIndexBlock)]);
|
|
309
|
+
}
|
|
310
|
+
if (args_1.captureInboxMode) {
|
|
311
|
+
results.push(["wiki/inbox/project-candidates.md", (0, modes_1.appendCaptureInbox)()]);
|
|
312
|
+
results.push(["wiki/index.md inbox router", (0, workspace_1.upsertMarkedSection)("wiki/index.md", "<!-- PROJECT-WIKI-INBOX:START -->", "<!-- PROJECT-WIKI-INBOX:END -->", templates_1.inboxIndexBlock)]);
|
|
313
|
+
}
|
|
314
|
+
if (args_1.refreshIndexMode) {
|
|
315
|
+
results.push(["wiki/index.md auto-discovered pages", (0, workspace_1.upsertMarkedSection)("wiki/index.md", "<!-- PROJECT-WIKI-AUTO-INDEX:START -->", "<!-- PROJECT-WIKI-AUTO-INDEX:END -->", (0, modes_1.buildRefreshIndexBlock)())]);
|
|
316
|
+
}
|
|
317
|
+
if (args_1.migrateMode && migrationState) {
|
|
318
|
+
const migration = (0, migration_1.runMigrationMode)(migrationState);
|
|
319
|
+
for (const result of migration.results)
|
|
320
|
+
results.push(result);
|
|
321
|
+
results.push(["migration summary", `${migration.total} files from ${migration.legacyPath || "no legacy"}`]);
|
|
322
|
+
}
|
|
323
|
+
const modes = [];
|
|
324
|
+
if (args_1.migrateMode)
|
|
325
|
+
modes.push("migration");
|
|
326
|
+
if (args_1.glossaryMode)
|
|
327
|
+
modes.push("glossary");
|
|
328
|
+
if (args_1.captureInboxMode)
|
|
329
|
+
modes.push("capture-inbox");
|
|
330
|
+
if (args_1.refreshIndexMode)
|
|
331
|
+
modes.push("refresh-index");
|
|
332
|
+
if (args_1.noGitConfigMode)
|
|
333
|
+
modes.push("no-git-config");
|
|
334
|
+
console.log(modes.length > 0 ? `Project Librarian + ${modes.join(" + ")} complete.` : "Project Librarian complete.");
|
|
335
|
+
for (const [relativePath, status] of results) {
|
|
336
|
+
console.log(`${String(status).padEnd(7)} ${relativePath}`);
|
|
337
|
+
}
|
|
246
338
|
}
|
package/dist/install-skill.js
CHANGED
|
@@ -39,13 +39,12 @@ const os = __importStar(require("node:os"));
|
|
|
39
39
|
const path = __importStar(require("node:path"));
|
|
40
40
|
const args_1 = require("./args");
|
|
41
41
|
const skillName = "project-librarian";
|
|
42
|
+
const allAgentTargets = ["codex", "claude", "cursor", "gemini"];
|
|
42
43
|
const packageFiles = [
|
|
43
44
|
"SKILL.md",
|
|
44
45
|
"dist",
|
|
45
46
|
"README.md",
|
|
46
47
|
"README.ko.md",
|
|
47
|
-
"README.ja.md",
|
|
48
|
-
"README.zh.md",
|
|
49
48
|
"LICENSE",
|
|
50
49
|
"package.json",
|
|
51
50
|
"agents",
|
|
@@ -61,19 +60,19 @@ function installScope() {
|
|
|
61
60
|
return fail(`invalid --scope: ${scope}; expected user or project`);
|
|
62
61
|
}
|
|
63
62
|
function installAgents() {
|
|
64
|
-
const value = (0, args_1.argValue)("--agents") || "
|
|
63
|
+
const value = (0, args_1.argValue)("--agents") || "all";
|
|
65
64
|
const parts = value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
66
65
|
const agents = new Set();
|
|
67
66
|
for (const part of parts) {
|
|
68
|
-
if (part === "
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
if (part === "all") {
|
|
68
|
+
for (const agent of allAgentTargets)
|
|
69
|
+
agents.add(agent);
|
|
71
70
|
}
|
|
72
|
-
else if (part
|
|
71
|
+
else if (allAgentTargets.includes(part)) {
|
|
73
72
|
agents.add(part);
|
|
74
73
|
}
|
|
75
74
|
else {
|
|
76
|
-
return fail(`invalid --agents entry: ${part}; expected codex, claude, or
|
|
75
|
+
return fail(`invalid --agents entry: ${part}; expected codex, claude, cursor, gemini, or all`);
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
78
|
return Array.from(agents);
|
|
@@ -85,10 +84,23 @@ function userAgentRoot(agent) {
|
|
|
85
84
|
const home = os.homedir();
|
|
86
85
|
if (agent === "codex")
|
|
87
86
|
return process.env.CODEX_HOME || path.join(home, ".codex");
|
|
88
|
-
|
|
87
|
+
if (agent === "claude")
|
|
88
|
+
return process.env.CLAUDE_HOME || path.join(home, ".claude");
|
|
89
|
+
if (agent === "cursor")
|
|
90
|
+
return process.env.CURSOR_HOME || path.join(home, ".cursor");
|
|
91
|
+
return process.env.GEMINI_HOME || path.join(home, ".gemini");
|
|
92
|
+
}
|
|
93
|
+
function projectAgentRoot(agent) {
|
|
94
|
+
if (agent === "codex")
|
|
95
|
+
return ".codex";
|
|
96
|
+
if (agent === "claude")
|
|
97
|
+
return ".claude";
|
|
98
|
+
if (agent === "cursor")
|
|
99
|
+
return ".cursor";
|
|
100
|
+
return ".gemini";
|
|
89
101
|
}
|
|
90
102
|
function installTarget(agent, scope) {
|
|
91
|
-
const base = scope === "user" ? userAgentRoot(agent) : path.join(process.cwd(), agent
|
|
103
|
+
const base = scope === "user" ? userAgentRoot(agent) : path.join(process.cwd(), projectAgentRoot(agent));
|
|
92
104
|
return path.join(base, "skills", skillName);
|
|
93
105
|
}
|
|
94
106
|
function sameFile(source, target) {
|
|
@@ -134,8 +146,8 @@ function runInstallSkillMode() {
|
|
|
134
146
|
console.log(`Project Librarian skill ${dryRun ? "install dry-run" : "install"} complete.`);
|
|
135
147
|
console.log(`scope: ${scope}`);
|
|
136
148
|
console.log(`agents: ${agents.join(", ")}`);
|
|
137
|
-
console.log("note: install-skill only installs the reusable skill files; it does not create or update AGENTS.md, CLAUDE.md, wiki/, .codex/hooks.json, or .claude/settings.json.");
|
|
138
|
-
console.log("next:
|
|
149
|
+
console.log("note: install-skill only installs the reusable skill files; it does not create or update AGENTS.md, CLAUDE.md, GEMINI.md, wiki/, .cursor/rules/, .cursor/hooks.json, .gemini/settings.json, .codex/hooks.json, or .claude/settings.json.");
|
|
150
|
+
console.log("next: ask your agent to use Project Librarian from the target project root; the installed skill resolves the local runner.");
|
|
139
151
|
for (const [label, status] of rows) {
|
|
140
152
|
console.log(`${status.padEnd(7)} ${label}`);
|
|
141
153
|
}
|