@fenglimg/fabric-cli 2.2.0-rc.1 → 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-AOE6AYI7.js → chunk-2KBCTMID.js} +31 -8
- package/dist/chunk-3D7B2UAZ.js +149 -0
- package/dist/{chunk-XC5RUHLK.js → chunk-3IOLS5EK.js} +23 -38
- package/dist/{plan-context-hint-FC6P3WFE.js → chunk-722JU5BP.js} +52 -12
- package/dist/{chunk-2R55HNVD.js → chunk-7ZDXBOOU.js} +234 -206
- package/dist/{doctor-YONYXDX6.js → chunk-E7HJUU34.js} +215 -52
- package/dist/chunk-EOT63RDH.js +36 -0
- package/dist/chunk-FNHDQTPC.js +16 -0
- package/dist/{chunk-2CY4BMTH.js → chunk-HORSMSZL.js} +9 -5
- package/dist/{chunk-BO4XIZWZ.js → chunk-NLNH64A3.js} +5 -18
- 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-XYRBZJDU.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 +133 -22
- package/dist/info-7FKBTMVO.js +139 -0
- package/dist/install-v2-RINEA24K.js +3279 -0
- package/dist/{metrics-RER6NLFC.js → metrics-HMFH4YHK.js} +1 -1
- package/dist/{onboard-coverage-JWQWDZW7.js → onboard-coverage-XSG77LL3.js} +48 -27
- package/dist/plan-context-hint-5TNGH3R4.js +12 -0
- package/dist/{scope-explain-CDIZESP5.js → scope-explain-HLJZ2M33.js} +17 -6
- package/dist/status-4R3TM4FJ.js +37 -0
- package/dist/store-HOCORVL3.js +563 -0
- package/dist/{sync-UJ4BBCZJ.js → sync-DT5UJMMR.js} +197 -30
- package/dist/{uninstall-C3QXKOO6.js → uninstall-IFN2KYBK.js} +97 -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 +477 -176
- package/templates/hooks/knowledge-hint-broad.cjs +577 -274
- package/templates/hooks/knowledge-hint-narrow.cjs +113 -73
- 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/nudge-policy.cjs +117 -0
- package/templates/hooks/lib/state-store.cjs +60 -0
- 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 +13 -3
- package/templates/skills/fabric-connect/SKILL.md +3 -3
- 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 +14 -5
- package/templates/skills/fabric-review/ref/cite-contract.md +1 -1
- 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 +1 -1
- package/templates/skills/fabric-sync/SKILL.md +1 -1
- package/templates/skills/lib/shared-policy.md +2 -2
- package/dist/chunk-4R2CYEA4.js +0 -116
- package/dist/chunk-L4Q55UC4.js +0 -52
- package/dist/chunk-LFIKMVY7.js +0 -27
- package/dist/chunk-RYAFBNES.js +0 -33
- package/dist/chunk-T5RPGCCM.js +0 -40
- package/dist/install-74ANPCCP.js +0 -2737
- package/dist/status-GLQWLWH6.js +0 -23
- package/dist/store-XB3ADT65.js +0 -144
- package/dist/whoami-2MLO4Y37.js +0 -36
- 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-BO4XIZWZ.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
|
}
|
|
@@ -88,6 +91,20 @@ async function removeCitePolicyEvictHook(projectRoot) {
|
|
|
88
91
|
projectRoot
|
|
89
92
|
);
|
|
90
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
|
+
}
|
|
91
108
|
async function removeHookScripts(step, rels, projectRoot) {
|
|
92
109
|
const results = [];
|
|
93
110
|
for (const rel of rels) {
|
|
@@ -144,25 +161,10 @@ async function unmergeCodexHookConfig(projectRoot) {
|
|
|
144
161
|
extractCommands: extractFlatCommands
|
|
145
162
|
});
|
|
146
163
|
}
|
|
147
|
-
async function unmergeCursorHookConfig(projectRoot) {
|
|
148
|
-
return unmergeHookConfig({
|
|
149
|
-
step: "cursor-hook-config",
|
|
150
|
-
projectRoot,
|
|
151
|
-
configRel: HOOK_CONFIG_TARGETS.cursor,
|
|
152
|
-
arrayPaths: [...HOOK_CONFIG_ARRAY_PATHS.cursor],
|
|
153
|
-
fabricCommands: Object.values(FABRIC_HOOK_COMMAND_PATHS.cursor),
|
|
154
|
-
extractCommands: extractFlatCommands
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
164
|
async function stripFabricBootstrapBlocks(projectRoot) {
|
|
158
165
|
const results = [];
|
|
159
166
|
results.push(await stripClaudeBootstrapImports(projectRoot));
|
|
160
|
-
results.push(await stripManagedBlock(projectRoot, "AGENTS.md"
|
|
161
|
-
results.push(
|
|
162
|
-
await stripManagedBlock(projectRoot, join(".cursor", "rules", "fabric-bootstrap.mdc"), {
|
|
163
|
-
deleteWhenEmpty: true
|
|
164
|
-
})
|
|
165
|
-
);
|
|
167
|
+
results.push(await stripManagedBlock(projectRoot, "AGENTS.md"));
|
|
166
168
|
return results;
|
|
167
169
|
}
|
|
168
170
|
async function stripClaudeBootstrapImports(projectRoot) {
|
|
@@ -207,8 +209,8 @@ async function stripClaudeBootstrapImports(projectRoot) {
|
|
|
207
209
|
};
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
|
-
async function stripManagedBlock(projectRoot, relPath
|
|
211
|
-
const step =
|
|
212
|
+
async function stripManagedBlock(projectRoot, relPath) {
|
|
213
|
+
const step = "bootstrap-codex";
|
|
212
214
|
const target = join(projectRoot, relPath);
|
|
213
215
|
if (!existsSync(target)) {
|
|
214
216
|
return { step, path: target, status: "skipped", message: "absent" };
|
|
@@ -231,19 +233,6 @@ async function stripManagedBlock(projectRoot, relPath, options) {
|
|
|
231
233
|
const before = existing.slice(0, match.index ?? 0);
|
|
232
234
|
const after = existing.slice((match.index ?? 0) + match[0].length);
|
|
233
235
|
const filtered = `${before}${after.replace(/^\r?\n/, "")}`;
|
|
234
|
-
if (options.deleteWhenEmpty && isFrontMatterOnly(filtered)) {
|
|
235
|
-
try {
|
|
236
|
-
await rm(target, { force: true });
|
|
237
|
-
return { step, path: target, status: "removed", message: "front-matter-only" };
|
|
238
|
-
} catch (error) {
|
|
239
|
-
return {
|
|
240
|
-
step,
|
|
241
|
-
path: target,
|
|
242
|
-
status: "error",
|
|
243
|
-
message: error instanceof Error ? error.message : String(error)
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
236
|
try {
|
|
248
237
|
await atomicWriteText(target, filtered);
|
|
249
238
|
return { step, path: target, status: "removed" };
|
|
@@ -256,12 +245,6 @@ async function stripManagedBlock(projectRoot, relPath, options) {
|
|
|
256
245
|
};
|
|
257
246
|
}
|
|
258
247
|
}
|
|
259
|
-
function isFrontMatterOnly(content) {
|
|
260
|
-
const trimmed = content.replace(/^\s+/, "");
|
|
261
|
-
const match = trimmed.match(/^---\n[\s\S]*?\n---\s*$/);
|
|
262
|
-
if (match === null) return trimmed.length === 0;
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
265
248
|
async function deleteFabricAgentsSnapshot(projectRoot) {
|
|
266
249
|
const target = fabricAgentsSnapshotPath(projectRoot);
|
|
267
250
|
return rmIfExists("bootstrap-snapshot", target);
|
|
@@ -280,12 +263,6 @@ async function uninstallBootstrapStage(projectRoot, _opts = {}) {
|
|
|
280
263
|
projectRoot,
|
|
281
264
|
() => deleteFabricAgentsSnapshot(projectRoot)
|
|
282
265
|
);
|
|
283
|
-
await runAndCollectOne(
|
|
284
|
-
results,
|
|
285
|
-
"cursor-hook-config",
|
|
286
|
-
projectRoot,
|
|
287
|
-
() => unmergeCursorHookConfig(projectRoot)
|
|
288
|
-
);
|
|
289
266
|
await runAndCollectOne(
|
|
290
267
|
results,
|
|
291
268
|
"codex-hook-config",
|
|
@@ -323,6 +300,18 @@ async function uninstallBootstrapStage(projectRoot, _opts = {}) {
|
|
|
323
300
|
projectRoot,
|
|
324
301
|
() => removeCitePolicyEvictHook(projectRoot)
|
|
325
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
|
+
);
|
|
326
315
|
await runAndCollect(
|
|
327
316
|
results,
|
|
328
317
|
"skill-connect",
|
|
@@ -359,6 +348,12 @@ async function uninstallBootstrapStage(projectRoot, _opts = {}) {
|
|
|
359
348
|
projectRoot,
|
|
360
349
|
() => uninstallFabricArchiveSkill(projectRoot)
|
|
361
350
|
);
|
|
351
|
+
await runAndCollect(
|
|
352
|
+
results,
|
|
353
|
+
"skill-router",
|
|
354
|
+
projectRoot,
|
|
355
|
+
() => uninstallFabricRouterSkill(projectRoot)
|
|
356
|
+
);
|
|
362
357
|
return results;
|
|
363
358
|
}
|
|
364
359
|
async function runAndCollect(results, step, projectRoot, fn) {
|
|
@@ -558,15 +553,6 @@ function jsonEqual(a, b) {
|
|
|
558
553
|
}
|
|
559
554
|
|
|
560
555
|
// src/commands/uninstall.ts
|
|
561
|
-
var UNINSTALL_WIZARD_GROUP_CANCELLED = /* @__PURE__ */ Symbol("uninstall-wizard-group-cancelled");
|
|
562
|
-
var KNOWLEDGE_SUBDIRS = [
|
|
563
|
-
"decisions",
|
|
564
|
-
"pitfalls",
|
|
565
|
-
"guidelines",
|
|
566
|
-
"models",
|
|
567
|
-
"processes",
|
|
568
|
-
"pending"
|
|
569
|
-
];
|
|
570
556
|
var FABRIC_STATE_FILES = ["agents.meta.json", "events.jsonl", "forensic.json"];
|
|
571
557
|
var uninstallCommand = defineCommand({
|
|
572
558
|
meta: {
|
|
@@ -681,21 +667,17 @@ async function buildUninstallExecutionPlan(target, options = {}) {
|
|
|
681
667
|
function buildUninstallFabricPlan(target, options = {}) {
|
|
682
668
|
const absTarget = normalizeTarget(target);
|
|
683
669
|
const fabricDir = join2(absTarget, ".fabric");
|
|
684
|
-
const
|
|
670
|
+
const globalStoresDir = join2(resolvePersonalFabricRoot(), ".fabric", "stores");
|
|
685
671
|
const entries = [];
|
|
686
672
|
for (const name of FABRIC_STATE_FILES) {
|
|
687
673
|
const p = join2(fabricDir, name);
|
|
688
674
|
entries.push({ path: p, kind: "state-file", absent: !existsSync2(p) });
|
|
689
675
|
}
|
|
690
|
-
|
|
691
|
-
const gk = join2(fabricDir, "knowledge", sub, ".gitkeep");
|
|
692
|
-
entries.push({ path: gk, kind: "gitkeep", absent: !existsSync2(gk) });
|
|
693
|
-
}
|
|
694
|
-
const safeEntries = entries.filter((entry) => !isInsidePersonalRoot(entry.path, personalKnowledgeDir));
|
|
676
|
+
const safeEntries = entries.filter((entry) => !isInsideGlobalStoresRoot(entry.path, globalStoresDir));
|
|
695
677
|
return {
|
|
696
678
|
target: absTarget,
|
|
697
679
|
fabricDir,
|
|
698
|
-
|
|
680
|
+
globalStoresDir,
|
|
699
681
|
options,
|
|
700
682
|
entries: safeEntries
|
|
701
683
|
};
|
|
@@ -730,8 +712,6 @@ function scaffoldStepLabel(kind) {
|
|
|
730
712
|
switch (kind) {
|
|
731
713
|
case "state-file":
|
|
732
714
|
return "scaffold-state";
|
|
733
|
-
case "gitkeep":
|
|
734
|
-
return "scaffold-gitkeep";
|
|
735
715
|
}
|
|
736
716
|
}
|
|
737
717
|
async function uninstallMcpClients(target, options = {}) {
|
|
@@ -805,12 +785,17 @@ async function uninstallMcpClients(target, options = {}) {
|
|
|
805
785
|
}
|
|
806
786
|
async function executeUninstallExecutionPlan(plan) {
|
|
807
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;
|
|
808
791
|
for (const stage of plan.stages) {
|
|
792
|
+
stepNum += 1;
|
|
809
793
|
if (stage.skipped) {
|
|
794
|
+
console.log(formatUninstallStageHeader(stage.name, stepNum, totalStages, true));
|
|
810
795
|
stageResults.push({ name: stage.name, disposition: "skipped", steps: [] });
|
|
811
796
|
continue;
|
|
812
797
|
}
|
|
813
|
-
console.log(formatUninstallStageHeader(stage.name));
|
|
798
|
+
console.log(formatUninstallStageHeader(stage.name, stepNum, totalStages));
|
|
814
799
|
try {
|
|
815
800
|
const steps = await executeUninstallStage(plan, stage.name);
|
|
816
801
|
const disposition = steps.some((s) => s.status === "error") ? "failed" : "ran";
|
|
@@ -879,66 +864,36 @@ function createDefaultUninstallWizardAdapter() {
|
|
|
879
864
|
return {
|
|
880
865
|
async run(context) {
|
|
881
866
|
intro(t("cli.uninstall.wizard.intro"));
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
target: context.target
|
|
885
|
-
}),
|
|
886
|
-
t("cli.uninstall.wizard.overview.title")
|
|
867
|
+
const available = UNINSTALL_STAGE_KEYS.filter(
|
|
868
|
+
(key) => !context.lockedStages.includes(key)
|
|
887
869
|
);
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
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
|
|
893
880
|
});
|
|
894
|
-
if (isCancel(
|
|
881
|
+
if (isCancel(picked)) {
|
|
895
882
|
emitUninstallWizardCancellation();
|
|
896
883
|
return null;
|
|
897
884
|
}
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
message: t("cli.uninstall.wizard.stage.scaffold", {
|
|
905
|
-
defaultValue: formatPromptDefault(!context.options.skipScaffold)
|
|
906
|
-
}),
|
|
907
|
-
initialValue: !context.options.skipScaffold
|
|
908
|
-
}),
|
|
909
|
-
bootstrap: async () => context.lockedStages.includes("bootstrap") ? false : confirmInGroup({
|
|
910
|
-
message: t("cli.uninstall.wizard.stage.bootstrap", {
|
|
911
|
-
defaultValue: formatPromptDefault(!context.options.skipBootstrap)
|
|
912
|
-
}),
|
|
913
|
-
initialValue: !context.options.skipBootstrap
|
|
914
|
-
}),
|
|
915
|
-
mcp: async () => context.lockedStages.includes("mcp") ? false : confirmInGroup({
|
|
916
|
-
message: t("cli.uninstall.wizard.stage.mcp", {
|
|
917
|
-
defaultValue: formatPromptDefault(!context.options.skipMcp)
|
|
918
|
-
}),
|
|
919
|
-
initialValue: !context.options.skipMcp
|
|
920
|
-
})
|
|
921
|
-
},
|
|
922
|
-
{
|
|
923
|
-
onCancel() {
|
|
924
|
-
throw UNINSTALL_WIZARD_GROUP_CANCELLED;
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
);
|
|
928
|
-
} catch (error) {
|
|
929
|
-
if (error === UNINSTALL_WIZARD_GROUP_CANCELLED) {
|
|
930
|
-
emitUninstallWizardCancellation();
|
|
931
|
-
return null;
|
|
932
|
-
}
|
|
933
|
-
throw error;
|
|
934
|
-
}
|
|
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
|
+
};
|
|
935
891
|
const previewOptions = {
|
|
936
892
|
...context.options,
|
|
937
|
-
skipScaffold: !
|
|
938
|
-
skipBootstrap: !
|
|
939
|
-
skipMcp: !
|
|
893
|
+
skipScaffold: !selection.scaffold,
|
|
894
|
+
skipBootstrap: !selection.bootstrap,
|
|
895
|
+
skipMcp: !selection.mcp
|
|
940
896
|
};
|
|
941
|
-
log.step(t("cli.uninstall.wizard.step.review"));
|
|
942
897
|
printUninstallPlanSummary(context.target, previewOptions, context.supports);
|
|
943
898
|
const confirmed = await confirm({
|
|
944
899
|
message: t("cli.uninstall.wizard.execute.confirm"),
|
|
@@ -949,20 +904,24 @@ function createDefaultUninstallWizardAdapter() {
|
|
|
949
904
|
return null;
|
|
950
905
|
}
|
|
951
906
|
outro(t("cli.uninstall.wizard.outro"));
|
|
952
|
-
return
|
|
907
|
+
return selection;
|
|
953
908
|
}
|
|
954
909
|
};
|
|
955
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
|
+
}
|
|
956
922
|
function emitUninstallWizardCancellation() {
|
|
957
923
|
cancel(t("cli.uninstall.wizard.cancelled"));
|
|
958
924
|
}
|
|
959
|
-
async function confirmInGroup(options) {
|
|
960
|
-
const result = await confirm(options);
|
|
961
|
-
if (isCancel(result)) {
|
|
962
|
-
throw UNINSTALL_WIZARD_GROUP_CANCELLED;
|
|
963
|
-
}
|
|
964
|
-
return result;
|
|
965
|
-
}
|
|
966
925
|
async function confirmDestructive(plan) {
|
|
967
926
|
printUninstallPlanSummary(plan.target, plan.options, plan.supports);
|
|
968
927
|
const answer = await confirm({
|
|
@@ -1009,8 +968,7 @@ function printUninstallPlanSummary(target, options, supports) {
|
|
|
1009
968
|
})
|
|
1010
969
|
);
|
|
1011
970
|
console.log(t("cli.uninstall.plan.preserves"));
|
|
1012
|
-
console.log(` -
|
|
1013
|
-
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"))}`);
|
|
1014
972
|
}
|
|
1015
973
|
function printUninstallSummary(result) {
|
|
1016
974
|
const removed = result.stageResults.flatMap(
|
|
@@ -1038,8 +996,10 @@ function printUninstallSummary(result) {
|
|
|
1038
996
|
}
|
|
1039
997
|
}
|
|
1040
998
|
}
|
|
1041
|
-
function formatUninstallStageHeader(stageName) {
|
|
1042
|
-
|
|
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;
|
|
1043
1003
|
}
|
|
1044
1004
|
function formatUninstallStageResult(stageName, steps) {
|
|
1045
1005
|
const removedCount = steps.filter((s) => s.status === "removed").length;
|
|
@@ -1056,9 +1016,9 @@ function formatUninstallStageFailure(stage, error) {
|
|
|
1056
1016
|
function resolvePersonalFabricRoot() {
|
|
1057
1017
|
return process.env.FABRIC_HOME ?? homedir();
|
|
1058
1018
|
}
|
|
1059
|
-
function
|
|
1019
|
+
function isInsideGlobalStoresRoot(candidate, globalStoresDir) {
|
|
1060
1020
|
const candidateAbs = resolve(candidate);
|
|
1061
|
-
const rootAbs = resolve(
|
|
1021
|
+
const rootAbs = resolve(globalStoresDir);
|
|
1062
1022
|
if (candidateAbs === rootAbs) {
|
|
1063
1023
|
return true;
|
|
1064
1024
|
}
|
|
@@ -1076,9 +1036,6 @@ function assertExistingDirectory(target) {
|
|
|
1076
1036
|
function isInteractiveUninstall() {
|
|
1077
1037
|
return Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY) && Boolean(process.stderr.isTTY);
|
|
1078
1038
|
}
|
|
1079
|
-
function formatPromptDefault(value) {
|
|
1080
|
-
return value ? "Y/n" : "y/N";
|
|
1081
|
-
}
|
|
1082
1039
|
function yesNoLabel(value) {
|
|
1083
1040
|
return value ? t("cli.shared.yes") : t("cli.shared.no");
|
|
1084
1041
|
}
|
|
@@ -1094,7 +1051,7 @@ export {
|
|
|
1094
1051
|
uninstall_default as default,
|
|
1095
1052
|
executeUninstallExecutionPlan,
|
|
1096
1053
|
executeUninstallFabricPlan,
|
|
1097
|
-
|
|
1054
|
+
isInsideGlobalStoresRoot,
|
|
1098
1055
|
resolveUninstallExecutionPlanWithWizard,
|
|
1099
1056
|
runUninstallCommand,
|
|
1100
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.2.0-rc.
|
|
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.2.0-rc.
|
|
49
|
-
"@fenglimg/fabric-shared": "2.2.0-rc.
|
|
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
|
},
|