@fenglimg/fabric-cli 2.0.0-rc.13 → 2.0.0-rc.15
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 +4 -2
- package/dist/chunk-AIB54QRT.js +82 -0
- package/dist/{chunk-FDRLV5PL.js → chunk-AXIFEVAS.js} +5 -213
- package/dist/{chunk-WWNXR34K.js → chunk-G2CIOLD4.js} +16 -1
- package/dist/{chunk-OHWQNSLH.js → chunk-SKSYUHKK.js} +267 -40
- package/dist/{chunk-X7QPY5KH.js → chunk-UTF4YBDN.js} +34 -271
- package/dist/config-7YD365I3.js +13 -0
- package/dist/{doctor-RILCO5OG.js → doctor-6XHLQJXB.js} +67 -50
- package/dist/index.js +7 -8
- package/dist/{install-SLS5W27W.js → install-JLDCHAXV.js} +328 -341
- package/dist/{plan-context-hint-QMUPAXIB.js → plan-context-hint-73U4FGKO.js} +6 -1
- package/dist/{serve-NGLXHDYC.js → serve-L3X5UHG2.js} +15 -10
- package/dist/{uninstall-JHUSFENL.js → uninstall-DD6FIFCI.js} +56 -163
- package/package.json +3 -3
- package/templates/hooks/configs/README.md +9 -5
- package/templates/hooks/configs/cursor-hooks.json +7 -10
- package/dist/chunk-Q72D24BG.js +0 -186
- package/dist/hooks-HIWYI3VG.js +0 -13
- package/dist/scan-VHKZPT2W.js +0 -24
|
@@ -10,7 +10,12 @@ var ALL_PATHS_SENTINEL = "**";
|
|
|
10
10
|
var planContextHintCommand = defineCommand({
|
|
11
11
|
meta: {
|
|
12
12
|
name: "plan-context-hint",
|
|
13
|
-
description: "Emit versioned knowledge hint JSON to stdout. Used by rc.6 hooks and the fabric-import skill."
|
|
13
|
+
description: "Emit versioned knowledge hint JSON to stdout. Used by rc.6 hooks and the fabric-import skill.",
|
|
14
|
+
// rc.15 TASK-004 (C8): hidden from `fab --help` listing. The command stays
|
|
15
|
+
// callable so hook scripts and the fabric-import skill can still invoke
|
|
16
|
+
// it via `fab plan-context-hint ...`; it just no longer appears in the
|
|
17
|
+
// top-level usage banner alongside install/doctor/serve/uninstall/config.
|
|
18
|
+
hidden: true
|
|
14
19
|
},
|
|
15
20
|
args: {
|
|
16
21
|
paths: {
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
hasActionHint,
|
|
3
4
|
paint,
|
|
5
|
+
renderFabricError,
|
|
4
6
|
symbol
|
|
5
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-G2CIOLD4.js";
|
|
8
|
+
import {
|
|
9
|
+
t
|
|
10
|
+
} from "./chunk-6ICJICVU.js";
|
|
6
11
|
import {
|
|
7
12
|
createDebugLogger,
|
|
8
13
|
resolveDevMode
|
|
9
14
|
} from "./chunk-OBQU6NHO.js";
|
|
10
|
-
import {
|
|
11
|
-
t
|
|
12
|
-
} from "./chunk-6ICJICVU.js";
|
|
13
15
|
|
|
14
16
|
// src/commands/serve.ts
|
|
15
17
|
import { defineCommand } from "citty";
|
|
@@ -39,11 +41,6 @@ var serveCommand = defineCommand({
|
|
|
39
41
|
type: "boolean",
|
|
40
42
|
description: t("cli.serve.args.debug.description"),
|
|
41
43
|
default: false
|
|
42
|
-
},
|
|
43
|
-
force: {
|
|
44
|
-
type: "boolean",
|
|
45
|
-
description: t("cli.serve.args.force.description"),
|
|
46
|
-
default: false
|
|
47
44
|
}
|
|
48
45
|
},
|
|
49
46
|
async run({ args }) {
|
|
@@ -55,7 +52,15 @@ var serveCommand = defineCommand({
|
|
|
55
52
|
const authToken = readAuthTokenFromEnv();
|
|
56
53
|
const host = validateHost(requestedHost, authToken);
|
|
57
54
|
const projectRoot = resolution.target;
|
|
58
|
-
|
|
55
|
+
try {
|
|
56
|
+
acquireLock(projectRoot);
|
|
57
|
+
} catch (err) {
|
|
58
|
+
if (hasActionHint(err)) {
|
|
59
|
+
renderFabricError(err);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
throw err;
|
|
63
|
+
}
|
|
59
64
|
process.on("exit", () => {
|
|
60
65
|
releaseLock(projectRoot);
|
|
61
66
|
});
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
detectClientSupports,
|
|
4
|
-
resolveClients
|
|
5
|
-
} from "./chunk-OHWQNSLH.js";
|
|
6
2
|
import {
|
|
7
3
|
FABRIC_HOOK_COMMAND_PATHS,
|
|
8
4
|
FABRIC_SECTION_REGEX,
|
|
@@ -11,21 +7,27 @@ import {
|
|
|
11
7
|
HOOK_SCRIPT_DESTINATIONS,
|
|
12
8
|
SECTION_TARGETS,
|
|
13
9
|
SKILL_DESTINATIONS
|
|
14
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UTF4YBDN.js";
|
|
15
11
|
import {
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
detectClientSupports,
|
|
13
|
+
resolveClients
|
|
14
|
+
} from "./chunk-SKSYUHKK.js";
|
|
18
15
|
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
hasActionHint,
|
|
17
|
+
paint,
|
|
18
|
+
renderFabricError
|
|
19
|
+
} from "./chunk-G2CIOLD4.js";
|
|
22
20
|
import {
|
|
23
21
|
t
|
|
24
22
|
} from "./chunk-6ICJICVU.js";
|
|
23
|
+
import {
|
|
24
|
+
createDebugLogger,
|
|
25
|
+
resolveDevMode
|
|
26
|
+
} from "./chunk-OBQU6NHO.js";
|
|
25
27
|
|
|
26
28
|
// src/commands/uninstall.ts
|
|
27
29
|
import { existsSync as existsSync2, statSync } from "fs";
|
|
28
|
-
import {
|
|
30
|
+
import { rm as rm2 } from "fs/promises";
|
|
29
31
|
import { homedir } from "os";
|
|
30
32
|
import { isAbsolute, join as join2, relative, resolve, sep } from "path";
|
|
31
33
|
import { cancel, confirm, group, intro, isCancel, log, note, outro } from "@clack/prompts";
|
|
@@ -80,37 +82,34 @@ async function removeHookScripts(step, rels, projectRoot) {
|
|
|
80
82
|
}
|
|
81
83
|
return results;
|
|
82
84
|
}
|
|
83
|
-
async function unmergeClaudeCodeHookConfig(projectRoot
|
|
85
|
+
async function unmergeClaudeCodeHookConfig(projectRoot) {
|
|
84
86
|
return unmergeHookConfig({
|
|
85
87
|
step: "claude-hook-config",
|
|
86
88
|
projectRoot,
|
|
87
89
|
configRel: HOOK_CONFIG_TARGETS.claudeCode,
|
|
88
90
|
arrayPaths: [...HOOK_CONFIG_ARRAY_PATHS.claudeCode],
|
|
89
91
|
fabricCommands: Object.values(FABRIC_HOOK_COMMAND_PATHS.claudeCode),
|
|
90
|
-
extractCommands: extractClaudeCommands
|
|
91
|
-
cleanEmpties: opts.cleanEmpties === true
|
|
92
|
+
extractCommands: extractClaudeCommands
|
|
92
93
|
});
|
|
93
94
|
}
|
|
94
|
-
async function unmergeCodexHookConfig(projectRoot
|
|
95
|
+
async function unmergeCodexHookConfig(projectRoot) {
|
|
95
96
|
return unmergeHookConfig({
|
|
96
97
|
step: "codex-hook-config",
|
|
97
98
|
projectRoot,
|
|
98
99
|
configRel: HOOK_CONFIG_TARGETS.codex,
|
|
99
100
|
arrayPaths: [...HOOK_CONFIG_ARRAY_PATHS.codex],
|
|
100
101
|
fabricCommands: Object.values(FABRIC_HOOK_COMMAND_PATHS.codex),
|
|
101
|
-
extractCommands: extractFlatCommands
|
|
102
|
-
cleanEmpties: opts.cleanEmpties === true
|
|
102
|
+
extractCommands: extractFlatCommands
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
|
-
async function unmergeCursorHookConfig(projectRoot
|
|
105
|
+
async function unmergeCursorHookConfig(projectRoot) {
|
|
106
106
|
return unmergeHookConfig({
|
|
107
107
|
step: "cursor-hook-config",
|
|
108
108
|
projectRoot,
|
|
109
109
|
configRel: HOOK_CONFIG_TARGETS.cursor,
|
|
110
110
|
arrayPaths: [...HOOK_CONFIG_ARRAY_PATHS.cursor],
|
|
111
111
|
fabricCommands: Object.values(FABRIC_HOOK_COMMAND_PATHS.cursor),
|
|
112
|
-
extractCommands: extractFlatCommands
|
|
113
|
-
cleanEmpties: opts.cleanEmpties === true
|
|
112
|
+
extractCommands: extractFlatCommands
|
|
114
113
|
});
|
|
115
114
|
}
|
|
116
115
|
async function stripFabricKnowledgeBaseSection(projectRoot) {
|
|
@@ -169,7 +168,7 @@ async function stripFabricKnowledgeBaseSection(projectRoot) {
|
|
|
169
168
|
}
|
|
170
169
|
return results;
|
|
171
170
|
}
|
|
172
|
-
async function uninstallBootstrapStage(projectRoot,
|
|
171
|
+
async function uninstallBootstrapStage(projectRoot, _opts = {}) {
|
|
173
172
|
const results = [];
|
|
174
173
|
await runAndCollect(
|
|
175
174
|
results,
|
|
@@ -181,19 +180,19 @@ async function uninstallBootstrapStage(projectRoot, opts = {}) {
|
|
|
181
180
|
results,
|
|
182
181
|
"cursor-hook-config",
|
|
183
182
|
projectRoot,
|
|
184
|
-
() => unmergeCursorHookConfig(projectRoot
|
|
183
|
+
() => unmergeCursorHookConfig(projectRoot)
|
|
185
184
|
);
|
|
186
185
|
await runAndCollectOne(
|
|
187
186
|
results,
|
|
188
187
|
"codex-hook-config",
|
|
189
188
|
projectRoot,
|
|
190
|
-
() => unmergeCodexHookConfig(projectRoot
|
|
189
|
+
() => unmergeCodexHookConfig(projectRoot)
|
|
191
190
|
);
|
|
192
191
|
await runAndCollectOne(
|
|
193
192
|
results,
|
|
194
193
|
"claude-hook-config",
|
|
195
194
|
projectRoot,
|
|
196
|
-
() => unmergeClaudeCodeHookConfig(projectRoot
|
|
195
|
+
() => unmergeClaudeCodeHookConfig(projectRoot)
|
|
197
196
|
);
|
|
198
197
|
await runAndCollect(
|
|
199
198
|
results,
|
|
@@ -339,7 +338,7 @@ async function unmergeHookConfig(args) {
|
|
|
339
338
|
}
|
|
340
339
|
const next = JSON.parse(JSON.stringify(parsed));
|
|
341
340
|
for (const dotted of args.arrayPaths) {
|
|
342
|
-
pruneArrayAtPath(next, dotted, args.fabricCommands, args.extractCommands
|
|
341
|
+
pruneArrayAtPath(next, dotted, args.fabricCommands, args.extractCommands);
|
|
343
342
|
}
|
|
344
343
|
if (jsonEqual(parsed, next)) {
|
|
345
344
|
return { step: args.step, path: target, status: "skipped", message: "no-fabric-entries" };
|
|
@@ -356,7 +355,7 @@ async function unmergeHookConfig(args) {
|
|
|
356
355
|
};
|
|
357
356
|
}
|
|
358
357
|
}
|
|
359
|
-
function pruneArrayAtPath(root, path, fabricCommands, extractCommands
|
|
358
|
+
function pruneArrayAtPath(root, path, fabricCommands, extractCommands) {
|
|
360
359
|
const keys = path.split(".");
|
|
361
360
|
const chain = [];
|
|
362
361
|
let cursor = root;
|
|
@@ -384,7 +383,7 @@ function pruneArrayAtPath(root, path, fabricCommands, extractCommands, cleanEmpt
|
|
|
384
383
|
});
|
|
385
384
|
const leaf = chain[chain.length - 1];
|
|
386
385
|
leaf.parent[leaf.key] = filtered;
|
|
387
|
-
if (
|
|
386
|
+
if (filtered.length > 0) {
|
|
388
387
|
return;
|
|
389
388
|
}
|
|
390
389
|
for (let i = chain.length - 1; i >= 0; i--) {
|
|
@@ -446,59 +445,24 @@ var uninstallCommand = defineCommand({
|
|
|
446
445
|
description: t("cli.uninstall.description")
|
|
447
446
|
},
|
|
448
447
|
args: {
|
|
449
|
-
target: {
|
|
450
|
-
type: "string",
|
|
451
|
-
description: t("cli.uninstall.args.target.description")
|
|
452
|
-
},
|
|
453
448
|
debug: {
|
|
454
449
|
type: "boolean",
|
|
455
450
|
description: t("cli.uninstall.args.debug.description"),
|
|
456
451
|
default: false
|
|
457
452
|
},
|
|
458
|
-
|
|
453
|
+
"dry-run": {
|
|
459
454
|
type: "boolean",
|
|
460
|
-
description: t("cli.uninstall.args.
|
|
455
|
+
description: t("cli.uninstall.args.dry-run.description"),
|
|
461
456
|
default: false
|
|
462
457
|
},
|
|
458
|
+
target: {
|
|
459
|
+
type: "string",
|
|
460
|
+
description: t("cli.uninstall.args.target.description")
|
|
461
|
+
},
|
|
463
462
|
yes: {
|
|
464
463
|
type: "boolean",
|
|
465
464
|
description: t("cli.uninstall.args.yes.description"),
|
|
466
465
|
default: false
|
|
467
|
-
},
|
|
468
|
-
plan: {
|
|
469
|
-
type: "boolean",
|
|
470
|
-
description: t("cli.uninstall.args.plan.description"),
|
|
471
|
-
default: false
|
|
472
|
-
},
|
|
473
|
-
bootstrap: {
|
|
474
|
-
type: "boolean",
|
|
475
|
-
default: true,
|
|
476
|
-
negativeDescription: t("cli.uninstall.flags.no-bootstrap")
|
|
477
|
-
},
|
|
478
|
-
mcp: {
|
|
479
|
-
type: "boolean",
|
|
480
|
-
default: true,
|
|
481
|
-
negativeDescription: t("cli.uninstall.flags.no-mcp")
|
|
482
|
-
},
|
|
483
|
-
scaffold: {
|
|
484
|
-
type: "boolean",
|
|
485
|
-
default: true,
|
|
486
|
-
negativeDescription: t("cli.uninstall.flags.no-scaffold")
|
|
487
|
-
},
|
|
488
|
-
interactive: {
|
|
489
|
-
type: "boolean",
|
|
490
|
-
description: t("cli.uninstall.flags.interactive"),
|
|
491
|
-
default: true
|
|
492
|
-
},
|
|
493
|
-
purge: {
|
|
494
|
-
type: "boolean",
|
|
495
|
-
description: t("cli.uninstall.flags.purge"),
|
|
496
|
-
default: false
|
|
497
|
-
},
|
|
498
|
-
"clean-empties": {
|
|
499
|
-
type: "boolean",
|
|
500
|
-
description: t("cli.uninstall.flags.clean-empties"),
|
|
501
|
-
default: false
|
|
502
466
|
}
|
|
503
467
|
},
|
|
504
468
|
async run({ args }) {
|
|
@@ -514,7 +478,15 @@ async function runUninstallCommand(args) {
|
|
|
514
478
|
for (const step of resolution.chain) {
|
|
515
479
|
logger(step);
|
|
516
480
|
}
|
|
517
|
-
|
|
481
|
+
try {
|
|
482
|
+
checkLockOrThrow(intent.target);
|
|
483
|
+
} catch (err) {
|
|
484
|
+
if (hasActionHint(err)) {
|
|
485
|
+
renderFabricError(err);
|
|
486
|
+
process.exit(1);
|
|
487
|
+
}
|
|
488
|
+
throw err;
|
|
489
|
+
}
|
|
518
490
|
const supports = detectClientSupports(intent.target);
|
|
519
491
|
const basePlan = await buildUninstallExecutionPlan(intent.target, {
|
|
520
492
|
...intent.options
|
|
@@ -525,7 +497,7 @@ async function runUninstallCommand(args) {
|
|
|
525
497
|
interactive: intent.interactiveSummary && !intent.wizardEnabled,
|
|
526
498
|
supports
|
|
527
499
|
};
|
|
528
|
-
const finalPlan = intent.wizardEnabled ? await resolveUninstallExecutionPlanWithWizard(planWithSupports,
|
|
500
|
+
const finalPlan = intent.wizardEnabled ? await resolveUninstallExecutionPlanWithWizard(planWithSupports, createDefaultUninstallWizardAdapter()) : planWithSupports;
|
|
529
501
|
if (finalPlan === null) {
|
|
530
502
|
process.exitCode = 130;
|
|
531
503
|
return;
|
|
@@ -541,7 +513,7 @@ async function runUninstallCommand(args) {
|
|
|
541
513
|
}))
|
|
542
514
|
};
|
|
543
515
|
}
|
|
544
|
-
if (intent.interactiveSummary && !intent.wizardEnabled && args.yes !== true
|
|
516
|
+
if (intent.interactiveSummary && !intent.wizardEnabled && args.yes !== true) {
|
|
545
517
|
const proceed = await confirmDestructive(finalPlan);
|
|
546
518
|
if (!proceed) {
|
|
547
519
|
process.exitCode = 130;
|
|
@@ -555,25 +527,19 @@ async function runUninstallCommand(args) {
|
|
|
555
527
|
function resolveUninstallCliIntent(args, targetInput) {
|
|
556
528
|
const target = normalizeTarget(targetInput);
|
|
557
529
|
const terminalInteractive = isInteractiveUninstall();
|
|
558
|
-
const planOnly = args
|
|
530
|
+
const planOnly = args["dry-run"] === true;
|
|
559
531
|
const options = {
|
|
560
|
-
|
|
561
|
-
skipBootstrap: args.bootstrap === false,
|
|
562
|
-
skipMcp: args.mcp === false,
|
|
563
|
-
skipScaffold: args.scaffold === false,
|
|
564
|
-
planOnly,
|
|
565
|
-
purge: args.purge === true,
|
|
566
|
-
cleanEmpties: args["clean-empties"] === true
|
|
532
|
+
planOnly
|
|
567
533
|
};
|
|
568
534
|
return {
|
|
569
535
|
target,
|
|
570
536
|
options,
|
|
571
|
-
interactiveSummary:
|
|
537
|
+
interactiveSummary: terminalInteractive,
|
|
572
538
|
wizardEnabled: shouldUseUninstallWizard(args, terminalInteractive) && !planOnly
|
|
573
539
|
};
|
|
574
540
|
}
|
|
575
541
|
function shouldUseUninstallWizard(args, terminalInteractive = isInteractiveUninstall()) {
|
|
576
|
-
return terminalInteractive && args.
|
|
542
|
+
return terminalInteractive && args.yes !== true;
|
|
577
543
|
}
|
|
578
544
|
async function buildUninstallExecutionPlan(target, options = {}) {
|
|
579
545
|
const scaffold = buildUninstallFabricPlan(target, options);
|
|
@@ -605,13 +571,6 @@ function buildUninstallFabricPlan(target, options = {}) {
|
|
|
605
571
|
const gk = join2(fabricDir, "knowledge", sub, ".gitkeep");
|
|
606
572
|
entries.push({ path: gk, kind: "gitkeep", absent: !existsSync2(gk) });
|
|
607
573
|
}
|
|
608
|
-
if (options.purge === true) {
|
|
609
|
-
for (const sub of KNOWLEDGE_SUBDIRS) {
|
|
610
|
-
const subdir = join2(fabricDir, "knowledge", sub);
|
|
611
|
-
entries.push({ path: subdir, kind: "knowledge-subdir", absent: !existsSync2(subdir) });
|
|
612
|
-
}
|
|
613
|
-
entries.push({ path: fabricDir, kind: "fabric-dir", absent: !existsSync2(fabricDir) });
|
|
614
|
-
}
|
|
615
574
|
const safeEntries = entries.filter((entry) => !isInsidePersonalRoot(entry.path, personalKnowledgeDir));
|
|
616
575
|
return {
|
|
617
576
|
target: absTarget,
|
|
@@ -623,9 +582,7 @@ function buildUninstallFabricPlan(target, options = {}) {
|
|
|
623
582
|
}
|
|
624
583
|
async function executeUninstallFabricPlan(plan) {
|
|
625
584
|
const results = [];
|
|
626
|
-
const
|
|
627
|
-
const otherEntries = plan.entries.filter((entry) => entry.kind !== "fabric-dir");
|
|
628
|
-
for (const entry of otherEntries) {
|
|
585
|
+
for (const entry of plan.entries) {
|
|
629
586
|
if (entry.absent) {
|
|
630
587
|
results.push({
|
|
631
588
|
step: scaffoldStepLabel(entry.kind),
|
|
@@ -636,7 +593,7 @@ async function executeUninstallFabricPlan(plan) {
|
|
|
636
593
|
continue;
|
|
637
594
|
}
|
|
638
595
|
try {
|
|
639
|
-
await rm2(entry.path, {
|
|
596
|
+
await rm2(entry.path, { force: true });
|
|
640
597
|
results.push({ step: scaffoldStepLabel(entry.kind), path: entry.path, status: "removed" });
|
|
641
598
|
} catch (error) {
|
|
642
599
|
results.push({
|
|
@@ -647,39 +604,6 @@ async function executeUninstallFabricPlan(plan) {
|
|
|
647
604
|
});
|
|
648
605
|
}
|
|
649
606
|
}
|
|
650
|
-
if (fabricDirEntry !== void 0) {
|
|
651
|
-
const path = fabricDirEntry.path;
|
|
652
|
-
if (!existsSync2(path)) {
|
|
653
|
-
results.push({
|
|
654
|
-
step: "fabric-dir",
|
|
655
|
-
path,
|
|
656
|
-
status: "skipped",
|
|
657
|
-
message: "absent"
|
|
658
|
-
});
|
|
659
|
-
} else {
|
|
660
|
-
try {
|
|
661
|
-
const entries = await readdir2(path);
|
|
662
|
-
if (entries.length > 0) {
|
|
663
|
-
results.push({
|
|
664
|
-
step: "fabric-dir",
|
|
665
|
-
path,
|
|
666
|
-
status: "skipped",
|
|
667
|
-
message: "not-empty"
|
|
668
|
-
});
|
|
669
|
-
} else {
|
|
670
|
-
await rm2(path, { recursive: true, force: true });
|
|
671
|
-
results.push({ step: "fabric-dir", path, status: "removed" });
|
|
672
|
-
}
|
|
673
|
-
} catch (error) {
|
|
674
|
-
results.push({
|
|
675
|
-
step: "fabric-dir",
|
|
676
|
-
path,
|
|
677
|
-
status: "error",
|
|
678
|
-
message: error instanceof Error ? error.message : String(error)
|
|
679
|
-
});
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
607
|
return results;
|
|
684
608
|
}
|
|
685
609
|
function scaffoldStepLabel(kind) {
|
|
@@ -688,10 +612,6 @@ function scaffoldStepLabel(kind) {
|
|
|
688
612
|
return "scaffold-state";
|
|
689
613
|
case "gitkeep":
|
|
690
614
|
return "scaffold-gitkeep";
|
|
691
|
-
case "knowledge-subdir":
|
|
692
|
-
return "scaffold-knowledge";
|
|
693
|
-
case "fabric-dir":
|
|
694
|
-
return "fabric-dir";
|
|
695
615
|
}
|
|
696
616
|
}
|
|
697
617
|
async function uninstallMcpClients(target, options = {}) {
|
|
@@ -799,7 +719,7 @@ async function executeUninstallStage(plan, stageName) {
|
|
|
799
719
|
case "scaffold":
|
|
800
720
|
return executeUninstallFabricPlan(plan.scaffold);
|
|
801
721
|
case "bootstrap": {
|
|
802
|
-
const opts = {
|
|
722
|
+
const opts = {};
|
|
803
723
|
return uninstallBootstrapStage(plan.target, opts);
|
|
804
724
|
}
|
|
805
725
|
case "mcp": {
|
|
@@ -812,12 +732,12 @@ async function uninstallFabric(target, options = {}) {
|
|
|
812
732
|
const plan = await buildUninstallExecutionPlan(target, options);
|
|
813
733
|
return executeUninstallExecutionPlan(plan);
|
|
814
734
|
}
|
|
815
|
-
async function resolveUninstallExecutionPlanWithWizard(basePlan,
|
|
735
|
+
async function resolveUninstallExecutionPlanWithWizard(basePlan, wizardAdapter) {
|
|
816
736
|
const selection = await wizardAdapter.run({
|
|
817
737
|
target: basePlan.target,
|
|
818
738
|
options: basePlan.options,
|
|
819
739
|
supports: basePlan.supports,
|
|
820
|
-
lockedStages:
|
|
740
|
+
lockedStages: []
|
|
821
741
|
});
|
|
822
742
|
if (selection === null) {
|
|
823
743
|
return null;
|
|
@@ -826,9 +746,7 @@ async function resolveUninstallExecutionPlanWithWizard(basePlan, args, wizardAda
|
|
|
826
746
|
...basePlan.options,
|
|
827
747
|
skipScaffold: !selection.scaffold,
|
|
828
748
|
skipBootstrap: !selection.bootstrap,
|
|
829
|
-
skipMcp: !selection.mcp
|
|
830
|
-
purge: selection.purge,
|
|
831
|
-
cleanEmpties: selection.cleanEmpties
|
|
749
|
+
skipMcp: !selection.mcp
|
|
832
750
|
};
|
|
833
751
|
const rebuilt = await buildUninstallExecutionPlan(basePlan.target, nextOptions);
|
|
834
752
|
return {
|
|
@@ -879,18 +797,6 @@ function createDefaultUninstallWizardAdapter() {
|
|
|
879
797
|
defaultValue: formatPromptDefault(!context.options.skipMcp)
|
|
880
798
|
}),
|
|
881
799
|
initialValue: !context.options.skipMcp
|
|
882
|
-
}),
|
|
883
|
-
purge: async () => confirmInGroup({
|
|
884
|
-
message: t("cli.uninstall.wizard.purge", {
|
|
885
|
-
defaultValue: formatPromptDefault(context.options.purge === true)
|
|
886
|
-
}),
|
|
887
|
-
initialValue: context.options.purge === true
|
|
888
|
-
}),
|
|
889
|
-
cleanEmpties: async () => confirmInGroup({
|
|
890
|
-
message: t("cli.uninstall.wizard.clean-empties", {
|
|
891
|
-
defaultValue: formatPromptDefault(context.options.cleanEmpties === true)
|
|
892
|
-
}),
|
|
893
|
-
initialValue: context.options.cleanEmpties === true
|
|
894
800
|
})
|
|
895
801
|
},
|
|
896
802
|
{
|
|
@@ -910,9 +816,7 @@ function createDefaultUninstallWizardAdapter() {
|
|
|
910
816
|
...context.options,
|
|
911
817
|
skipScaffold: !groupedSelection.scaffold,
|
|
912
818
|
skipBootstrap: !groupedSelection.bootstrap,
|
|
913
|
-
skipMcp: !groupedSelection.mcp
|
|
914
|
-
purge: groupedSelection.purge,
|
|
915
|
-
cleanEmpties: groupedSelection.cleanEmpties
|
|
819
|
+
skipMcp: !groupedSelection.mcp
|
|
916
820
|
};
|
|
917
821
|
log.step(t("cli.uninstall.wizard.step.review"));
|
|
918
822
|
printUninstallPlanSummary(context.target, previewOptions, context.supports);
|
|
@@ -939,13 +843,6 @@ async function confirmInGroup(options) {
|
|
|
939
843
|
}
|
|
940
844
|
return result;
|
|
941
845
|
}
|
|
942
|
-
function collectLockedWizardStages(args) {
|
|
943
|
-
const locked = [];
|
|
944
|
-
if (args.scaffold === false) locked.push("scaffold");
|
|
945
|
-
if (args.bootstrap === false) locked.push("bootstrap");
|
|
946
|
-
if (args.mcp === false) locked.push("mcp");
|
|
947
|
-
return locked;
|
|
948
|
-
}
|
|
949
846
|
async function confirmDestructive(plan) {
|
|
950
847
|
printUninstallPlanSummary(plan.target, plan.options, plan.supports);
|
|
951
848
|
const answer = await confirm({
|
|
@@ -964,9 +861,7 @@ function printUninstallPlanPreview(plan) {
|
|
|
964
861
|
t("cli.uninstall.plan.preview-result", {
|
|
965
862
|
scaffold: yesNoLabel(!plan.options.skipScaffold),
|
|
966
863
|
bootstrap: yesNoLabel(!plan.options.skipBootstrap),
|
|
967
|
-
mcp: yesNoLabel(!plan.options.skipMcp)
|
|
968
|
-
purge: yesNoLabel(plan.options.purge === true),
|
|
969
|
-
cleanEmpties: yesNoLabel(plan.options.cleanEmpties === true)
|
|
864
|
+
mcp: yesNoLabel(!plan.options.skipMcp)
|
|
970
865
|
})
|
|
971
866
|
);
|
|
972
867
|
if (!plan.options.skipScaffold && plan.scaffold.entries.length > 0) {
|
|
@@ -984,9 +879,7 @@ function printUninstallPlanSummary(target, options, supports) {
|
|
|
984
879
|
t("cli.uninstall.plan.actions", {
|
|
985
880
|
scaffold: yesNoLabel(!options.skipScaffold),
|
|
986
881
|
bootstrap: yesNoLabel(!options.skipBootstrap),
|
|
987
|
-
mcp: yesNoLabel(!options.skipMcp)
|
|
988
|
-
purge: yesNoLabel(options.purge === true),
|
|
989
|
-
cleanEmpties: yesNoLabel(options.cleanEmpties === true)
|
|
882
|
+
mcp: yesNoLabel(!options.skipMcp)
|
|
990
883
|
})
|
|
991
884
|
);
|
|
992
885
|
const detected = supports.filter((support) => support.detected);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fenglimg/fabric-cli",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"fab": "dist/index.js",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"tree-sitter-javascript": "^0.25.0",
|
|
21
21
|
"tree-sitter-typescript": "^0.23.2",
|
|
22
22
|
"web-tree-sitter": "^0.26.8",
|
|
23
|
-
"@fenglimg/fabric-
|
|
24
|
-
"@fenglimg/fabric-
|
|
23
|
+
"@fenglimg/fabric-server": "2.0.0-rc.15",
|
|
24
|
+
"@fenglimg/fabric-shared": "2.0.0-rc.15"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^22.15.0",
|
|
@@ -27,11 +27,15 @@ config (`~/.codex/config.toml`) is TOML.
|
|
|
27
27
|
|
|
28
28
|
## cursor-hooks.json
|
|
29
29
|
|
|
30
|
-
Written to (or merged into) the user repo's `.cursor/hooks.json`.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
Written to (or merged into) the user repo's `.cursor/hooks.json`. Schema
|
|
31
|
+
authoritative source: https://cursor.com/cn/docs/hooks. Top-level requires
|
|
32
|
+
`version: 1` (number literal, NOT string) and a `hooks` object (NOT `events`)
|
|
33
|
+
keyed by camelCase event names: `stop`, `sessionStart`, `preToolUse`. Per-entry
|
|
34
|
+
shape stays flat (Codex-style): `{command, matcher?, type?, timeout?,
|
|
35
|
+
loop_limit?, failClosed?}`. rc.14 TASK-001 corrected rc.13's wrong top-level
|
|
36
|
+
envelope (was `{events: {Stop, SessionStart, PreToolUse}}` PascalCase, which
|
|
37
|
+
Cursor rejects with "Config version must be a number; Config hooks must be an
|
|
38
|
+
object").
|
|
35
39
|
|
|
36
40
|
## fabric-hint.cjs script paths
|
|
37
41
|
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
2
|
+
"version": 1,
|
|
3
|
+
"hooks": {
|
|
4
|
+
"stop": [
|
|
5
|
+
{ "command": ".cursor/hooks/fabric-hint.cjs" }
|
|
7
6
|
],
|
|
8
|
-
"
|
|
9
|
-
{
|
|
10
|
-
"command": ".cursor/hooks/knowledge-hint-broad.cjs"
|
|
11
|
-
}
|
|
7
|
+
"sessionStart": [
|
|
8
|
+
{ "command": ".cursor/hooks/knowledge-hint-broad.cjs" }
|
|
12
9
|
],
|
|
13
|
-
"
|
|
10
|
+
"preToolUse": [
|
|
14
11
|
{
|
|
15
12
|
"matcher": "Edit|Write|MultiEdit",
|
|
16
13
|
"command": ".cursor/hooks/knowledge-hint-narrow.cjs"
|