@fenglimg/fabric-cli 2.2.0-rc.9 → 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-YM4XATJF.js → chunk-722JU5BP.js} +2 -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 +91 -81
- package/dist/{info-7FKBTMVO.js → info-NJEY26H6.js} +91 -46
- package/dist/{context-7NUKXDB6.js → inspect-5YZMJPFM.js} +11 -11
- package/dist/{install-v2-I6PJ6IFT.js → install-v2-KGIDII4H.js} +163 -364
- package/dist/{plan-context-hint-G75R4P4J.js → plan-context-hint-5TNGH3R4.js} +1 -1
- 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 +346 -138
- package/templates/hooks/knowledge-hint-broad.cjs +265 -75
- package/templates/hooks/knowledge-hint-narrow.cjs +3 -3
- package/templates/hooks/knowledge-pretooluse.cjs +111 -0
- package/templates/hooks/lib/banner-i18n.cjs +31 -12
- 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 +43 -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 +28 -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
|
@@ -4,16 +4,13 @@ import {
|
|
|
4
4
|
installArchiveHintHook,
|
|
5
5
|
installCitePolicyEvictHook,
|
|
6
6
|
installFabricArchiveSkill,
|
|
7
|
-
installFabricAuditSkill,
|
|
8
|
-
installFabricConnectSkill,
|
|
9
|
-
installFabricImportSkill,
|
|
10
7
|
installFabricReviewSkill,
|
|
11
|
-
installFabricRouterSkill,
|
|
12
8
|
installFabricStoreSkill,
|
|
13
9
|
installFabricSyncSkill,
|
|
14
10
|
installHookLibs,
|
|
15
11
|
installKnowledgeHintBroadHook,
|
|
16
12
|
installKnowledgeHintNarrowHook,
|
|
13
|
+
installKnowledgePretoolUseHook,
|
|
17
14
|
installPostTooluseMutationHook,
|
|
18
15
|
installSessionEndMarkerHook,
|
|
19
16
|
installSharedSkillLib,
|
|
@@ -22,38 +19,39 @@ import {
|
|
|
22
19
|
writeClaudeBootstrapThinShell,
|
|
23
20
|
writeCodexBootstrapManagedBlock,
|
|
24
21
|
writeFabricAgentsSnapshot
|
|
25
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ACSMNX3V.js";
|
|
23
|
+
import {
|
|
24
|
+
installMcpClients
|
|
25
|
+
} from "./chunk-2KBCTMID.js";
|
|
26
|
+
import {
|
|
27
|
+
detectClientSupports
|
|
28
|
+
} from "./chunk-3IOLS5EK.js";
|
|
26
29
|
import {
|
|
27
30
|
ensureStoreProjectBinding,
|
|
31
|
+
grid,
|
|
28
32
|
migrateRootConfig,
|
|
29
33
|
normalizeStoreProjectId,
|
|
30
|
-
suggestStoreProjectId
|
|
31
|
-
|
|
34
|
+
suggestStoreProjectId,
|
|
35
|
+
tree
|
|
36
|
+
} from "./chunk-VQKXTMWH.js";
|
|
32
37
|
import {
|
|
33
38
|
createDebugLogger,
|
|
34
39
|
resolveDevMode
|
|
35
40
|
} from "./chunk-WA3DYGSY.js";
|
|
36
|
-
import {
|
|
37
|
-
installMcpClients
|
|
38
|
-
} from "./chunk-2KBCTMID.js";
|
|
39
|
-
import {
|
|
40
|
-
detectClientSupports
|
|
41
|
-
} from "./chunk-3IOLS5EK.js";
|
|
42
41
|
import {
|
|
43
42
|
paint
|
|
44
|
-
} from "./chunk-
|
|
45
|
-
import "./chunk-
|
|
46
|
-
import "./chunk-EOT63RDH.js";
|
|
43
|
+
} from "./chunk-SL77FXX7.js";
|
|
44
|
+
import "./chunk-GGDVZCD6.js";
|
|
47
45
|
import {
|
|
48
46
|
storeCreate,
|
|
49
47
|
storeList,
|
|
50
48
|
storeProjectList,
|
|
51
49
|
syncStoreAliasLinks,
|
|
52
50
|
unboundAvailableStores
|
|
53
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-7V4XMLQ2.js";
|
|
54
52
|
import {
|
|
55
53
|
loadProjectConfig
|
|
56
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-I5F5BHWI.js";
|
|
57
55
|
import {
|
|
58
56
|
globalConfigPath,
|
|
59
57
|
loadGlobalConfig,
|
|
@@ -1142,17 +1140,17 @@ async function analyzeImports(relativePath, snippet) {
|
|
|
1142
1140
|
}
|
|
1143
1141
|
async function extractImports(source, languageKind) {
|
|
1144
1142
|
const { parser } = await loadTreeSitter(languageKind);
|
|
1145
|
-
let
|
|
1143
|
+
let tree2 = null;
|
|
1146
1144
|
try {
|
|
1147
|
-
|
|
1148
|
-
if (
|
|
1145
|
+
tree2 = parser.parse(source);
|
|
1146
|
+
if (tree2 === null || tree2.rootNode.hasError) {
|
|
1149
1147
|
throw new Error("tree-sitter parse failed");
|
|
1150
1148
|
}
|
|
1151
1149
|
const imports = [];
|
|
1152
|
-
collectImportSources(
|
|
1150
|
+
collectImportSources(tree2.rootNode, imports);
|
|
1153
1151
|
return compactPatternNames(imports);
|
|
1154
1152
|
} finally {
|
|
1155
|
-
|
|
1153
|
+
tree2?.delete();
|
|
1156
1154
|
}
|
|
1157
1155
|
}
|
|
1158
1156
|
async function loadTreeSitter(languageKind) {
|
|
@@ -1738,7 +1736,7 @@ function readProjectName(target) {
|
|
|
1738
1736
|
return basename(target);
|
|
1739
1737
|
}
|
|
1740
1738
|
function getCliVersion() {
|
|
1741
|
-
return true ? "2.
|
|
1739
|
+
return true ? "2.3.0-rc.1" : "unknown";
|
|
1742
1740
|
}
|
|
1743
1741
|
function sortRecord(record) {
|
|
1744
1742
|
return Object.fromEntries(Object.entries(record).sort(([left], [right]) => left.localeCompare(right)));
|
|
@@ -1848,15 +1846,9 @@ var EnvStage = class {
|
|
|
1848
1846
|
maintenance_hint_cooldown_days: 7,
|
|
1849
1847
|
archive_edit_threshold: 20,
|
|
1850
1848
|
underseed_node_threshold: 10,
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
import_max_commits_scan: 500,
|
|
1855
|
-
import_skip_canonical_threshold: 50,
|
|
1856
|
-
archive_max_candidates_per_batch: 8,
|
|
1857
|
-
archive_max_recent_paths: 20,
|
|
1858
|
-
archive_digest_max_sessions: 10,
|
|
1859
|
-
review_topic_result_cap: 8,
|
|
1849
|
+
// ux-w2-3: import_*/archive_max_*/review_topic_result_cap skill thresholds
|
|
1850
|
+
// hardcoded (✂ census Table 1) — no longer scaffolded; skills fall to a
|
|
1851
|
+
// built-in default when the key is absent.
|
|
1860
1852
|
review_stale_pending_days: 14
|
|
1861
1853
|
};
|
|
1862
1854
|
mkdirSync2(fabricDir, { recursive: true });
|
|
@@ -2296,6 +2288,8 @@ function validateHookPaths(projectRoot) {
|
|
|
2296
2288
|
{ stepSuffix: "", hookFile: "fabric-hint.cjs" },
|
|
2297
2289
|
{ stepSuffix: "-broad", hookFile: "knowledge-hint-broad.cjs" },
|
|
2298
2290
|
{ stepSuffix: "-narrow", hookFile: "knowledge-hint-narrow.cjs" },
|
|
2291
|
+
// ux-w2-6: single PreToolUse orchestrator (merges narrow + cite).
|
|
2292
|
+
{ stepSuffix: "-pretooluse", hookFile: "knowledge-pretooluse.cjs" },
|
|
2299
2293
|
// lifecycle-refactor W2-T2/T3: SessionEnd + PostToolUse marker hooks.
|
|
2300
2294
|
{ stepSuffix: "-session-end", hookFile: "session-end-marker.cjs" },
|
|
2301
2295
|
{ stepSuffix: "-post-tooluse", hookFile: "post-tooluse-mutation.cjs" }
|
|
@@ -2357,19 +2351,16 @@ var HooksStage = class {
|
|
|
2357
2351
|
const target = context.target;
|
|
2358
2352
|
const installResults = [];
|
|
2359
2353
|
installResults.push(...await this.runBestEffort("skill-deprecated-cleanup", () => cleanupDeprecatedSkills(target)));
|
|
2360
|
-
installResults.push(...await this.runBestEffort("skill-router-install", () => installFabricRouterSkill(target)));
|
|
2361
2354
|
installResults.push(...await this.runBestEffort("skill-install", () => installFabricArchiveSkill(target)));
|
|
2362
2355
|
installResults.push(...await this.runBestEffort("skill-review-install", () => installFabricReviewSkill(target)));
|
|
2363
|
-
installResults.push(...await this.runBestEffort("skill-import-install", () => installFabricImportSkill(target)));
|
|
2364
2356
|
installResults.push(...await this.runBestEffort("skill-sync-install", () => installFabricSyncSkill(target)));
|
|
2365
2357
|
installResults.push(...await this.runBestEffort("skill-store-install", () => installFabricStoreSkill(target)));
|
|
2366
|
-
installResults.push(...await this.runBestEffort("skill-audit-install", () => installFabricAuditSkill(target)));
|
|
2367
|
-
installResults.push(...await this.runBestEffort("skill-connect-install", () => installFabricConnectSkill(target)));
|
|
2368
2358
|
installResults.push(...await this.runBestEffort("skill-shared-lib", () => installSharedSkillLib(target)));
|
|
2369
2359
|
installResults.push(...await this.runBestEffort("hook-script", () => installArchiveHintHook(target)));
|
|
2370
2360
|
installResults.push(...await this.runBestEffort("hook-broad-script", () => installKnowledgeHintBroadHook(target)));
|
|
2371
2361
|
installResults.push(...await this.runBestEffort("hook-narrow-script", () => installKnowledgeHintNarrowHook(target)));
|
|
2372
2362
|
installResults.push(...await this.runBestEffort("hook-cite-policy-evict-script", () => installCitePolicyEvictHook(target)));
|
|
2363
|
+
installResults.push(...await this.runBestEffort("hook-pretooluse-script", () => installKnowledgePretoolUseHook(target)));
|
|
2373
2364
|
installResults.push(...await this.runBestEffort("hook-session-end-script", () => installSessionEndMarkerHook(target)));
|
|
2374
2365
|
installResults.push(...await this.runBestEffort("hook-post-tooluse-script", () => installPostTooluseMutationHook(target)));
|
|
2375
2366
|
installResults.push(...await this.runBestEffort("hook-lib", () => installHookLibs(target)));
|
|
@@ -2794,235 +2785,12 @@ var GuidanceStage = class {
|
|
|
2794
2785
|
}
|
|
2795
2786
|
};
|
|
2796
2787
|
|
|
2797
|
-
// src/tui/
|
|
2798
|
-
import {
|
|
2799
|
-
|
|
2800
|
-
var statusColors = {
|
|
2801
|
-
pending: "gray",
|
|
2802
|
-
running: "cyan",
|
|
2803
|
-
success: "green",
|
|
2804
|
-
error: "red",
|
|
2805
|
-
skipped: "yellow"
|
|
2806
|
-
};
|
|
2807
|
-
var statusSymbols = {
|
|
2808
|
-
pending: "\u25CB",
|
|
2809
|
-
running: "\u25CF",
|
|
2810
|
-
success: "\u2713",
|
|
2811
|
-
error: "\u2717",
|
|
2812
|
-
skipped: "\u25CB"
|
|
2813
|
-
};
|
|
2814
|
-
function StepCounter({
|
|
2815
|
-
current,
|
|
2816
|
-
total,
|
|
2817
|
-
label,
|
|
2818
|
-
status = "running"
|
|
2819
|
-
}) {
|
|
2820
|
-
const color = statusColors[status] || "cyan";
|
|
2821
|
-
const symbol = statusSymbols[status] || "\u25CF";
|
|
2822
|
-
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
2823
|
-
/* @__PURE__ */ jsx(Text, { color, bold: true, children: symbol }),
|
|
2824
|
-
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2825
|
-
"(",
|
|
2826
|
-
current,
|
|
2827
|
-
"/",
|
|
2828
|
-
total,
|
|
2829
|
-
")"
|
|
2830
|
-
] }),
|
|
2831
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: label })
|
|
2832
|
-
] });
|
|
2833
|
-
}
|
|
2834
|
-
|
|
2835
|
-
// src/tui/StatusMessage.tsx
|
|
2836
|
-
import { Box as Box2, Text as Text2 } from "ink";
|
|
2837
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2838
|
-
var typeColors = {
|
|
2839
|
-
success: "green",
|
|
2840
|
-
error: "red",
|
|
2841
|
-
warning: "yellow",
|
|
2842
|
-
info: "blue"
|
|
2843
|
-
};
|
|
2844
|
-
var typeLabels = {
|
|
2845
|
-
success: "\u2713",
|
|
2846
|
-
error: "\u2717",
|
|
2847
|
-
warning: "!",
|
|
2848
|
-
info: "\u2139"
|
|
2849
|
-
};
|
|
2850
|
-
function StatusMessage({
|
|
2851
|
-
message,
|
|
2852
|
-
type,
|
|
2853
|
-
timestamp = false
|
|
2854
|
-
}) {
|
|
2855
|
-
const color = typeColors[type] || "white";
|
|
2856
|
-
const label = typeLabels[type] || "\u2022";
|
|
2857
|
-
const timeStr = timestamp ? `[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] ` : "";
|
|
2858
|
-
return /* @__PURE__ */ jsxs2(Box2, { gap: 1, children: [
|
|
2859
|
-
/* @__PURE__ */ jsx2(Text2, { color, bold: true, children: label }),
|
|
2860
|
-
timestamp && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: timeStr }),
|
|
2861
|
-
/* @__PURE__ */ jsx2(Text2, { color: type === "error" ? "red" : void 0, children: message })
|
|
2862
|
-
] });
|
|
2863
|
-
}
|
|
2864
|
-
|
|
2865
|
-
// src/tui/SummaryCard.tsx
|
|
2866
|
-
import { Box as Box3, Text as Text3 } from "ink";
|
|
2867
|
-
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2868
|
-
function DetailStatus({ status }) {
|
|
2869
|
-
if (!status) return null;
|
|
2870
|
-
const indicators = {
|
|
2871
|
-
success: { symbol: "\u2713", color: "green" },
|
|
2872
|
-
error: { symbol: "\u2717", color: "red" },
|
|
2873
|
-
skipped: { symbol: "\u25CB", color: "yellow" },
|
|
2874
|
-
info: { symbol: "\u2139", color: "blue" }
|
|
2875
|
-
};
|
|
2876
|
-
const { symbol, color } = indicators[status] || { symbol: "\u2022", color: "white" };
|
|
2877
|
-
return /* @__PURE__ */ jsx3(Text3, { color, bold: true, children: symbol });
|
|
2878
|
-
}
|
|
2879
|
-
function SummaryCard({ summary }) {
|
|
2880
|
-
const { title, successCount, skippedCount = 0, errorCount = 0, details = [] } = summary;
|
|
2881
|
-
const totalCount = successCount + skippedCount + errorCount;
|
|
2882
|
-
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, children: [
|
|
2883
|
-
/* @__PURE__ */ jsx3(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: title }) }),
|
|
2884
|
-
/* @__PURE__ */ jsxs3(Box3, { gap: 3, children: [
|
|
2885
|
-
successCount > 0 && /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
|
|
2886
|
-
/* @__PURE__ */ jsx3(Text3, { color: "green", bold: true, children: "\u2713" }),
|
|
2887
|
-
/* @__PURE__ */ jsxs3(Text3, { children: [
|
|
2888
|
-
successCount,
|
|
2889
|
-
" succeeded"
|
|
2890
|
-
] })
|
|
2891
|
-
] }),
|
|
2892
|
-
skippedCount > 0 && /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
|
|
2893
|
-
/* @__PURE__ */ jsx3(Text3, { color: "yellow", bold: true, children: "\u25CB" }),
|
|
2894
|
-
/* @__PURE__ */ jsxs3(Text3, { children: [
|
|
2895
|
-
skippedCount,
|
|
2896
|
-
" skipped"
|
|
2897
|
-
] })
|
|
2898
|
-
] }),
|
|
2899
|
-
errorCount > 0 && /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
|
|
2900
|
-
/* @__PURE__ */ jsx3(Text3, { color: "red", bold: true, children: "\u2717" }),
|
|
2901
|
-
/* @__PURE__ */ jsxs3(Text3, { children: [
|
|
2902
|
-
errorCount,
|
|
2903
|
-
" failed"
|
|
2904
|
-
] })
|
|
2905
|
-
] })
|
|
2906
|
-
] }),
|
|
2907
|
-
details.length > 0 && /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", marginTop: 1, children: details.map((detail, index) => /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
|
|
2908
|
-
/* @__PURE__ */ jsx3(DetailStatus, { status: detail.status }),
|
|
2909
|
-
/* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
2910
|
-
detail.label,
|
|
2911
|
-
":"
|
|
2912
|
-
] }),
|
|
2913
|
-
/* @__PURE__ */ jsx3(Text3, { children: detail.value })
|
|
2914
|
-
] }, index)) }),
|
|
2915
|
-
/* @__PURE__ */ jsx3(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: totalCount === successCount ? "All steps completed successfully" : errorCount > 0 ? `${errorCount} step${errorCount > 1 ? "s" : ""} failed` : `${successCount}/${totalCount} steps completed` }) })
|
|
2916
|
-
] });
|
|
2917
|
-
}
|
|
2918
|
-
|
|
2919
|
-
// src/tui/ErrorBox.tsx
|
|
2920
|
-
import { Box as Box4, Text as Text4 } from "ink";
|
|
2921
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2922
|
-
function ErrorBox({ error, showStack = false }) {
|
|
2923
|
-
const title = error.title || "Error";
|
|
2924
|
-
const code = "code" in error ? error.code : void 0;
|
|
2925
|
-
const hint = "hint" in error ? error.hint : void 0;
|
|
2926
|
-
const stack = "stack" in error ? error.stack : void 0;
|
|
2927
|
-
return /* @__PURE__ */ jsxs4(
|
|
2928
|
-
Box4,
|
|
2929
|
-
{
|
|
2930
|
-
flexDirection: "column",
|
|
2931
|
-
borderStyle: "round",
|
|
2932
|
-
borderColor: "red",
|
|
2933
|
-
paddingX: 1,
|
|
2934
|
-
children: [
|
|
2935
|
-
/* @__PURE__ */ jsxs4(Box4, { gap: 1, children: [
|
|
2936
|
-
/* @__PURE__ */ jsxs4(Text4, { color: "red", bold: true, children: [
|
|
2937
|
-
"\u2717 ",
|
|
2938
|
-
title
|
|
2939
|
-
] }),
|
|
2940
|
-
code && /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
2941
|
-
"(",
|
|
2942
|
-
code,
|
|
2943
|
-
")"
|
|
2944
|
-
] })
|
|
2945
|
-
] }),
|
|
2946
|
-
/* @__PURE__ */ jsx4(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx4(Text4, { color: "red", children: error.message }) }),
|
|
2947
|
-
hint && /* @__PURE__ */ jsx4(Box4, { marginTop: 1, children: /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
2948
|
-
"\u{1F4A1} ",
|
|
2949
|
-
hint
|
|
2950
|
-
] }) }),
|
|
2951
|
-
showStack && stack && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
2952
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Stack trace:" }),
|
|
2953
|
-
/* @__PURE__ */ jsx4(Box4, { marginLeft: 2, children: /* @__PURE__ */ jsx4(Text4, { dimColor: true, color: "gray", children: stack.split("\n").slice(0, 5).join("\n") }) })
|
|
2954
|
-
] })
|
|
2955
|
-
]
|
|
2956
|
-
}
|
|
2957
|
-
);
|
|
2958
|
-
}
|
|
2959
|
-
function toErrorInfo(error) {
|
|
2960
|
-
if ("title" in error) {
|
|
2961
|
-
return error;
|
|
2962
|
-
}
|
|
2963
|
-
return {
|
|
2964
|
-
title: error.name || "Error",
|
|
2965
|
-
message: error.message,
|
|
2966
|
-
stack: error.stack
|
|
2967
|
-
};
|
|
2968
|
-
}
|
|
2969
|
-
|
|
2970
|
-
// src/tui/Spinner.tsx
|
|
2971
|
-
import { useState, useEffect } from "react";
|
|
2972
|
-
import { Text as Text5 } from "ink";
|
|
2973
|
-
import { jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2974
|
-
var FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
2975
|
-
function Spinner({ label }) {
|
|
2976
|
-
const [frame, setFrame] = useState(0);
|
|
2977
|
-
useEffect(() => {
|
|
2978
|
-
const timer = setInterval(() => {
|
|
2979
|
-
setFrame((prev) => (prev + 1) % FRAMES.length);
|
|
2980
|
-
}, 80);
|
|
2981
|
-
return () => clearInterval(timer);
|
|
2982
|
-
}, []);
|
|
2983
|
-
return /* @__PURE__ */ jsxs5(Text5, { color: "cyan", children: [
|
|
2984
|
-
FRAMES[frame],
|
|
2985
|
-
" ",
|
|
2986
|
-
label || "Loading..."
|
|
2987
|
-
] });
|
|
2988
|
-
}
|
|
2989
|
-
|
|
2990
|
-
// src/tui/ProgressBar.tsx
|
|
2991
|
-
import { Box as Box5, Text as Text6 } from "ink";
|
|
2992
|
-
import { jsx as jsx5, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2993
|
-
|
|
2994
|
-
// src/tui/SectionHeader.tsx
|
|
2995
|
-
import { Box as Box6, Text as Text7 } from "ink";
|
|
2996
|
-
import { jsx as jsx6, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2997
|
-
function SectionHeader({ title, subtitle }) {
|
|
2998
|
-
return /* @__PURE__ */ jsxs7(Box6, { flexDirection: "column", marginBottom: 1, children: [
|
|
2999
|
-
/* @__PURE__ */ jsx6(Box6, { borderStyle: "classic", borderColor: "gray", children: /* @__PURE__ */ jsx6(Box6, { paddingX: 1, children: /* @__PURE__ */ jsx6(Text7, { bold: true, color: "cyan", children: title }) }) }),
|
|
3000
|
-
subtitle && /* @__PURE__ */ jsx6(Box6, { marginLeft: 2, children: /* @__PURE__ */ jsx6(Text7, { dimColor: true, children: subtitle }) })
|
|
3001
|
-
] });
|
|
3002
|
-
}
|
|
3003
|
-
|
|
3004
|
-
// src/tui/StoreWizard.tsx
|
|
3005
|
-
import { useState as useState2 } from "react";
|
|
3006
|
-
import { Box as Box7, Text as Text8, useInput } from "ink";
|
|
3007
|
-
import { jsx as jsx7, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3008
|
-
|
|
3009
|
-
// src/tui/InputField.tsx
|
|
3010
|
-
import { useState as useState3 } from "react";
|
|
3011
|
-
import { Box as Box8, Text as Text9, useInput as useInput2, useApp } from "ink";
|
|
3012
|
-
import { jsx as jsx8, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3013
|
-
|
|
3014
|
-
// src/tui/StoreWizardFlow.tsx
|
|
3015
|
-
import { useState as useState4, useCallback } from "react";
|
|
3016
|
-
import { render } from "ink";
|
|
3017
|
-
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
3018
|
-
|
|
3019
|
-
// src/tui/InkOutputRenderer.ts
|
|
3020
|
-
import { render as render2 } from "ink";
|
|
3021
|
-
import React2 from "react";
|
|
3022
|
-
var InkOutputRenderer = class {
|
|
2788
|
+
// src/tui/ConsoleOutputRenderer.ts
|
|
2789
|
+
import { paint as paint2, symbol, sectionBar, isColorEnabled } from "@fenglimg/fabric-shared/theme";
|
|
2790
|
+
var ConsoleOutputRenderer = class {
|
|
3023
2791
|
config;
|
|
2792
|
+
colorOn;
|
|
3024
2793
|
currentStep = null;
|
|
3025
|
-
inkInstances = [];
|
|
3026
2794
|
constructor(config = {}) {
|
|
3027
2795
|
this.config = {
|
|
3028
2796
|
colors: true,
|
|
@@ -3030,129 +2798,160 @@ var InkOutputRenderer = class {
|
|
|
3030
2798
|
timestamps: false,
|
|
3031
2799
|
...config
|
|
3032
2800
|
};
|
|
2801
|
+
this.colorOn = this.config.colors === false ? false : isColorEnabled(process.env, process.stdout.isTTY);
|
|
2802
|
+
}
|
|
2803
|
+
write(line) {
|
|
2804
|
+
console.log(line);
|
|
2805
|
+
}
|
|
2806
|
+
/** Status-message marker by type (StatusMessage glyph + role color, mapped down). */
|
|
2807
|
+
statusMarker(type) {
|
|
2808
|
+
switch (type) {
|
|
2809
|
+
case "success":
|
|
2810
|
+
return symbol("ok", this.colorOn);
|
|
2811
|
+
case "error":
|
|
2812
|
+
return symbol("error", this.colorOn);
|
|
2813
|
+
case "warning":
|
|
2814
|
+
return symbol("warn", this.colorOn);
|
|
2815
|
+
case "info":
|
|
2816
|
+
default:
|
|
2817
|
+
return paint2("ai", "\u2139", this.colorOn);
|
|
2818
|
+
}
|
|
3033
2819
|
}
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
const { unmount } = render2(node);
|
|
3039
|
-
this.inkInstances.push({ unmount });
|
|
2820
|
+
renderStatus(message, type) {
|
|
2821
|
+
const marker = this.statusMarker(type);
|
|
2822
|
+
const body = type === "error" ? paint2("error", message, this.colorOn) : message;
|
|
2823
|
+
this.write(`${marker} ${body}`);
|
|
3040
2824
|
}
|
|
3041
|
-
/**
|
|
3042
|
-
* Render a step progress indicator
|
|
3043
|
-
*/
|
|
3044
2825
|
renderStep(step) {
|
|
3045
2826
|
this.currentStep = step;
|
|
3046
|
-
|
|
3047
|
-
this.renderComponent(
|
|
3048
|
-
React2.createElement(Spinner, { label: step.name })
|
|
3049
|
-
);
|
|
3050
|
-
} else {
|
|
3051
|
-
this.renderComponent(
|
|
3052
|
-
React2.createElement(StepCounter, {
|
|
3053
|
-
current: step.current,
|
|
3054
|
-
total: step.total,
|
|
3055
|
-
label: step.name,
|
|
3056
|
-
status: step.status
|
|
3057
|
-
})
|
|
3058
|
-
);
|
|
3059
|
-
}
|
|
2827
|
+
this.write(buildStepLine(step, this.colorOn));
|
|
3060
2828
|
if (step.detail) {
|
|
3061
|
-
this.
|
|
3062
|
-
React2.createElement(StatusMessage, {
|
|
3063
|
-
message: step.detail,
|
|
3064
|
-
type: step.status === "error" ? "error" : "info"
|
|
3065
|
-
})
|
|
3066
|
-
);
|
|
2829
|
+
this.renderStatus(step.detail, step.status === "error" ? "error" : "info");
|
|
3067
2830
|
}
|
|
3068
2831
|
}
|
|
3069
|
-
/**
|
|
3070
|
-
* Render a success message
|
|
3071
|
-
*/
|
|
3072
2832
|
renderSuccess(message) {
|
|
3073
|
-
this.
|
|
3074
|
-
React2.createElement(StatusMessage, {
|
|
3075
|
-
message,
|
|
3076
|
-
type: "success"
|
|
3077
|
-
})
|
|
3078
|
-
);
|
|
2833
|
+
this.renderStatus(message, "success");
|
|
3079
2834
|
}
|
|
3080
|
-
/**
|
|
3081
|
-
* Render an error
|
|
3082
|
-
*/
|
|
3083
2835
|
renderError(error) {
|
|
3084
|
-
const
|
|
3085
|
-
this.
|
|
3086
|
-
React2.createElement(ErrorBox, {
|
|
3087
|
-
error: errorInfo,
|
|
3088
|
-
showStack: this.config.verbose
|
|
3089
|
-
})
|
|
3090
|
-
);
|
|
2836
|
+
const info = error instanceof Error ? toErrorInfo(error) : error;
|
|
2837
|
+
this.write(buildErrorBlock(info, Boolean(this.config.verbose), this.colorOn));
|
|
3091
2838
|
}
|
|
3092
|
-
/**
|
|
3093
|
-
* Render a warning message
|
|
3094
|
-
*/
|
|
3095
2839
|
renderWarning(message) {
|
|
3096
|
-
this.
|
|
3097
|
-
React2.createElement(StatusMessage, {
|
|
3098
|
-
message,
|
|
3099
|
-
type: "warning"
|
|
3100
|
-
})
|
|
3101
|
-
);
|
|
2840
|
+
this.renderStatus(message, "warning");
|
|
3102
2841
|
}
|
|
3103
|
-
/**
|
|
3104
|
-
* Render an info message
|
|
3105
|
-
*/
|
|
3106
2842
|
renderInfo(message) {
|
|
3107
|
-
this.
|
|
3108
|
-
React2.createElement(StatusMessage, {
|
|
3109
|
-
message,
|
|
3110
|
-
type: "info"
|
|
3111
|
-
})
|
|
3112
|
-
);
|
|
2843
|
+
this.renderStatus(message, "info");
|
|
3113
2844
|
}
|
|
3114
|
-
/**
|
|
3115
|
-
* Render a summary card
|
|
3116
|
-
*/
|
|
3117
2845
|
renderSummaryCard(summary) {
|
|
3118
|
-
this.
|
|
3119
|
-
|
|
3120
|
-
);
|
|
2846
|
+
this.write(sectionBar(summary.title, this.colorOn));
|
|
2847
|
+
this.write(buildSummaryBlock(summary, this.colorOn));
|
|
3121
2848
|
}
|
|
3122
|
-
/**
|
|
3123
|
-
* Render a section header
|
|
3124
|
-
*/
|
|
3125
2849
|
renderSection(title) {
|
|
3126
|
-
this.
|
|
3127
|
-
|
|
3128
|
-
);
|
|
2850
|
+
this.write("");
|
|
2851
|
+
this.write(sectionBar(title, this.colorOn));
|
|
3129
2852
|
}
|
|
3130
|
-
/**
|
|
3131
|
-
* Render a final completion message
|
|
3132
|
-
*/
|
|
3133
2853
|
renderComplete() {
|
|
3134
|
-
this.
|
|
3135
|
-
React2.createElement(StatusMessage, {
|
|
3136
|
-
message: "Done!",
|
|
3137
|
-
type: "success"
|
|
3138
|
-
})
|
|
3139
|
-
);
|
|
2854
|
+
this.renderStatus("Done!", "success");
|
|
3140
2855
|
}
|
|
3141
|
-
/**
|
|
3142
|
-
* Clean up any pending renders
|
|
3143
|
-
*/
|
|
3144
2856
|
async cleanup() {
|
|
3145
|
-
|
|
3146
|
-
try {
|
|
3147
|
-
instance.unmount();
|
|
3148
|
-
} catch {
|
|
3149
|
-
}
|
|
3150
|
-
}
|
|
3151
|
-
this.inkInstances = [];
|
|
2857
|
+
this.currentStep = null;
|
|
3152
2858
|
}
|
|
3153
2859
|
};
|
|
3154
|
-
function
|
|
3155
|
-
|
|
2860
|
+
function toErrorInfo(error) {
|
|
2861
|
+
if ("title" in error) {
|
|
2862
|
+
return error;
|
|
2863
|
+
}
|
|
2864
|
+
return {
|
|
2865
|
+
title: error.name || "Error",
|
|
2866
|
+
message: error.message,
|
|
2867
|
+
stack: error.stack
|
|
2868
|
+
};
|
|
2869
|
+
}
|
|
2870
|
+
function stepBadge(status, colorOn) {
|
|
2871
|
+
switch (status) {
|
|
2872
|
+
case "success":
|
|
2873
|
+
return symbol("ok", colorOn);
|
|
2874
|
+
case "error":
|
|
2875
|
+
return symbol("error", colorOn);
|
|
2876
|
+
case "skipped":
|
|
2877
|
+
return symbol("warn", colorOn);
|
|
2878
|
+
case "running":
|
|
2879
|
+
return paint2("ai", "[..]", colorOn);
|
|
2880
|
+
case "pending":
|
|
2881
|
+
default:
|
|
2882
|
+
return paint2("muted", "[--]", colorOn);
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
function buildStepLine(step, colorOn) {
|
|
2886
|
+
const badge = stepBadge(step.status, colorOn);
|
|
2887
|
+
const counter = paint2("muted", `(${step.current}/${step.total})`, colorOn);
|
|
2888
|
+
const name = step.name || (step.status === "running" ? "Loading..." : "");
|
|
2889
|
+
const last = step.total > 0 && step.current >= step.total;
|
|
2890
|
+
const text3 = `${badge} ${name} ${counter}`.replace(/\s+$/u, "");
|
|
2891
|
+
if (last) {
|
|
2892
|
+
return tree([{ text: text3 }]);
|
|
2893
|
+
}
|
|
2894
|
+
return tree([{ text: text3 }, { text: "" }]).split("\n")[0];
|
|
2895
|
+
}
|
|
2896
|
+
function detailMarker(status, colorOn) {
|
|
2897
|
+
switch (status) {
|
|
2898
|
+
case "success":
|
|
2899
|
+
return paint2("success", "\u2713", colorOn);
|
|
2900
|
+
case "error":
|
|
2901
|
+
return paint2("error", "\u2717", colorOn);
|
|
2902
|
+
case "skipped":
|
|
2903
|
+
return paint2("warn", "\u25CB", colorOn);
|
|
2904
|
+
case "info":
|
|
2905
|
+
return paint2("ai", "\u2139", colorOn);
|
|
2906
|
+
default:
|
|
2907
|
+
return null;
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
function buildSummaryBlock(summary, colorOn) {
|
|
2911
|
+
const { successCount, skippedCount = 0, errorCount = 0, details = [] } = summary;
|
|
2912
|
+
const totalCount = successCount + skippedCount + errorCount;
|
|
2913
|
+
const lines = [];
|
|
2914
|
+
const countCells = [
|
|
2915
|
+
`${paint2("success", "\u2713", colorOn)} ${successCount} succeeded`,
|
|
2916
|
+
`${paint2("warn", "\u25CB", colorOn)} ${skippedCount} skipped`,
|
|
2917
|
+
`${paint2("error", "\u2717", colorOn)} ${errorCount} failed`
|
|
2918
|
+
];
|
|
2919
|
+
lines.push(` ${grid([countCells], { gap: 4 })}`);
|
|
2920
|
+
for (const detail of details) {
|
|
2921
|
+
const marker = detailMarker(detail.status, colorOn);
|
|
2922
|
+
const label = paint2("muted", `${detail.label}:`, colorOn);
|
|
2923
|
+
lines.push(` ${marker ? `${marker} ` : ""}${label} ${detail.value}`);
|
|
2924
|
+
}
|
|
2925
|
+
const summaryLine = totalCount === successCount ? "All steps completed successfully" : errorCount > 0 ? `${errorCount} step${errorCount > 1 ? "s" : ""} failed` : `${successCount}/${totalCount} steps completed`;
|
|
2926
|
+
lines.push(` ${paint2("muted", summaryLine, colorOn)}`);
|
|
2927
|
+
return lines.join("\n");
|
|
2928
|
+
}
|
|
2929
|
+
function leftBar(colorOn) {
|
|
2930
|
+
return colorOn ? paint2("accent", "\u2502", colorOn) + " " : "| ";
|
|
2931
|
+
}
|
|
2932
|
+
function buildErrorBlock(info, verbose, colorOn) {
|
|
2933
|
+
const title = info.title || "Error";
|
|
2934
|
+
const code = info.code;
|
|
2935
|
+
const hint = info.hint;
|
|
2936
|
+
const stack = info.stack;
|
|
2937
|
+
const header = sectionBar(`[err] ${title}`, colorOn);
|
|
2938
|
+
const bar = leftBar(colorOn);
|
|
2939
|
+
const lines = [header, ""];
|
|
2940
|
+
const message = code ? `${info.message} ${paint2("muted", `(${code})`, colorOn)}` : info.message;
|
|
2941
|
+
lines.push(` ${bar}${paint2("error", message, colorOn)}`);
|
|
2942
|
+
if (hint) {
|
|
2943
|
+
lines.push(` ${bar.trimEnd()}`);
|
|
2944
|
+
lines.push(` ${bar}${paint2("muted", `\u{1F4A1} ${hint}`, colorOn)}`);
|
|
2945
|
+
}
|
|
2946
|
+
if (verbose && stack) {
|
|
2947
|
+
for (const frame of stack.split("\n").slice(0, 5)) {
|
|
2948
|
+
lines.push(` ${bar}${paint2("muted", `\u21B3 ${frame.trim()}`, colorOn)}`);
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
return lines.join("\n");
|
|
2952
|
+
}
|
|
2953
|
+
function createInstallRenderer(config) {
|
|
2954
|
+
return new ConsoleOutputRenderer(config);
|
|
3156
2955
|
}
|
|
3157
2956
|
|
|
3158
2957
|
// src/commands/install-v2.ts
|
|
@@ -3225,7 +3024,7 @@ async function runInitCommand(args) {
|
|
|
3225
3024
|
logger(step);
|
|
3226
3025
|
}
|
|
3227
3026
|
const terminalInteractive = isInteractiveInit();
|
|
3228
|
-
const renderer = shouldUseInstallRenderer(args, terminalInteractive) ?
|
|
3027
|
+
const renderer = shouldUseInstallRenderer(args, terminalInteractive) ? createInstallRenderer({ verbose: args.debug }) : void 0;
|
|
3229
3028
|
const context = createInstallContext(args, resolution.target, renderer);
|
|
3230
3029
|
const pipeline = new InstallPipeline().addStage(new PreflightStage()).addStage(new EnvStage()).addStage(new StoreStage()).addStage(new HooksStage()).addStage(new McpStage()).addStage(new ValidateStage()).addStage(new GuidanceStage());
|
|
3231
3030
|
const result = await pipeline.execute(context);
|