@fenglimg/fabric-cli 2.1.0-rc.2 → 2.2.0-rc.10
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 +8 -5
- package/dist/chunk-27HK6H5Y.js +69 -0
- package/dist/{chunk-BATF4PEJ.js → chunk-2KBCTMID.js} +31 -8
- package/dist/chunk-3D7B2UAZ.js +149 -0
- package/dist/{chunk-MF3OTILQ.js → chunk-3IOLS5EK.js} +48 -42
- package/dist/{plan-context-hint-FC6P3WFE.js → chunk-722JU5BP.js} +52 -12
- package/dist/{chunk-F46ORPOA.js → chunk-7ZDXBOOU.js} +271 -166
- package/dist/{doctor-QVNPHLJK.js → chunk-E7HJUU34.js} +248 -72
- package/dist/chunk-EOT63RDH.js +36 -0
- package/dist/chunk-FNHDQTPC.js +16 -0
- package/dist/chunk-HORSMSZL.js +26 -0
- package/dist/chunk-NLNH64A3.js +43 -0
- package/dist/{chunk-WU6GAPKH.js → chunk-PTGQAZEW.js} +12 -4
- package/dist/chunk-QFIVFZRH.js +13 -0
- package/dist/chunk-QPAW6IYT.js +387 -0
- package/dist/{chunk-COI5VDFU.js → chunk-WA3DYGSY.js} +1 -2
- package/dist/{config-XJIPZNUP.js → config-A3LTECAY.js} +4 -3
- package/dist/context-UJCGYOT6.js +117 -0
- package/dist/doctor-MDTZWKBK.js +24 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +167 -16
- package/dist/info-7FKBTMVO.js +139 -0
- package/dist/install-v2-RINEA24K.js +3279 -0
- package/dist/{metrics-ACEQFPDU.js → metrics-HMFH4YHK.js} +22 -9
- package/dist/{onboard-coverage-MFCAEBDO.js → onboard-coverage-XSG77LL3.js} +48 -27
- package/dist/plan-context-hint-5TNGH3R4.js +12 -0
- package/dist/scope-explain-HLJZ2M33.js +48 -0
- package/dist/status-4R3TM4FJ.js +37 -0
- package/dist/store-HOCORVL3.js +563 -0
- package/dist/sync-DT5UJMMR.js +418 -0
- package/dist/{uninstall-TAXSUSKH.js → uninstall-IFN2KYBK.js} +128 -140
- package/dist/whoami-ITGEFWH4.js +49 -0
- package/package.json +7 -5
- package/templates/hooks/cite-policy-evict.cjs +412 -160
- package/templates/hooks/configs/README.md +14 -27
- package/templates/hooks/configs/claude-code.json +17 -2
- package/templates/hooks/configs/codex-hooks.json +15 -3
- package/templates/hooks/fabric-hint.cjs +573 -180
- package/templates/hooks/knowledge-hint-broad.cjs +648 -190
- package/templates/hooks/knowledge-hint-narrow.cjs +123 -77
- package/templates/hooks/lib/banner-i18n.cjs +31 -0
- package/templates/hooks/lib/bindings-snapshot-reader.cjs +118 -7
- package/templates/hooks/lib/cite-line-parser.cjs +12 -20
- package/templates/hooks/lib/client-adapter.cjs +66 -7
- package/templates/hooks/lib/injection-log.cjs +91 -0
- package/templates/hooks/lib/nudge-policy.cjs +117 -0
- package/templates/hooks/lib/state-store.cjs +90 -11
- package/templates/hooks/post-tooluse-mutation.cjs +386 -0
- package/templates/hooks/session-end-marker.cjs +140 -0
- package/templates/skills/fabric/SKILL.md +100 -0
- package/templates/skills/fabric-archive/SKILL.md +35 -24
- package/templates/skills/fabric-archive/ref/dry-run-scope.md +1 -1
- package/templates/skills/fabric-archive/ref/i18n-policy.md +2 -3
- package/templates/skills/fabric-archive/ref/phase-1-5-onboard.md +2 -3
- package/templates/skills/fabric-archive/ref/phase-1-cross-session.md +1 -1
- package/templates/skills/fabric-archive/ref/phase-2-5-viability.md +1 -1
- package/templates/skills/fabric-archive/ref/phase-3-6-related-edges.md +18 -0
- package/templates/skills/fabric-archive/ref/phase-3-7-semantic-scope.md +47 -0
- package/templates/skills/fabric-audit/SKILL.md +63 -0
- package/templates/skills/fabric-connect/SKILL.md +48 -0
- package/templates/skills/fabric-import/SKILL.md +7 -7
- package/templates/skills/fabric-import/ref/i18n-policy.md +2 -3
- package/templates/skills/fabric-import/ref/state-recovery.md +1 -2
- package/templates/skills/fabric-review/SKILL.md +16 -5
- package/templates/skills/fabric-review/ref/cite-contract.md +56 -0
- package/templates/skills/fabric-review/ref/i18n-policy.md +2 -3
- package/templates/skills/fabric-review/ref/output-contract.md +1 -1
- package/templates/skills/fabric-review/ref/per-mode-flows.md +2 -2
- package/templates/skills/fabric-review/ref/worked-examples.md +1 -1
- package/templates/skills/fabric-store/SKILL.md +44 -0
- package/templates/skills/fabric-sync/SKILL.md +1 -1
- package/templates/skills/lib/shared-policy.md +2 -2
- package/dist/chunk-HFQVXY6P.js +0 -86
- package/dist/chunk-L4Q55UC4.js +0 -52
- package/dist/chunk-LFIKMVY7.js +0 -27
- package/dist/chunk-PWLW3B57.js +0 -18
- package/dist/chunk-RYAFBNES.js +0 -33
- package/dist/chunk-T5RPGCCM.js +0 -40
- package/dist/chunk-WWNXR34K.js +0 -49
- package/dist/install-2HDO5FTQ.js +0 -2683
- package/dist/scope-explain-2F2R5URO.js +0 -33
- package/dist/status-GLQWLWH6.js +0 -23
- package/dist/store-XTSE5TY6.js +0 -105
- package/dist/sync-BJCWDPNC.js +0 -245
- package/dist/whoami-B6AEMSEV.js +0 -31
- package/templates/hooks/configs/cursor-hooks.json +0 -18
- package/templates/hooks/lib/cite-contract-reminder.cjs +0 -179
- package/templates/hooks/lib/summary-fallback.cjs +0 -210
|
@@ -7,28 +7,28 @@ import {
|
|
|
7
7
|
HOOK_SCRIPT_DESTINATIONS,
|
|
8
8
|
SKILL_DESTINATIONS,
|
|
9
9
|
fabricAgentsSnapshotPath
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import {
|
|
12
|
-
paint
|
|
13
|
-
} from "./chunk-WWNXR34K.js";
|
|
10
|
+
} from "./chunk-7ZDXBOOU.js";
|
|
14
11
|
import {
|
|
15
12
|
createDebugLogger,
|
|
16
13
|
resolveDevMode
|
|
17
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-WA3DYGSY.js";
|
|
18
15
|
import {
|
|
19
16
|
detectClientSupports,
|
|
20
17
|
resolveClients
|
|
21
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-3IOLS5EK.js";
|
|
19
|
+
import {
|
|
20
|
+
paint
|
|
21
|
+
} from "./chunk-NLNH64A3.js";
|
|
22
22
|
import {
|
|
23
23
|
t
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-HORSMSZL.js";
|
|
25
25
|
|
|
26
26
|
// src/commands/uninstall.ts
|
|
27
27
|
import { existsSync as existsSync2, statSync } from "fs";
|
|
28
28
|
import { rm as rm2 } from "fs/promises";
|
|
29
29
|
import { homedir } from "os";
|
|
30
30
|
import { isAbsolute, join as join2, relative, resolve, sep } from "path";
|
|
31
|
-
import { cancel, confirm,
|
|
31
|
+
import { cancel, confirm, intro, isCancel, multiselect, note, outro } from "@clack/prompts";
|
|
32
32
|
import { defineCommand } from "citty";
|
|
33
33
|
|
|
34
34
|
// src/install/uninstall-skills-and-hooks.ts
|
|
@@ -37,6 +37,9 @@ import { readdir, readFile, rm, rmdir } from "fs/promises";
|
|
|
37
37
|
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
|
+
async function uninstallFabricRouterSkill(projectRoot) {
|
|
41
|
+
return removeSkill("skill-router", SKILL_DESTINATIONS.fabricRouter, projectRoot);
|
|
42
|
+
}
|
|
40
43
|
async function uninstallFabricArchiveSkill(projectRoot) {
|
|
41
44
|
return removeSkill("skill", SKILL_DESTINATIONS.fabricArchive, projectRoot);
|
|
42
45
|
}
|
|
@@ -49,6 +52,12 @@ async function uninstallFabricImportSkill(projectRoot) {
|
|
|
49
52
|
async function uninstallFabricSyncSkill(projectRoot) {
|
|
50
53
|
return removeSkill("skill-sync", SKILL_DESTINATIONS.fabricSync, projectRoot);
|
|
51
54
|
}
|
|
55
|
+
async function uninstallFabricAuditSkill(projectRoot) {
|
|
56
|
+
return removeSkill("skill-audit", SKILL_DESTINATIONS.fabricAudit, projectRoot);
|
|
57
|
+
}
|
|
58
|
+
async function uninstallFabricConnectSkill(projectRoot) {
|
|
59
|
+
return removeSkill("skill-connect", SKILL_DESTINATIONS.fabricConnect, projectRoot);
|
|
60
|
+
}
|
|
52
61
|
async function removeSkill(step, rels, projectRoot) {
|
|
53
62
|
const results = [];
|
|
54
63
|
for (const rel of rels) {
|
|
@@ -75,6 +84,27 @@ async function removeKnowledgeHintNarrowHook(projectRoot) {
|
|
|
75
84
|
projectRoot
|
|
76
85
|
);
|
|
77
86
|
}
|
|
87
|
+
async function removeCitePolicyEvictHook(projectRoot) {
|
|
88
|
+
return removeHookScripts(
|
|
89
|
+
"hook-cite-policy-evict-script",
|
|
90
|
+
HOOK_SCRIPT_DESTINATIONS.citePolicyEvict,
|
|
91
|
+
projectRoot
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
async function removeSessionEndMarkerHook(projectRoot) {
|
|
95
|
+
return removeHookScripts(
|
|
96
|
+
"hook-session-end-script",
|
|
97
|
+
HOOK_SCRIPT_DESTINATIONS.sessionEndMarker,
|
|
98
|
+
projectRoot
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
async function removePostTooluseMutationHook(projectRoot) {
|
|
102
|
+
return removeHookScripts(
|
|
103
|
+
"hook-post-tooluse-script",
|
|
104
|
+
HOOK_SCRIPT_DESTINATIONS.postTooluseMutation,
|
|
105
|
+
projectRoot
|
|
106
|
+
);
|
|
107
|
+
}
|
|
78
108
|
async function removeHookScripts(step, rels, projectRoot) {
|
|
79
109
|
const results = [];
|
|
80
110
|
for (const rel of rels) {
|
|
@@ -131,25 +161,10 @@ async function unmergeCodexHookConfig(projectRoot) {
|
|
|
131
161
|
extractCommands: extractFlatCommands
|
|
132
162
|
});
|
|
133
163
|
}
|
|
134
|
-
async function unmergeCursorHookConfig(projectRoot) {
|
|
135
|
-
return unmergeHookConfig({
|
|
136
|
-
step: "cursor-hook-config",
|
|
137
|
-
projectRoot,
|
|
138
|
-
configRel: HOOK_CONFIG_TARGETS.cursor,
|
|
139
|
-
arrayPaths: [...HOOK_CONFIG_ARRAY_PATHS.cursor],
|
|
140
|
-
fabricCommands: Object.values(FABRIC_HOOK_COMMAND_PATHS.cursor),
|
|
141
|
-
extractCommands: extractFlatCommands
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
164
|
async function stripFabricBootstrapBlocks(projectRoot) {
|
|
145
165
|
const results = [];
|
|
146
166
|
results.push(await stripClaudeBootstrapImports(projectRoot));
|
|
147
|
-
results.push(await stripManagedBlock(projectRoot, "AGENTS.md"
|
|
148
|
-
results.push(
|
|
149
|
-
await stripManagedBlock(projectRoot, join(".cursor", "rules", "fabric-bootstrap.mdc"), {
|
|
150
|
-
deleteWhenEmpty: true
|
|
151
|
-
})
|
|
152
|
-
);
|
|
167
|
+
results.push(await stripManagedBlock(projectRoot, "AGENTS.md"));
|
|
153
168
|
return results;
|
|
154
169
|
}
|
|
155
170
|
async function stripClaudeBootstrapImports(projectRoot) {
|
|
@@ -194,8 +209,8 @@ async function stripClaudeBootstrapImports(projectRoot) {
|
|
|
194
209
|
};
|
|
195
210
|
}
|
|
196
211
|
}
|
|
197
|
-
async function stripManagedBlock(projectRoot, relPath
|
|
198
|
-
const step =
|
|
212
|
+
async function stripManagedBlock(projectRoot, relPath) {
|
|
213
|
+
const step = "bootstrap-codex";
|
|
199
214
|
const target = join(projectRoot, relPath);
|
|
200
215
|
if (!existsSync(target)) {
|
|
201
216
|
return { step, path: target, status: "skipped", message: "absent" };
|
|
@@ -218,19 +233,6 @@ async function stripManagedBlock(projectRoot, relPath, options) {
|
|
|
218
233
|
const before = existing.slice(0, match.index ?? 0);
|
|
219
234
|
const after = existing.slice((match.index ?? 0) + match[0].length);
|
|
220
235
|
const filtered = `${before}${after.replace(/^\r?\n/, "")}`;
|
|
221
|
-
if (options.deleteWhenEmpty && isFrontMatterOnly(filtered)) {
|
|
222
|
-
try {
|
|
223
|
-
await rm(target, { force: true });
|
|
224
|
-
return { step, path: target, status: "removed", message: "front-matter-only" };
|
|
225
|
-
} catch (error) {
|
|
226
|
-
return {
|
|
227
|
-
step,
|
|
228
|
-
path: target,
|
|
229
|
-
status: "error",
|
|
230
|
-
message: error instanceof Error ? error.message : String(error)
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
236
|
try {
|
|
235
237
|
await atomicWriteText(target, filtered);
|
|
236
238
|
return { step, path: target, status: "removed" };
|
|
@@ -243,12 +245,6 @@ async function stripManagedBlock(projectRoot, relPath, options) {
|
|
|
243
245
|
};
|
|
244
246
|
}
|
|
245
247
|
}
|
|
246
|
-
function isFrontMatterOnly(content) {
|
|
247
|
-
const trimmed = content.replace(/^\s+/, "");
|
|
248
|
-
const match = trimmed.match(/^---\n[\s\S]*?\n---\s*$/);
|
|
249
|
-
if (match === null) return trimmed.length === 0;
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
248
|
async function deleteFabricAgentsSnapshot(projectRoot) {
|
|
253
249
|
const target = fabricAgentsSnapshotPath(projectRoot);
|
|
254
250
|
return rmIfExists("bootstrap-snapshot", target);
|
|
@@ -267,12 +263,6 @@ async function uninstallBootstrapStage(projectRoot, _opts = {}) {
|
|
|
267
263
|
projectRoot,
|
|
268
264
|
() => deleteFabricAgentsSnapshot(projectRoot)
|
|
269
265
|
);
|
|
270
|
-
await runAndCollectOne(
|
|
271
|
-
results,
|
|
272
|
-
"cursor-hook-config",
|
|
273
|
-
projectRoot,
|
|
274
|
-
() => unmergeCursorHookConfig(projectRoot)
|
|
275
|
-
);
|
|
276
266
|
await runAndCollectOne(
|
|
277
267
|
results,
|
|
278
268
|
"codex-hook-config",
|
|
@@ -304,6 +294,36 @@ async function uninstallBootstrapStage(projectRoot, _opts = {}) {
|
|
|
304
294
|
projectRoot,
|
|
305
295
|
() => removeArchiveHintHook(projectRoot)
|
|
306
296
|
);
|
|
297
|
+
await runAndCollect(
|
|
298
|
+
results,
|
|
299
|
+
"hook-cite-policy-evict-script",
|
|
300
|
+
projectRoot,
|
|
301
|
+
() => removeCitePolicyEvictHook(projectRoot)
|
|
302
|
+
);
|
|
303
|
+
await runAndCollect(
|
|
304
|
+
results,
|
|
305
|
+
"hook-session-end-script",
|
|
306
|
+
projectRoot,
|
|
307
|
+
() => removeSessionEndMarkerHook(projectRoot)
|
|
308
|
+
);
|
|
309
|
+
await runAndCollect(
|
|
310
|
+
results,
|
|
311
|
+
"hook-post-tooluse-script",
|
|
312
|
+
projectRoot,
|
|
313
|
+
() => removePostTooluseMutationHook(projectRoot)
|
|
314
|
+
);
|
|
315
|
+
await runAndCollect(
|
|
316
|
+
results,
|
|
317
|
+
"skill-connect",
|
|
318
|
+
projectRoot,
|
|
319
|
+
() => uninstallFabricConnectSkill(projectRoot)
|
|
320
|
+
);
|
|
321
|
+
await runAndCollect(
|
|
322
|
+
results,
|
|
323
|
+
"skill-audit",
|
|
324
|
+
projectRoot,
|
|
325
|
+
() => uninstallFabricAuditSkill(projectRoot)
|
|
326
|
+
);
|
|
307
327
|
await runAndCollect(
|
|
308
328
|
results,
|
|
309
329
|
"skill-sync",
|
|
@@ -328,6 +348,12 @@ async function uninstallBootstrapStage(projectRoot, _opts = {}) {
|
|
|
328
348
|
projectRoot,
|
|
329
349
|
() => uninstallFabricArchiveSkill(projectRoot)
|
|
330
350
|
);
|
|
351
|
+
await runAndCollect(
|
|
352
|
+
results,
|
|
353
|
+
"skill-router",
|
|
354
|
+
projectRoot,
|
|
355
|
+
() => uninstallFabricRouterSkill(projectRoot)
|
|
356
|
+
);
|
|
331
357
|
return results;
|
|
332
358
|
}
|
|
333
359
|
async function runAndCollect(results, step, projectRoot, fn) {
|
|
@@ -527,15 +553,6 @@ function jsonEqual(a, b) {
|
|
|
527
553
|
}
|
|
528
554
|
|
|
529
555
|
// src/commands/uninstall.ts
|
|
530
|
-
var UNINSTALL_WIZARD_GROUP_CANCELLED = /* @__PURE__ */ Symbol("uninstall-wizard-group-cancelled");
|
|
531
|
-
var KNOWLEDGE_SUBDIRS = [
|
|
532
|
-
"decisions",
|
|
533
|
-
"pitfalls",
|
|
534
|
-
"guidelines",
|
|
535
|
-
"models",
|
|
536
|
-
"processes",
|
|
537
|
-
"pending"
|
|
538
|
-
];
|
|
539
556
|
var FABRIC_STATE_FILES = ["agents.meta.json", "events.jsonl", "forensic.json"];
|
|
540
557
|
var uninstallCommand = defineCommand({
|
|
541
558
|
meta: {
|
|
@@ -650,21 +667,17 @@ async function buildUninstallExecutionPlan(target, options = {}) {
|
|
|
650
667
|
function buildUninstallFabricPlan(target, options = {}) {
|
|
651
668
|
const absTarget = normalizeTarget(target);
|
|
652
669
|
const fabricDir = join2(absTarget, ".fabric");
|
|
653
|
-
const
|
|
670
|
+
const globalStoresDir = join2(resolvePersonalFabricRoot(), ".fabric", "stores");
|
|
654
671
|
const entries = [];
|
|
655
672
|
for (const name of FABRIC_STATE_FILES) {
|
|
656
673
|
const p = join2(fabricDir, name);
|
|
657
674
|
entries.push({ path: p, kind: "state-file", absent: !existsSync2(p) });
|
|
658
675
|
}
|
|
659
|
-
|
|
660
|
-
const gk = join2(fabricDir, "knowledge", sub, ".gitkeep");
|
|
661
|
-
entries.push({ path: gk, kind: "gitkeep", absent: !existsSync2(gk) });
|
|
662
|
-
}
|
|
663
|
-
const safeEntries = entries.filter((entry) => !isInsidePersonalRoot(entry.path, personalKnowledgeDir));
|
|
676
|
+
const safeEntries = entries.filter((entry) => !isInsideGlobalStoresRoot(entry.path, globalStoresDir));
|
|
664
677
|
return {
|
|
665
678
|
target: absTarget,
|
|
666
679
|
fabricDir,
|
|
667
|
-
|
|
680
|
+
globalStoresDir,
|
|
668
681
|
options,
|
|
669
682
|
entries: safeEntries
|
|
670
683
|
};
|
|
@@ -699,8 +712,6 @@ function scaffoldStepLabel(kind) {
|
|
|
699
712
|
switch (kind) {
|
|
700
713
|
case "state-file":
|
|
701
714
|
return "scaffold-state";
|
|
702
|
-
case "gitkeep":
|
|
703
|
-
return "scaffold-gitkeep";
|
|
704
715
|
}
|
|
705
716
|
}
|
|
706
717
|
async function uninstallMcpClients(target, options = {}) {
|
|
@@ -774,12 +785,17 @@ async function uninstallMcpClients(target, options = {}) {
|
|
|
774
785
|
}
|
|
775
786
|
async function executeUninstallExecutionPlan(plan) {
|
|
776
787
|
const stageResults = [];
|
|
788
|
+
const totalStages = plan.stages.length;
|
|
789
|
+
console.log(t("cli.uninstall.plan.phase-banner", { total: String(totalStages) }));
|
|
790
|
+
let stepNum = 0;
|
|
777
791
|
for (const stage of plan.stages) {
|
|
792
|
+
stepNum += 1;
|
|
778
793
|
if (stage.skipped) {
|
|
794
|
+
console.log(formatUninstallStageHeader(stage.name, stepNum, totalStages, true));
|
|
779
795
|
stageResults.push({ name: stage.name, disposition: "skipped", steps: [] });
|
|
780
796
|
continue;
|
|
781
797
|
}
|
|
782
|
-
console.log(formatUninstallStageHeader(stage.name));
|
|
798
|
+
console.log(formatUninstallStageHeader(stage.name, stepNum, totalStages));
|
|
783
799
|
try {
|
|
784
800
|
const steps = await executeUninstallStage(plan, stage.name);
|
|
785
801
|
const disposition = steps.some((s) => s.status === "error") ? "failed" : "ran";
|
|
@@ -848,66 +864,36 @@ function createDefaultUninstallWizardAdapter() {
|
|
|
848
864
|
return {
|
|
849
865
|
async run(context) {
|
|
850
866
|
intro(t("cli.uninstall.wizard.intro"));
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
target: context.target
|
|
854
|
-
}),
|
|
855
|
-
t("cli.uninstall.wizard.overview.title")
|
|
867
|
+
const available = UNINSTALL_STAGE_KEYS.filter(
|
|
868
|
+
(key) => !context.lockedStages.includes(key)
|
|
856
869
|
);
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
870
|
+
const initialValues = available.filter((key) => !isStageSkipped(context.options, key));
|
|
871
|
+
const picked = await multiselect({
|
|
872
|
+
message: t("cli.uninstall.wizard.select.prompt", { target: context.target }),
|
|
873
|
+
options: available.map((key) => ({
|
|
874
|
+
value: key,
|
|
875
|
+
label: t(`cli.uninstall.wizard.select.${key}.label`),
|
|
876
|
+
hint: t(`cli.uninstall.wizard.select.${key}.hint`)
|
|
877
|
+
})),
|
|
878
|
+
initialValues,
|
|
879
|
+
required: false
|
|
862
880
|
});
|
|
863
|
-
if (isCancel(
|
|
881
|
+
if (isCancel(picked)) {
|
|
864
882
|
emitUninstallWizardCancellation();
|
|
865
883
|
return null;
|
|
866
884
|
}
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
message: t("cli.uninstall.wizard.stage.scaffold", {
|
|
874
|
-
defaultValue: formatPromptDefault(!context.options.skipScaffold)
|
|
875
|
-
}),
|
|
876
|
-
initialValue: !context.options.skipScaffold
|
|
877
|
-
}),
|
|
878
|
-
bootstrap: async () => context.lockedStages.includes("bootstrap") ? false : confirmInGroup({
|
|
879
|
-
message: t("cli.uninstall.wizard.stage.bootstrap", {
|
|
880
|
-
defaultValue: formatPromptDefault(!context.options.skipBootstrap)
|
|
881
|
-
}),
|
|
882
|
-
initialValue: !context.options.skipBootstrap
|
|
883
|
-
}),
|
|
884
|
-
mcp: async () => context.lockedStages.includes("mcp") ? false : confirmInGroup({
|
|
885
|
-
message: t("cli.uninstall.wizard.stage.mcp", {
|
|
886
|
-
defaultValue: formatPromptDefault(!context.options.skipMcp)
|
|
887
|
-
}),
|
|
888
|
-
initialValue: !context.options.skipMcp
|
|
889
|
-
})
|
|
890
|
-
},
|
|
891
|
-
{
|
|
892
|
-
onCancel() {
|
|
893
|
-
throw UNINSTALL_WIZARD_GROUP_CANCELLED;
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
);
|
|
897
|
-
} catch (error) {
|
|
898
|
-
if (error === UNINSTALL_WIZARD_GROUP_CANCELLED) {
|
|
899
|
-
emitUninstallWizardCancellation();
|
|
900
|
-
return null;
|
|
901
|
-
}
|
|
902
|
-
throw error;
|
|
903
|
-
}
|
|
885
|
+
const selected = new Set(picked);
|
|
886
|
+
const selection = {
|
|
887
|
+
scaffold: selected.has("scaffold"),
|
|
888
|
+
bootstrap: selected.has("bootstrap"),
|
|
889
|
+
mcp: selected.has("mcp")
|
|
890
|
+
};
|
|
904
891
|
const previewOptions = {
|
|
905
892
|
...context.options,
|
|
906
|
-
skipScaffold: !
|
|
907
|
-
skipBootstrap: !
|
|
908
|
-
skipMcp: !
|
|
893
|
+
skipScaffold: !selection.scaffold,
|
|
894
|
+
skipBootstrap: !selection.bootstrap,
|
|
895
|
+
skipMcp: !selection.mcp
|
|
909
896
|
};
|
|
910
|
-
log.step(t("cli.uninstall.wizard.step.review"));
|
|
911
897
|
printUninstallPlanSummary(context.target, previewOptions, context.supports);
|
|
912
898
|
const confirmed = await confirm({
|
|
913
899
|
message: t("cli.uninstall.wizard.execute.confirm"),
|
|
@@ -918,20 +904,24 @@ function createDefaultUninstallWizardAdapter() {
|
|
|
918
904
|
return null;
|
|
919
905
|
}
|
|
920
906
|
outro(t("cli.uninstall.wizard.outro"));
|
|
921
|
-
return
|
|
907
|
+
return selection;
|
|
922
908
|
}
|
|
923
909
|
};
|
|
924
910
|
}
|
|
911
|
+
var UNINSTALL_STAGE_KEYS = ["scaffold", "bootstrap", "mcp"];
|
|
912
|
+
function isStageSkipped(options, key) {
|
|
913
|
+
switch (key) {
|
|
914
|
+
case "scaffold":
|
|
915
|
+
return Boolean(options.skipScaffold);
|
|
916
|
+
case "bootstrap":
|
|
917
|
+
return Boolean(options.skipBootstrap);
|
|
918
|
+
case "mcp":
|
|
919
|
+
return Boolean(options.skipMcp);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
925
922
|
function emitUninstallWizardCancellation() {
|
|
926
923
|
cancel(t("cli.uninstall.wizard.cancelled"));
|
|
927
924
|
}
|
|
928
|
-
async function confirmInGroup(options) {
|
|
929
|
-
const result = await confirm(options);
|
|
930
|
-
if (isCancel(result)) {
|
|
931
|
-
throw UNINSTALL_WIZARD_GROUP_CANCELLED;
|
|
932
|
-
}
|
|
933
|
-
return result;
|
|
934
|
-
}
|
|
935
925
|
async function confirmDestructive(plan) {
|
|
936
926
|
printUninstallPlanSummary(plan.target, plan.options, plan.supports);
|
|
937
927
|
const answer = await confirm({
|
|
@@ -978,8 +968,7 @@ function printUninstallPlanSummary(target, options, supports) {
|
|
|
978
968
|
})
|
|
979
969
|
);
|
|
980
970
|
console.log(t("cli.uninstall.plan.preserves"));
|
|
981
|
-
console.log(` -
|
|
982
|
-
console.log(` - ~/.fabric/knowledge/ ${paint.muted(t("cli.uninstall.plan.preserves.personal"))}`);
|
|
971
|
+
console.log(` - ~/.fabric/stores/ ${paint.muted(t("cli.uninstall.plan.preserves.stores"))}`);
|
|
983
972
|
}
|
|
984
973
|
function printUninstallSummary(result) {
|
|
985
974
|
const removed = result.stageResults.flatMap(
|
|
@@ -1007,8 +996,10 @@ function printUninstallSummary(result) {
|
|
|
1007
996
|
}
|
|
1008
997
|
}
|
|
1009
998
|
}
|
|
1010
|
-
function formatUninstallStageHeader(stageName) {
|
|
1011
|
-
|
|
999
|
+
function formatUninstallStageHeader(stageName, stepNum, total, skipped = false) {
|
|
1000
|
+
const label = t(`cli.uninstall.stages.${stageName}`);
|
|
1001
|
+
const head = `[${stepNum}/${total}] ${label}`;
|
|
1002
|
+
return skipped ? paint.muted(`${head} (${t("cli.shared.skipped")})`) : head;
|
|
1012
1003
|
}
|
|
1013
1004
|
function formatUninstallStageResult(stageName, steps) {
|
|
1014
1005
|
const removedCount = steps.filter((s) => s.status === "removed").length;
|
|
@@ -1025,9 +1016,9 @@ function formatUninstallStageFailure(stage, error) {
|
|
|
1025
1016
|
function resolvePersonalFabricRoot() {
|
|
1026
1017
|
return process.env.FABRIC_HOME ?? homedir();
|
|
1027
1018
|
}
|
|
1028
|
-
function
|
|
1019
|
+
function isInsideGlobalStoresRoot(candidate, globalStoresDir) {
|
|
1029
1020
|
const candidateAbs = resolve(candidate);
|
|
1030
|
-
const rootAbs = resolve(
|
|
1021
|
+
const rootAbs = resolve(globalStoresDir);
|
|
1031
1022
|
if (candidateAbs === rootAbs) {
|
|
1032
1023
|
return true;
|
|
1033
1024
|
}
|
|
@@ -1045,9 +1036,6 @@ function assertExistingDirectory(target) {
|
|
|
1045
1036
|
function isInteractiveUninstall() {
|
|
1046
1037
|
return Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY) && Boolean(process.stderr.isTTY);
|
|
1047
1038
|
}
|
|
1048
|
-
function formatPromptDefault(value) {
|
|
1049
|
-
return value ? "Y/n" : "y/N";
|
|
1050
|
-
}
|
|
1051
1039
|
function yesNoLabel(value) {
|
|
1052
1040
|
return value ? t("cli.shared.yes") : t("cli.shared.no");
|
|
1053
1041
|
}
|
|
@@ -1063,7 +1051,7 @@ export {
|
|
|
1063
1051
|
uninstall_default as default,
|
|
1064
1052
|
executeUninstallExecutionPlan,
|
|
1065
1053
|
executeUninstallFabricPlan,
|
|
1066
|
-
|
|
1054
|
+
isInsideGlobalStoresRoot,
|
|
1067
1055
|
resolveUninstallExecutionPlanWithWizard,
|
|
1068
1056
|
runUninstallCommand,
|
|
1069
1057
|
shouldUseUninstallWizard,
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
warnUnknownFlags,
|
|
4
|
+
whoami
|
|
5
|
+
} from "./chunk-27HK6H5Y.js";
|
|
6
|
+
import "./chunk-QPAW6IYT.js";
|
|
7
|
+
import "./chunk-QFIVFZRH.js";
|
|
8
|
+
import "./chunk-FNHDQTPC.js";
|
|
9
|
+
import {
|
|
10
|
+
getProjectTranslator
|
|
11
|
+
} from "./chunk-HORSMSZL.js";
|
|
12
|
+
|
|
13
|
+
// src/commands/whoami.ts
|
|
14
|
+
import { defineCommand } from "citty";
|
|
15
|
+
var whoami_default = defineCommand({
|
|
16
|
+
meta: { name: "whoami", description: "[DEPRECATED] Use 'fabric info --global' instead" },
|
|
17
|
+
args: {
|
|
18
|
+
// F27: `--json` machine-readable output (was silently ignored — the command
|
|
19
|
+
// declared no args, so citty swallowed the flag and still printed text).
|
|
20
|
+
json: { type: "boolean", description: "Emit machine-readable JSON instead of text" }
|
|
21
|
+
},
|
|
22
|
+
run({ args }) {
|
|
23
|
+
warnUnknownFlags(["json"]);
|
|
24
|
+
console.error("\u26A0\uFE0F DEPRECATED: 'fabric whoami' is deprecated. Use 'fabric info --global' instead.");
|
|
25
|
+
const info = whoami();
|
|
26
|
+
if (args.json === true) {
|
|
27
|
+
console.log(JSON.stringify(info, null, 2));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const t = getProjectTranslator();
|
|
31
|
+
if (info === null) {
|
|
32
|
+
console.log(t("cli.cmd.no-global-config"));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
console.log(t("cli.whoami.uid", { uid: info.uid }));
|
|
36
|
+
if (info.stores.length === 0) {
|
|
37
|
+
console.log(t("cli.whoami.stores-none"));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.log(t("cli.whoami.stores-label"));
|
|
41
|
+
const localOnly = t("cli.shared.local-only");
|
|
42
|
+
for (const store of info.stores) {
|
|
43
|
+
console.log(` ${store.alias} ${store.store_uuid}${store.local_only ? ` ${localOnly}` : ""}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
export {
|
|
48
|
+
whoami_default as default
|
|
49
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fenglimg/fabric-cli",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Fabric CLI — installs the MCP server + skills + hooks for Claude Code
|
|
3
|
+
"version": "2.2.0-rc.10",
|
|
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>",
|
|
7
7
|
"homepage": "https://github.com/fenglimg/fabric-v2#readme",
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"mcp",
|
|
19
19
|
"cli",
|
|
20
20
|
"claude-code",
|
|
21
|
-
"cursor",
|
|
22
21
|
"codex-cli",
|
|
23
22
|
"ai-knowledge-management"
|
|
24
23
|
],
|
|
@@ -40,16 +39,19 @@
|
|
|
40
39
|
"dependencies": {
|
|
41
40
|
"@clack/prompts": "^1.2.0",
|
|
42
41
|
"citty": "^0.2.2",
|
|
42
|
+
"ink": "^4.4.1",
|
|
43
43
|
"picocolors": "^1.1.1",
|
|
44
|
+
"react": "^18.3.1",
|
|
44
45
|
"string-width": "^7.2.0",
|
|
45
46
|
"tree-sitter-javascript": "^0.25.0",
|
|
46
47
|
"tree-sitter-typescript": "^0.23.2",
|
|
47
48
|
"web-tree-sitter": "^0.26.8",
|
|
48
|
-
"@fenglimg/fabric-server": "2.
|
|
49
|
-
"@fenglimg/fabric-shared": "2.
|
|
49
|
+
"@fenglimg/fabric-server": "2.2.0-rc.10",
|
|
50
|
+
"@fenglimg/fabric-shared": "2.2.0-rc.10"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@types/node": "^22.15.0",
|
|
54
|
+
"@types/react": "^18.3.12",
|
|
53
55
|
"tsup": "^8.5.0",
|
|
54
56
|
"typescript": "^5.8.3"
|
|
55
57
|
},
|