@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
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getProjectTranslator
|
|
4
|
+
} from "./chunk-HORSMSZL.js";
|
|
2
5
|
|
|
3
6
|
// src/commands/metrics.ts
|
|
4
7
|
import { resolve } from "path";
|
|
5
8
|
import { defineCommand } from "citty";
|
|
6
9
|
import { readMetrics } from "@fenglimg/fabric-server";
|
|
7
|
-
function parseSinceArg(raw) {
|
|
10
|
+
function parseSinceArg(raw, t) {
|
|
8
11
|
if (raw === void 0 || raw.length === 0) return 0;
|
|
9
12
|
const match = /^(\d+)([smhd]?)$/u.exec(raw);
|
|
10
13
|
if (match === null) {
|
|
11
|
-
throw new Error(
|
|
14
|
+
throw new Error(t("cli.metrics.invalid-since", { raw }));
|
|
12
15
|
}
|
|
13
16
|
const n = Number.parseInt(match[1], 10);
|
|
14
17
|
const unit = match[2] ?? "s";
|
|
@@ -36,6 +39,8 @@ function aggregate(rows, sinceMs, now) {
|
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
return {
|
|
42
|
+
// Stable token (NOT localized) so the --json contract is locale-independent;
|
|
43
|
+
// renderText localizes "all-time" at presentation time only.
|
|
39
44
|
windowDescription: sinceMs > 0 ? formatDuration(sinceMs) : "all-time",
|
|
40
45
|
rowCount: filtered.length,
|
|
41
46
|
totals,
|
|
@@ -50,17 +55,24 @@ function formatDuration(ms) {
|
|
|
50
55
|
if (ms >= 6e4) return `${Math.round(ms / 6e4)}m`;
|
|
51
56
|
return `${Math.round(ms / 1e3)}s`;
|
|
52
57
|
}
|
|
53
|
-
function renderText(agg) {
|
|
58
|
+
function renderText(agg, t) {
|
|
54
59
|
const lines = [];
|
|
55
|
-
|
|
60
|
+
const windowDisplay = agg.windowDescription === "all-time" ? t("cli.metrics.window-all-time") : agg.windowDescription;
|
|
61
|
+
lines.push(t("cli.metrics.window", { window: windowDisplay }));
|
|
56
62
|
if (agg.rangeStart && agg.rangeEnd) {
|
|
57
|
-
lines.push(
|
|
63
|
+
lines.push(
|
|
64
|
+
t("cli.metrics.rows-range", {
|
|
65
|
+
count: String(agg.rowCount),
|
|
66
|
+
start: agg.rangeStart,
|
|
67
|
+
end: agg.rangeEnd
|
|
68
|
+
})
|
|
69
|
+
);
|
|
58
70
|
} else {
|
|
59
|
-
lines.push(
|
|
71
|
+
lines.push(t("cli.metrics.rows", { count: String(agg.rowCount) }));
|
|
60
72
|
}
|
|
61
73
|
lines.push("");
|
|
62
74
|
if (Object.keys(agg.totals).length === 0) {
|
|
63
|
-
lines.push("
|
|
75
|
+
lines.push(t("cli.metrics.no-activity"));
|
|
64
76
|
return lines.join("\n");
|
|
65
77
|
}
|
|
66
78
|
lines.push(" counter total");
|
|
@@ -103,14 +115,15 @@ var metricsCommand = defineCommand({
|
|
|
103
115
|
},
|
|
104
116
|
async run({ args }) {
|
|
105
117
|
const projectRoot = resolve(args.target ?? process.cwd());
|
|
106
|
-
const
|
|
118
|
+
const t = getProjectTranslator(projectRoot);
|
|
119
|
+
const sinceMs = parseSinceArg(args.since, t);
|
|
107
120
|
const rows = await readMetrics(projectRoot);
|
|
108
121
|
const aggregated = aggregate(rows, sinceMs, /* @__PURE__ */ new Date());
|
|
109
122
|
if (args.json === true) {
|
|
110
123
|
process.stdout.write(`${JSON.stringify(aggregated)}
|
|
111
124
|
`);
|
|
112
125
|
} else {
|
|
113
|
-
process.stdout.write(`${renderText(aggregated)}
|
|
126
|
+
process.stdout.write(`${renderText(aggregated, t)}
|
|
114
127
|
`);
|
|
115
128
|
}
|
|
116
129
|
}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
t
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HORSMSZL.js";
|
|
5
5
|
|
|
6
6
|
// src/commands/onboard-coverage.ts
|
|
7
|
-
import { existsSync,
|
|
7
|
+
import { existsSync, readFileSync } from "fs";
|
|
8
8
|
import { join, resolve } from "path";
|
|
9
9
|
import { defineCommand } from "citty";
|
|
10
10
|
import {
|
|
11
|
+
buildStoreResolveInput,
|
|
12
|
+
createStoreResolver,
|
|
11
13
|
ONBOARD_SLOT_NAMES,
|
|
12
|
-
ONBOARD_SLOT_TOTAL
|
|
14
|
+
ONBOARD_SLOT_TOTAL,
|
|
15
|
+
readKnowledgeAcrossStores,
|
|
16
|
+
resolveGlobalRoot,
|
|
17
|
+
storeRelativePathForMount
|
|
13
18
|
} from "@fenglimg/fabric-shared";
|
|
14
19
|
var KNOWLEDGE_TYPE_DIRS = [
|
|
15
20
|
"decisions",
|
|
@@ -97,30 +102,46 @@ function readOptedOutSlots(projectRoot) {
|
|
|
97
102
|
if (!Array.isArray(slots)) return [];
|
|
98
103
|
return slots.filter((v) => typeof v === "string");
|
|
99
104
|
}
|
|
100
|
-
function
|
|
105
|
+
function readSetStoreDirs(projectRoot) {
|
|
106
|
+
let input;
|
|
107
|
+
try {
|
|
108
|
+
input = buildStoreResolveInput(projectRoot);
|
|
109
|
+
} catch {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
if (input === null) {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
const readSet = createStoreResolver().resolveReadSet(input);
|
|
116
|
+
const globalRoot = resolveGlobalRoot();
|
|
117
|
+
return readSet.stores.map((store) => ({
|
|
118
|
+
store_uuid: store.store_uuid,
|
|
119
|
+
alias: store.alias,
|
|
120
|
+
// D4 two-layer layout: resolve via the mounted record (group + label), not
|
|
121
|
+
// the single-segment uuid path — mirrors the other read-set consumers.
|
|
122
|
+
dir: join(
|
|
123
|
+
globalRoot,
|
|
124
|
+
storeRelativePathForMount(
|
|
125
|
+
input.mountedStores.find((s) => s.store_uuid === store.store_uuid) ?? {
|
|
126
|
+
store_uuid: store.store_uuid
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
function entryName(filePath) {
|
|
133
|
+
return filePath.split(/[\\/]/u).at(-1) ?? filePath;
|
|
134
|
+
}
|
|
135
|
+
async function runOnboardCoverage(projectRoot) {
|
|
101
136
|
const filled = emptyFilled();
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
} catch {
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
for (const entry of entries) {
|
|
114
|
-
if (!entry.isFile()) continue;
|
|
115
|
-
if (!entry.name.endsWith(".md")) continue;
|
|
116
|
-
const filePath = join(dir, entry.name);
|
|
117
|
-
const slot = readOnboardSlotFrontmatter(filePath);
|
|
118
|
-
if (slot === void 0) continue;
|
|
119
|
-
if (!ONBOARD_SLOT_NAMES.includes(slot)) continue;
|
|
120
|
-
const stableId = readStableIdFrontmatter(filePath, entry.name);
|
|
121
|
-
filled[slot].push(stableId);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
137
|
+
const refs = await readKnowledgeAcrossStores(readSetStoreDirs(projectRoot));
|
|
138
|
+
for (const ref of refs) {
|
|
139
|
+
if (!KNOWLEDGE_TYPE_DIRS.includes(ref.type)) continue;
|
|
140
|
+
const slot = readOnboardSlotFrontmatter(ref.file);
|
|
141
|
+
if (slot === void 0) continue;
|
|
142
|
+
if (!ONBOARD_SLOT_NAMES.includes(slot)) continue;
|
|
143
|
+
const stableId = readStableIdFrontmatter(ref.file, entryName(ref.file));
|
|
144
|
+
filled[slot].push(ref.alias.length === 0 ? stableId : `${ref.alias}:${stableId}`);
|
|
124
145
|
}
|
|
125
146
|
const optedOut = readOptedOutSlots(projectRoot);
|
|
126
147
|
const missing = ONBOARD_SLOT_NAMES.filter((slot) => {
|
|
@@ -196,7 +217,7 @@ var onboardCoverageCommand = defineCommand({
|
|
|
196
217
|
async run({ args }) {
|
|
197
218
|
try {
|
|
198
219
|
const projectRoot = resolve(args.target ?? process.cwd());
|
|
199
|
-
const report = runOnboardCoverage(projectRoot);
|
|
220
|
+
const report = await runOnboardCoverage(projectRoot);
|
|
200
221
|
if (args.json === true) {
|
|
201
222
|
process.stdout.write(`${JSON.stringify(report)}
|
|
202
223
|
`);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
planContextHintCommand,
|
|
4
|
+
plan_context_hint_default,
|
|
5
|
+
runPlanContextHint
|
|
6
|
+
} from "./chunk-722JU5BP.js";
|
|
7
|
+
import "./chunk-WA3DYGSY.js";
|
|
8
|
+
export {
|
|
9
|
+
plan_context_hint_default as default,
|
|
10
|
+
planContextHintCommand,
|
|
11
|
+
runPlanContextHint
|
|
12
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
scopeExplain
|
|
4
|
+
} from "./chunk-EOT63RDH.js";
|
|
5
|
+
import {
|
|
6
|
+
getProjectTranslator
|
|
7
|
+
} from "./chunk-HORSMSZL.js";
|
|
8
|
+
|
|
9
|
+
// src/commands/scope-explain.ts
|
|
10
|
+
import { defineCommand } from "citty";
|
|
11
|
+
import { FabricError } from "@fenglimg/fabric-shared/errors";
|
|
12
|
+
var scope_explain_default = defineCommand({
|
|
13
|
+
meta: {
|
|
14
|
+
name: "scope-explain",
|
|
15
|
+
description: "[DEPRECATED] Use 'fabric info scope <path>' instead"
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
scope: {
|
|
19
|
+
type: "positional",
|
|
20
|
+
required: true,
|
|
21
|
+
description: "Scope coordinate (e.g. team, project:x, personal)"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
run({ args }) {
|
|
25
|
+
console.error("\u26A0\uFE0F DEPRECATED: 'fabric scope-explain' is deprecated. Use 'fabric info scope <path>' instead.");
|
|
26
|
+
const projectRoot = process.cwd();
|
|
27
|
+
let result;
|
|
28
|
+
try {
|
|
29
|
+
result = scopeExplain(projectRoot, args.scope);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (error instanceof FabricError) {
|
|
32
|
+
console.error(`${error.message}
|
|
33
|
+
\u2192 ${error.actionHint}`);
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
if (result === null) {
|
|
40
|
+
console.log(getProjectTranslator(projectRoot)("cli.cmd.no-global-config"));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
console.log(JSON.stringify(result, null, 2));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
export {
|
|
47
|
+
scope_explain_default as default
|
|
48
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
projectStatus,
|
|
4
|
+
warnUnknownFlags
|
|
5
|
+
} from "./chunk-27HK6H5Y.js";
|
|
6
|
+
import "./chunk-QPAW6IYT.js";
|
|
7
|
+
import "./chunk-QFIVFZRH.js";
|
|
8
|
+
import "./chunk-FNHDQTPC.js";
|
|
9
|
+
|
|
10
|
+
// src/commands/status.ts
|
|
11
|
+
import { defineCommand } from "citty";
|
|
12
|
+
var status_default = defineCommand({
|
|
13
|
+
meta: { name: "status", description: "[DEPRECATED] Use 'fabric info' instead" },
|
|
14
|
+
args: {
|
|
15
|
+
// F27: `--json` machine-readable output (was silently ignored pre-F27).
|
|
16
|
+
json: { type: "boolean", description: "Emit machine-readable JSON instead of text" }
|
|
17
|
+
},
|
|
18
|
+
run({ args }) {
|
|
19
|
+
warnUnknownFlags(["json"]);
|
|
20
|
+
console.error("\u26A0\uFE0F DEPRECATED: 'fabric status' is deprecated. Use 'fabric info' instead.");
|
|
21
|
+
const status = projectStatus(process.cwd());
|
|
22
|
+
if (args.json === true) {
|
|
23
|
+
console.log(JSON.stringify(status, null, 2));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log(`uid: ${status.uid ?? "(no global config)"}`);
|
|
27
|
+
const projectIdLabel = status.project_id ?? (status.is_fabric_project ? "(unset)" : "(not a Fabric project)");
|
|
28
|
+
console.log(`project_id: ${projectIdLabel}`);
|
|
29
|
+
console.log(`mounted stores: ${status.mounted.length > 0 ? status.mounted.join(", ") : "(none)"}`);
|
|
30
|
+
console.log(`required: ${status.required.length > 0 ? status.required.join(", ") : "(none)"}`);
|
|
31
|
+
console.log(`default write: ${status.default_write_store ?? status.active_write_store ?? "(none \u2014 personal scope only)"}`);
|
|
32
|
+
console.log(`write routes: ${status.write_routes.length}`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
export {
|
|
36
|
+
status_default as default
|
|
37
|
+
};
|