@fenglimg/fabric-cli 2.2.0 → 2.3.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/audit-PURSJJFH.js +734 -0
- package/dist/{chunk-QPAW6IYT.js → chunk-7V4XMLQ2.js} +3 -3
- package/dist/{chunk-7ZDXBOOU.js → chunk-ACSMNX3V.js} +44 -128
- package/dist/{chunk-PTGQAZEW.js → chunk-GGDVZCD6.js} +2 -4
- package/dist/{chunk-EOT63RDH.js → chunk-I5F5BHWI.js} +9 -0
- package/dist/chunk-PP7QVRXH.js +565 -0
- package/dist/chunk-SL77FXX7.js +54 -0
- package/dist/{chunk-3D7B2UAZ.js → chunk-VQKXTMWH.js} +44 -4
- package/dist/doctor-S6KPGS35.js +27 -0
- package/dist/index.js +90 -80
- package/dist/{info-7FKBTMVO.js → info-NJEY26H6.js} +91 -46
- package/dist/{context-UJCGYOT6.js → inspect-5YZMJPFM.js} +10 -10
- package/dist/{install-v2-3KJX3YRO.js → install-v2-KGIDII4H.js} +163 -364
- package/dist/{store-HOCORVL3.js → store-GF4SFBMJ.js} +155 -57
- package/dist/{sync-DT5UJMMR.js → sync-3XCIRDPK.js} +3 -4
- package/dist/{uninstall-IFN2KYBK.js → uninstall-BG4ML4FC.js} +39 -10
- package/package.json +3 -7
- package/templates/hooks/cite-policy-evict.cjs +1 -1
- package/templates/hooks/configs/claude-code.json +1 -5
- package/templates/hooks/configs/codex-hooks.json +1 -5
- package/templates/hooks/fabric-hint.cjs +67 -41
- package/templates/hooks/knowledge-hint-broad.cjs +82 -24
- package/templates/hooks/knowledge-hint-narrow.cjs +3 -3
- package/templates/hooks/knowledge-pretooluse.cjs +111 -0
- package/templates/hooks/lib/banner-i18n.cjs +12 -11
- package/templates/hooks/lib/bindings-snapshot-reader.cjs +1 -1
- package/templates/hooks/lib/event-writer.cjs +79 -0
- package/templates/hooks/lib/nudge-policy.cjs +11 -0
- package/templates/hooks/lib/theme.cjs +62 -0
- package/templates/hooks/post-tooluse-mutation.cjs +28 -39
- package/templates/skills/fabric-archive/SKILL.md +29 -12
- package/templates/skills/fabric-archive/ref/dry-run-scope.md +1 -1
- package/templates/skills/fabric-archive/ref/i18n-policy.md +1 -1
- package/templates/skills/fabric-archive/ref/phase-1-5-onboard.md +5 -5
- package/templates/skills/fabric-archive/ref/phase-1-cross-session.md +2 -2
- package/templates/skills/fabric-archive/ref/phase-2-5-viability.md +1 -1
- package/templates/skills/fabric-archive/ref/phase-3-5-scope.md +1 -1
- package/templates/skills/fabric-archive/ref/phase-3-6-related-edges.md +1 -1
- package/templates/skills/fabric-archive/ref/phase-3-classify.md +1 -1
- package/templates/skills/fabric-archive/ref/phase-4-5-emit.md +1 -1
- package/templates/skills/fabric-archive/ref/phase-4-mcp-persist.md +6 -5
- package/templates/skills/{fabric-import/ref/checkpoint-state.md → fabric-archive/ref/source-checkpoint.md} +3 -3
- package/templates/skills/{fabric-import/ref/phase-3-dedup.md → fabric-archive/ref/source-dedup.md} +4 -4
- package/templates/skills/{fabric-import/ref/phase-2-mining.md → fabric-archive/ref/source-mining.md} +20 -20
- package/templates/skills/{fabric-import/ref/output-contract.md → fabric-archive/ref/source-output-contract.md} +3 -3
- package/templates/skills/{fabric-import/ref/state-recovery.md → fabric-archive/ref/source-state-recovery.md} +2 -2
- package/templates/skills/{fabric-import/ref/worked-examples.md → fabric-archive/ref/source-worked-examples.md} +10 -10
- package/templates/skills/fabric-archive/ref/worked-examples.md +3 -3
- package/templates/skills/fabric-review/SKILL.md +19 -15
- package/templates/skills/fabric-review/ref/cite-contract.md +2 -2
- package/templates/skills/fabric-review/ref/modify-flow.md +13 -1
- package/templates/skills/fabric-review/ref/per-mode-flows.md +5 -5
- package/templates/skills/fabric-review/ref/relate-mode.md +33 -0
- package/templates/skills/fabric-review/ref/retire-mode.md +47 -0
- package/templates/skills/fabric-review/ref/semantic-check.md +1 -1
- package/templates/skills/fabric-review/ref/worked-examples.md +5 -5
- package/templates/skills/fabric-store/SKILL.md +12 -27
- package/templates/skills/fabric-sync/SKILL.md +16 -35
- package/templates/skills/lib/shared-policy.md +6 -4
- package/dist/chunk-27HK6H5Y.js +0 -69
- package/dist/chunk-E7HJUU34.js +0 -1096
- package/dist/chunk-NLNH64A3.js +0 -43
- package/dist/chunk-QFIVFZRH.js +0 -13
- package/dist/doctor-MDTZWKBK.js +0 -24
- package/dist/metrics-HMFH4YHK.js +0 -135
- package/dist/scope-explain-HLJZ2M33.js +0 -48
- package/dist/status-4R3TM4FJ.js +0 -37
- package/dist/whoami-ITGEFWH4.js +0 -49
- package/templates/skills/fabric/SKILL.md +0 -100
- package/templates/skills/fabric-audit/SKILL.md +0 -63
- package/templates/skills/fabric-connect/SKILL.md +0 -48
- package/templates/skills/fabric-import/SKILL.md +0 -151
- package/templates/skills/fabric-import/ref/i18n-policy.md +0 -78
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
regenerateBindingsSnapshot
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-EOT63RDH.js";
|
|
4
|
+
} from "./chunk-GGDVZCD6.js";
|
|
6
5
|
import {
|
|
7
6
|
assertStoreMountable,
|
|
8
7
|
resolveStoreDir,
|
|
@@ -17,16 +16,17 @@ import {
|
|
|
17
16
|
storeRemove,
|
|
18
17
|
storeSetWriteRoute,
|
|
19
18
|
storeSwitchWrite
|
|
20
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-7V4XMLQ2.js";
|
|
21
20
|
import {
|
|
22
21
|
loadProjectConfig
|
|
23
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-I5F5BHWI.js";
|
|
24
23
|
import "./chunk-FNHDQTPC.js";
|
|
25
24
|
import {
|
|
26
25
|
getProjectTranslator
|
|
27
26
|
} from "./chunk-HORSMSZL.js";
|
|
28
27
|
|
|
29
28
|
// src/commands/store.ts
|
|
29
|
+
import { confirm, isCancel } from "@clack/prompts";
|
|
30
30
|
import { defineCommand } from "citty";
|
|
31
31
|
import { join as join3 } from "path";
|
|
32
32
|
|
|
@@ -220,6 +220,47 @@ import {
|
|
|
220
220
|
loadGlobalConfig,
|
|
221
221
|
resolveGlobalRoot
|
|
222
222
|
} from "@fenglimg/fabric-shared";
|
|
223
|
+
async function resolveStoreMutationConsent(opts) {
|
|
224
|
+
if (opts.yes || process.env.FABRIC_NONINTERACTIVE === "1") {
|
|
225
|
+
return "proceed";
|
|
226
|
+
}
|
|
227
|
+
if (process.stdin.isTTY !== true) {
|
|
228
|
+
console.error(
|
|
229
|
+
`store ${opts.label}: stdin is not a TTY and neither --yes nor FABRIC_NONINTERACTIVE=1 is set. Refusing to mutate.`
|
|
230
|
+
);
|
|
231
|
+
return "abort";
|
|
232
|
+
}
|
|
233
|
+
const answer = await confirm({
|
|
234
|
+
message: `About to rewrite ${opts.count} knowledge entr${opts.count === 1 ? "y" : "ies"} (store ${opts.label}). Proceed?`,
|
|
235
|
+
initialValue: false
|
|
236
|
+
});
|
|
237
|
+
if (isCancel(answer) || answer !== true) {
|
|
238
|
+
console.error(`store ${opts.label}: aborted by user.`);
|
|
239
|
+
return "abort";
|
|
240
|
+
}
|
|
241
|
+
return "proceed";
|
|
242
|
+
}
|
|
243
|
+
async function runGatedMigrate(opts) {
|
|
244
|
+
if (opts.dryRun) {
|
|
245
|
+
opts.print(await opts.run(true));
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const preview = await opts.run(true);
|
|
249
|
+
if (preview.changes.length === 0) {
|
|
250
|
+
opts.print(preview);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const decision = await resolveStoreMutationConsent({
|
|
254
|
+
label: opts.label,
|
|
255
|
+
count: preview.changes.length,
|
|
256
|
+
yes: opts.yes
|
|
257
|
+
});
|
|
258
|
+
if (decision === "abort") {
|
|
259
|
+
process.exitCode = 1;
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
opts.print(await opts.run(false));
|
|
263
|
+
}
|
|
223
264
|
var listCommand = defineCommand({
|
|
224
265
|
meta: { name: "list", description: "List mounted knowledge stores" },
|
|
225
266
|
run() {
|
|
@@ -230,16 +271,24 @@ var listCommand = defineCommand({
|
|
|
230
271
|
return;
|
|
231
272
|
}
|
|
232
273
|
const localOnly = t("cli.shared.local-only");
|
|
233
|
-
|
|
234
|
-
|
|
274
|
+
const rows = stores.map((store) => ({
|
|
275
|
+
alias: store.alias,
|
|
276
|
+
name: store.mount_name ?? store.store_uuid,
|
|
277
|
+
uuid: store.store_uuid,
|
|
278
|
+
remote: storeGitRemote(store.alias) ?? localOnly
|
|
279
|
+
}));
|
|
280
|
+
const aliasW = Math.max(...rows.map((r) => r.alias.length));
|
|
281
|
+
const nameW = Math.max(...rows.map((r) => r.name.length));
|
|
282
|
+
const uuidW = Math.max(...rows.map((r) => r.uuid.length));
|
|
283
|
+
for (const r of rows) {
|
|
235
284
|
console.log(
|
|
236
|
-
`${
|
|
285
|
+
`${r.alias.padEnd(aliasW)} ${r.name.padEnd(nameW)} ${r.uuid.padEnd(uuidW)} ${r.remote}`
|
|
237
286
|
);
|
|
238
287
|
}
|
|
239
288
|
}
|
|
240
289
|
});
|
|
241
|
-
var
|
|
242
|
-
meta: { name: "
|
|
290
|
+
var mountCommand = defineCommand({
|
|
291
|
+
meta: { name: "mount", description: "Mount a knowledge store into the global registry" },
|
|
243
292
|
args: {
|
|
244
293
|
uuid: { type: "string", required: true, description: "Intrinsic store UUID" },
|
|
245
294
|
alias: { type: "string", required: true, description: "Local alias for this store" },
|
|
@@ -346,29 +395,35 @@ var bindCommand = defineCommand({
|
|
|
346
395
|
}
|
|
347
396
|
});
|
|
348
397
|
var switchWriteCommand = defineCommand({
|
|
349
|
-
meta: {
|
|
398
|
+
meta: {
|
|
399
|
+
name: "switch-write",
|
|
400
|
+
description: "Set the default write store, or route one semantic scope with --scope"
|
|
401
|
+
},
|
|
350
402
|
args: {
|
|
351
|
-
alias: { type: "positional", required: true, description: "Alias of the store to write to" }
|
|
403
|
+
alias: { type: "positional", required: true, description: "Alias of the store to write to" },
|
|
404
|
+
scope: {
|
|
405
|
+
type: "string",
|
|
406
|
+
description: "Route only this semantic scope (e.g. team or project:fabric-v2) to the store"
|
|
407
|
+
}
|
|
352
408
|
},
|
|
353
409
|
async run({ args }) {
|
|
354
410
|
const projectRoot = process.cwd();
|
|
411
|
+
if (typeof args.scope === "string" && args.scope.length > 0) {
|
|
412
|
+
storeSetWriteRoute(projectRoot, args.scope, args.alias);
|
|
413
|
+
regenerateBindingsSnapshot(projectRoot, { now: (/* @__PURE__ */ new Date()).toISOString() });
|
|
414
|
+
console.log(
|
|
415
|
+
getProjectTranslator(projectRoot)("cli.store.routed", {
|
|
416
|
+
scope: args.scope,
|
|
417
|
+
alias: args.alias
|
|
418
|
+
})
|
|
419
|
+
);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
355
422
|
storeSwitchWrite(projectRoot, args.alias);
|
|
356
423
|
regenerateBindingsSnapshot(projectRoot, { now: (/* @__PURE__ */ new Date()).toISOString() });
|
|
357
424
|
console.log(getProjectTranslator(projectRoot)("cli.store.switch-write", { alias: args.alias }));
|
|
358
425
|
}
|
|
359
426
|
});
|
|
360
|
-
var routeWriteCommand = defineCommand({
|
|
361
|
-
meta: { name: "route-write", description: "Route a semantic scope to a writable shared store" },
|
|
362
|
-
args: {
|
|
363
|
-
scope: { type: "positional", required: true, description: "Semantic scope, e.g. team or project:fabric-v2" },
|
|
364
|
-
alias: { type: "positional", required: true, description: "Alias of the shared store to write to" }
|
|
365
|
-
},
|
|
366
|
-
run({ args }) {
|
|
367
|
-
const projectRoot = process.cwd();
|
|
368
|
-
storeSetWriteRoute(projectRoot, args.scope, args.alias);
|
|
369
|
-
console.log(`write route: ${args.scope} -> ${args.alias}`);
|
|
370
|
-
}
|
|
371
|
-
});
|
|
372
427
|
var projectListCommand = defineCommand({
|
|
373
428
|
meta: { name: "list", description: "List projects registered in a store" },
|
|
374
429
|
args: {
|
|
@@ -408,14 +463,15 @@ var projectCommand = defineCommand({
|
|
|
408
463
|
});
|
|
409
464
|
var backfillScopeCommand = defineCommand({
|
|
410
465
|
meta: {
|
|
411
|
-
name: "backfill
|
|
466
|
+
name: "backfill",
|
|
412
467
|
description: "Backfill semantic_scope + visibility_store on existing knowledge (repairs dirty layer)"
|
|
413
468
|
},
|
|
414
469
|
args: {
|
|
415
470
|
store: { type: "string", description: "Backfill a mounted store's knowledge" },
|
|
416
|
-
"dry-run": { type: "boolean", description: "Preview changes without writing" }
|
|
471
|
+
"dry-run": { type: "boolean", description: "Preview changes without writing" },
|
|
472
|
+
yes: { type: "boolean", description: "Skip the confirm-before-mutate prompt (CI / non-interactive)" }
|
|
417
473
|
},
|
|
418
|
-
run({ args }) {
|
|
474
|
+
async run({ args }) {
|
|
419
475
|
const dryRun = args["dry-run"] === true;
|
|
420
476
|
let knowledgeDir;
|
|
421
477
|
let visibilityStore;
|
|
@@ -437,23 +493,43 @@ var backfillScopeCommand = defineCommand({
|
|
|
437
493
|
knowledgeDir = join3(storeDir, STORE_LAYOUT2.knowledgeDir);
|
|
438
494
|
visibilityStore = selectedStore;
|
|
439
495
|
}
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
496
|
+
const printReport = (report, preview2) => {
|
|
497
|
+
if (report.changes.length === 0) {
|
|
498
|
+
console.log(`scope backfill: nothing to do (${report.unchanged} already consistent).`);
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
console.log(
|
|
502
|
+
`${preview2 ? "[dry-run] " : ""}scope backfill: ${report.changes.length} entr${report.changes.length === 1 ? "y" : "ies"} updated, ${report.unchanged} unchanged.`
|
|
503
|
+
);
|
|
504
|
+
for (const c of report.changes) {
|
|
505
|
+
console.log(` ${c.id ?? "(no id)"} [${c.changed.join(", ")}]`);
|
|
506
|
+
}
|
|
507
|
+
const scopeAssigned = report.changes.filter((c) => c.changed.includes("semantic_scope")).length;
|
|
508
|
+
if (scopeAssigned > 0) {
|
|
509
|
+
console.error(
|
|
510
|
+
`${preview2 ? "[dry-run] " : ""}note: ${scopeAssigned} entr${scopeAssigned === 1 ? "y" : "ies"} defaulted to semantic_scope: team. Demote project-specific ones with \`fabric store migrate scope <store> --to project:<id> --id <id>\`.`
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
if (dryRun) {
|
|
515
|
+
printReport(backfillKnowledgeDir(knowledgeDir, { visibilityStore, dryRun: true }), true);
|
|
443
516
|
return;
|
|
444
517
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
console.log(` ${c.id ?? "(no id)"} [${c.changed.join(", ")}]`);
|
|
518
|
+
const preview = backfillKnowledgeDir(knowledgeDir, { visibilityStore, dryRun: true });
|
|
519
|
+
if (preview.changes.length === 0) {
|
|
520
|
+
printReport(preview, false);
|
|
521
|
+
return;
|
|
450
522
|
}
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
523
|
+
const decision = await resolveStoreMutationConsent({
|
|
524
|
+
label: "migrate backfill",
|
|
525
|
+
count: preview.changes.length,
|
|
526
|
+
yes: args.yes === true
|
|
527
|
+
});
|
|
528
|
+
if (decision === "abort") {
|
|
529
|
+
process.exitCode = 1;
|
|
530
|
+
return;
|
|
456
531
|
}
|
|
532
|
+
printReport(backfillKnowledgeDir(knowledgeDir, { visibilityStore, dryRun: false }), false);
|
|
457
533
|
}
|
|
458
534
|
});
|
|
459
535
|
function resolveStoreDirAndVisibility(aliasOrUuid) {
|
|
@@ -488,7 +564,7 @@ function printRescopeReport(report) {
|
|
|
488
564
|
}
|
|
489
565
|
var rescopeCommand = defineCommand({
|
|
490
566
|
meta: {
|
|
491
|
-
name: "
|
|
567
|
+
name: "scope",
|
|
492
568
|
description: "Rewrite knowledge entries' semantic_scope coordinate in a store"
|
|
493
569
|
},
|
|
494
570
|
args: {
|
|
@@ -496,7 +572,8 @@ var rescopeCommand = defineCommand({
|
|
|
496
572
|
to: { type: "string", required: true, description: "New semantic_scope (e.g. team, project:alpha)" },
|
|
497
573
|
id: { type: "string", description: "Only the entry with this stable_id" },
|
|
498
574
|
from: { type: "string", description: "Only entries currently at this semantic_scope" },
|
|
499
|
-
"dry-run": { type: "boolean", description: "Preview changes without writing" }
|
|
575
|
+
"dry-run": { type: "boolean", description: "Preview changes without writing" },
|
|
576
|
+
yes: { type: "boolean", description: "Skip the confirm-before-mutate prompt (CI / non-interactive)" }
|
|
500
577
|
},
|
|
501
578
|
async run({ args }) {
|
|
502
579
|
const resolved = resolveStoreDirAndVisibility(args.store);
|
|
@@ -505,14 +582,18 @@ var rescopeCommand = defineCommand({
|
|
|
505
582
|
process.exitCode = 1;
|
|
506
583
|
return;
|
|
507
584
|
}
|
|
508
|
-
|
|
509
|
-
|
|
585
|
+
await runGatedMigrate({
|
|
586
|
+
label: "migrate scope",
|
|
587
|
+
dryRun: args["dry-run"] === true,
|
|
588
|
+
yes: args.yes === true,
|
|
589
|
+
run: (dryRun) => rescopeStore(resolved.dir, args.to, {
|
|
510
590
|
id: args.id,
|
|
511
591
|
fromScope: args.from,
|
|
512
592
|
storeVisibility: resolved.visibility,
|
|
513
|
-
dryRun
|
|
514
|
-
})
|
|
515
|
-
|
|
593
|
+
dryRun
|
|
594
|
+
}),
|
|
595
|
+
print: printRescopeReport
|
|
596
|
+
});
|
|
516
597
|
}
|
|
517
598
|
});
|
|
518
599
|
var promoteCommand = defineCommand({
|
|
@@ -523,7 +604,8 @@ var promoteCommand = defineCommand({
|
|
|
523
604
|
args: {
|
|
524
605
|
store: { type: "positional", required: true, description: "Target store alias or uuid" },
|
|
525
606
|
project: { type: "string", description: "Only this project's entries (default: all project:*)" },
|
|
526
|
-
"dry-run": { type: "boolean", description: "Preview changes without writing" }
|
|
607
|
+
"dry-run": { type: "boolean", description: "Preview changes without writing" },
|
|
608
|
+
yes: { type: "boolean", description: "Skip the confirm-before-mutate prompt (CI / non-interactive)" }
|
|
527
609
|
},
|
|
528
610
|
async run({ args }) {
|
|
529
611
|
const resolved = resolveStoreDirAndVisibility(args.store);
|
|
@@ -532,29 +614,45 @@ var promoteCommand = defineCommand({
|
|
|
532
614
|
process.exitCode = 1;
|
|
533
615
|
return;
|
|
534
616
|
}
|
|
535
|
-
|
|
536
|
-
|
|
617
|
+
await runGatedMigrate({
|
|
618
|
+
label: "migrate promote",
|
|
619
|
+
dryRun: args["dry-run"] === true,
|
|
620
|
+
yes: args.yes === true,
|
|
621
|
+
run: (dryRun) => promoteProjectToTeam(resolved.dir, {
|
|
537
622
|
projectId: args.project,
|
|
538
623
|
storeVisibility: resolved.visibility,
|
|
539
|
-
dryRun
|
|
540
|
-
})
|
|
541
|
-
|
|
624
|
+
dryRun
|
|
625
|
+
}),
|
|
626
|
+
print: printRescopeReport
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
var migrateCommand = defineCommand({
|
|
631
|
+
meta: { name: "migrate", description: "Rewrite knowledge entries' scope coordinates in a store" },
|
|
632
|
+
subCommands: {
|
|
633
|
+
scope: rescopeCommand,
|
|
634
|
+
promote: promoteCommand,
|
|
635
|
+
backfill: backfillScopeCommand
|
|
542
636
|
}
|
|
543
637
|
});
|
|
544
638
|
var store_default = defineCommand({
|
|
545
639
|
meta: { name: "store", description: "Manage mounted Fabric knowledge stores" },
|
|
640
|
+
// W3-E: subCommands ordered by value axis — registry (which stores exist) →
|
|
641
|
+
// project wiring (where this repo reads/writes) → knowledge migration →
|
|
642
|
+
// store-internal project registry.
|
|
546
643
|
subCommands: {
|
|
644
|
+
// registry
|
|
645
|
+
mount: mountCommand,
|
|
547
646
|
list: listCommand,
|
|
548
647
|
create: createCommand,
|
|
549
|
-
add: addCommand,
|
|
550
648
|
remove: removeCommand,
|
|
551
649
|
explain: explainCommand,
|
|
650
|
+
// project wiring
|
|
552
651
|
bind: bindCommand,
|
|
553
652
|
"switch-write": switchWriteCommand,
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
promote: promoteCommand,
|
|
653
|
+
// knowledge migration
|
|
654
|
+
migrate: migrateCommand,
|
|
655
|
+
// store-internal projects
|
|
558
656
|
project: projectCommand
|
|
559
657
|
}
|
|
560
658
|
});
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
paint
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SL77FXX7.js";
|
|
5
5
|
import {
|
|
6
6
|
regenerateBindingsSnapshot
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-QFIVFZRH.js";
|
|
7
|
+
} from "./chunk-GGDVZCD6.js";
|
|
8
|
+
import "./chunk-I5F5BHWI.js";
|
|
10
9
|
import {
|
|
11
10
|
loadGlobalConfig,
|
|
12
11
|
resolveGlobalRoot
|
|
@@ -7,18 +7,18 @@ import {
|
|
|
7
7
|
HOOK_SCRIPT_DESTINATIONS,
|
|
8
8
|
SKILL_DESTINATIONS,
|
|
9
9
|
fabricAgentsSnapshotPath
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import {
|
|
12
|
-
createDebugLogger,
|
|
13
|
-
resolveDevMode
|
|
14
|
-
} from "./chunk-WA3DYGSY.js";
|
|
10
|
+
} from "./chunk-ACSMNX3V.js";
|
|
15
11
|
import {
|
|
16
12
|
detectClientSupports,
|
|
17
13
|
resolveClients
|
|
18
14
|
} from "./chunk-3IOLS5EK.js";
|
|
15
|
+
import {
|
|
16
|
+
createDebugLogger,
|
|
17
|
+
resolveDevMode
|
|
18
|
+
} from "./chunk-WA3DYGSY.js";
|
|
19
19
|
import {
|
|
20
20
|
paint
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-SL77FXX7.js";
|
|
22
22
|
import {
|
|
23
23
|
t
|
|
24
24
|
} from "./chunk-HORSMSZL.js";
|
|
@@ -38,7 +38,11 @@ import { dirname, join } from "path";
|
|
|
38
38
|
import { atomicWriteJson, atomicWriteText } from "@fenglimg/fabric-shared/node/atomic-write";
|
|
39
39
|
import { BOOTSTRAP_REGEX } from "@fenglimg/fabric-shared/templates/bootstrap-canonical";
|
|
40
40
|
async function uninstallFabricRouterSkill(projectRoot) {
|
|
41
|
-
return removeSkill(
|
|
41
|
+
return removeSkill(
|
|
42
|
+
"skill-router",
|
|
43
|
+
[".claude/skills/fabric/SKILL.md", ".codex/skills/fabric/SKILL.md"],
|
|
44
|
+
projectRoot
|
|
45
|
+
);
|
|
42
46
|
}
|
|
43
47
|
async function uninstallFabricArchiveSkill(projectRoot) {
|
|
44
48
|
return removeSkill("skill", SKILL_DESTINATIONS.fabricArchive, projectRoot);
|
|
@@ -47,16 +51,28 @@ async function uninstallFabricReviewSkill(projectRoot) {
|
|
|
47
51
|
return removeSkill("skill-review", SKILL_DESTINATIONS.fabricReview, projectRoot);
|
|
48
52
|
}
|
|
49
53
|
async function uninstallFabricImportSkill(projectRoot) {
|
|
50
|
-
return removeSkill(
|
|
54
|
+
return removeSkill(
|
|
55
|
+
"skill-import",
|
|
56
|
+
[".claude/skills/fabric-import/SKILL.md", ".codex/skills/fabric-import/SKILL.md"],
|
|
57
|
+
projectRoot
|
|
58
|
+
);
|
|
51
59
|
}
|
|
52
60
|
async function uninstallFabricSyncSkill(projectRoot) {
|
|
53
61
|
return removeSkill("skill-sync", SKILL_DESTINATIONS.fabricSync, projectRoot);
|
|
54
62
|
}
|
|
55
63
|
async function uninstallFabricAuditSkill(projectRoot) {
|
|
56
|
-
return removeSkill(
|
|
64
|
+
return removeSkill(
|
|
65
|
+
"skill-audit",
|
|
66
|
+
[".claude/skills/fabric-audit/SKILL.md", ".codex/skills/fabric-audit/SKILL.md"],
|
|
67
|
+
projectRoot
|
|
68
|
+
);
|
|
57
69
|
}
|
|
58
70
|
async function uninstallFabricConnectSkill(projectRoot) {
|
|
59
|
-
return removeSkill(
|
|
71
|
+
return removeSkill(
|
|
72
|
+
"skill-connect",
|
|
73
|
+
[".claude/skills/fabric-connect/SKILL.md", ".codex/skills/fabric-connect/SKILL.md"],
|
|
74
|
+
projectRoot
|
|
75
|
+
);
|
|
60
76
|
}
|
|
61
77
|
async function removeSkill(step, rels, projectRoot) {
|
|
62
78
|
const results = [];
|
|
@@ -91,6 +107,13 @@ async function removeCitePolicyEvictHook(projectRoot) {
|
|
|
91
107
|
projectRoot
|
|
92
108
|
);
|
|
93
109
|
}
|
|
110
|
+
async function removeKnowledgePretoolUseHook(projectRoot) {
|
|
111
|
+
return removeHookScripts(
|
|
112
|
+
"hook-pretooluse-script",
|
|
113
|
+
HOOK_SCRIPT_DESTINATIONS.knowledgePretoolUse,
|
|
114
|
+
projectRoot
|
|
115
|
+
);
|
|
116
|
+
}
|
|
94
117
|
async function removeSessionEndMarkerHook(projectRoot) {
|
|
95
118
|
return removeHookScripts(
|
|
96
119
|
"hook-session-end-script",
|
|
@@ -300,6 +323,12 @@ async function uninstallBootstrapStage(projectRoot, _opts = {}) {
|
|
|
300
323
|
projectRoot,
|
|
301
324
|
() => removeCitePolicyEvictHook(projectRoot)
|
|
302
325
|
);
|
|
326
|
+
await runAndCollect(
|
|
327
|
+
results,
|
|
328
|
+
"hook-pretooluse-script",
|
|
329
|
+
projectRoot,
|
|
330
|
+
() => removeKnowledgePretoolUseHook(projectRoot)
|
|
331
|
+
);
|
|
303
332
|
await runAndCollect(
|
|
304
333
|
results,
|
|
305
334
|
"hook-session-end-script",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fenglimg/fabric-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0-rc.1",
|
|
4
4
|
"description": "Fabric CLI — installs the MCP server + skills + hooks for Claude Code and Codex CLI; runs doctor / knowledge maintenance.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "wangzhichao <fenglimg90@gmail.com>",
|
|
@@ -39,19 +39,15 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@clack/prompts": "^1.2.0",
|
|
41
41
|
"citty": "^0.2.2",
|
|
42
|
-
"ink": "^4.4.1",
|
|
43
|
-
"picocolors": "^1.1.1",
|
|
44
|
-
"react": "^18.3.1",
|
|
45
42
|
"string-width": "^7.2.0",
|
|
46
43
|
"tree-sitter-javascript": "^0.25.0",
|
|
47
44
|
"tree-sitter-typescript": "^0.23.2",
|
|
48
45
|
"web-tree-sitter": "^0.26.8",
|
|
49
|
-
"@fenglimg/fabric-server": "2.
|
|
50
|
-
"@fenglimg/fabric-shared": "2.
|
|
46
|
+
"@fenglimg/fabric-server": "2.3.0-rc.1",
|
|
47
|
+
"@fenglimg/fabric-shared": "2.3.0-rc.1"
|
|
51
48
|
},
|
|
52
49
|
"devDependencies": {
|
|
53
50
|
"@types/node": "^22.15.0",
|
|
54
|
-
"@types/react": "^18.3.12",
|
|
55
51
|
"tsup": "^8.5.0",
|
|
56
52
|
"typescript": "^5.8.3"
|
|
57
53
|
},
|
|
@@ -385,7 +385,7 @@ function renderNudge(editPaths) {
|
|
|
385
385
|
`[fabric cite] 改 ${target} 前未检测到相关 fab_recall —`,
|
|
386
386
|
"建议先调 fab_recall(paths=[<被改文件>]) 让系统自动记账引用的 KB(无需手写首行 KB:)。",
|
|
387
387
|
"已 recall 过可忽略本提示。仍可手写首行 `KB: <id> [applied]` 显式 override。",
|
|
388
|
-
"(nudge only — 不阻塞本次编辑;cite 覆盖率见 fabric
|
|
388
|
+
"(nudge only — 不阻塞本次编辑;cite 覆盖率见 fabric audit cite)",
|
|
389
389
|
].join("\n");
|
|
390
390
|
}
|
|
391
391
|
|
|
@@ -28,11 +28,7 @@
|
|
|
28
28
|
"hooks": [
|
|
29
29
|
{
|
|
30
30
|
"type": "command",
|
|
31
|
-
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/knowledge-
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
"type": "command",
|
|
35
|
-
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/cite-policy-evict.cjs"
|
|
31
|
+
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/knowledge-pretooluse.cjs"
|
|
36
32
|
}
|
|
37
33
|
]
|
|
38
34
|
}
|
|
@@ -13,11 +13,7 @@
|
|
|
13
13
|
"PreToolUse": [
|
|
14
14
|
{
|
|
15
15
|
"matcher": "Edit|Write|MultiEdit|apply_patch",
|
|
16
|
-
"command": "\"$(git rev-parse --show-toplevel)/.codex/hooks/knowledge-
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"matcher": "Edit|Write|MultiEdit|apply_patch",
|
|
20
|
-
"command": "\"$(git rev-parse --show-toplevel)/.codex/hooks/cite-policy-evict.cjs\""
|
|
16
|
+
"command": "\"$(git rev-parse --show-toplevel)/.codex/hooks/knowledge-pretooluse.cjs\""
|
|
21
17
|
}
|
|
22
18
|
],
|
|
23
19
|
"PostToolUse": [
|