@fenglimg/fabric-cli 2.0.1 → 2.1.0-rc.2
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/dist/{chunk-D25XJ4BC.js → chunk-F46ORPOA.js} +23 -0
- package/dist/chunk-HFQVXY6P.js +86 -0
- package/dist/chunk-L4Q55UC4.js +52 -0
- package/dist/chunk-LFIKMVY7.js +27 -0
- package/dist/chunk-RYAFBNES.js +33 -0
- package/dist/chunk-T5RPGCCM.js +40 -0
- package/dist/chunk-WU6GAPKH.js +36 -0
- package/dist/{doctor-EJDSEJSS.js → doctor-QVNPHLJK.js} +111 -1
- package/dist/index.js +12 -4
- package/dist/{install-EKWMFLUU.js → install-2HDO5FTQ.js} +242 -51
- package/dist/scope-explain-2F2R5URO.js +33 -0
- package/dist/status-GLQWLWH6.js +23 -0
- package/dist/store-XTSE5TY6.js +105 -0
- package/dist/sync-BJCWDPNC.js +245 -0
- package/dist/{uninstall-MH7ZIB6M.js → uninstall-TAXSUSKH.js} +14 -5
- package/dist/whoami-B6AEMSEV.js +31 -0
- package/package.json +3 -3
- package/templates/hooks/fabric-hint.cjs +40 -0
- package/templates/hooks/knowledge-hint-broad.cjs +40 -0
- package/templates/hooks/knowledge-hint-narrow.cjs +39 -0
- package/templates/hooks/lib/bindings-snapshot-reader.cjs +81 -0
- package/templates/hooks/lib/cite-contract-reminder.cjs +15 -9
- package/templates/hooks/lib/cite-line-parser.cjs +48 -26
- package/templates/skills/fabric-archive/SKILL.md +4 -0
- package/templates/skills/fabric-import/SKILL.md +4 -0
- package/templates/skills/fabric-review/SKILL.md +4 -0
- package/templates/skills/fabric-sync/SKILL.md +46 -0
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
var SKILL_TEMPLATE_REL = "skills/fabric-archive/SKILL.md";
|
|
55
55
|
var SKILL_REVIEW_TEMPLATE_REL = "skills/fabric-review/SKILL.md";
|
|
56
56
|
var SKILL_IMPORT_TEMPLATE_REL = "skills/fabric-import/SKILL.md";
|
|
57
|
+
var SKILL_SYNC_TEMPLATE_REL = "skills/fabric-sync/SKILL.md";
|
|
57
58
|
var HOOK_SCRIPT_TEMPLATE_REL = "hooks/fabric-hint.cjs";
|
|
58
59
|
var HOOK_BROAD_SCRIPT_TEMPLATE_REL = "hooks/knowledge-hint-broad.cjs";
|
|
59
60
|
var HOOK_NARROW_SCRIPT_TEMPLATE_REL = "hooks/knowledge-hint-narrow.cjs";
|
|
@@ -74,6 +75,12 @@ var SKILL_DESTINATIONS = {
|
|
|
74
75
|
fabricImport: [
|
|
75
76
|
".claude/skills/fabric-import/SKILL.md",
|
|
76
77
|
".codex/skills/fabric-import/SKILL.md"
|
|
78
|
+
],
|
|
79
|
+
// v2.1.0-rc.1 P4 (S46): fabric-sync mirrors the sibling skills' 2-client
|
|
80
|
+
// coverage (Claude Code + Codex CLI surface a Skills directory).
|
|
81
|
+
fabricSync: [
|
|
82
|
+
".claude/skills/fabric-sync/SKILL.md",
|
|
83
|
+
".codex/skills/fabric-sync/SKILL.md"
|
|
77
84
|
]
|
|
78
85
|
};
|
|
79
86
|
var DEPRECATED_SKILL_DIRS = [
|
|
@@ -235,6 +242,21 @@ async function installFabricImportSkill(projectRoot, _options = {}) {
|
|
|
235
242
|
results.push(...await installSkillRefFiles(projectRoot, "fabric-import"));
|
|
236
243
|
return results;
|
|
237
244
|
}
|
|
245
|
+
async function installFabricSyncSkill(projectRoot, _options = {}) {
|
|
246
|
+
const source = await readTemplate(SKILL_SYNC_TEMPLATE_REL);
|
|
247
|
+
validateSkillCanonicalSize(source, "fabric-sync");
|
|
248
|
+
const targets = SKILL_DESTINATIONS.fabricSync.map((rel) => join2(projectRoot, rel));
|
|
249
|
+
const results = [];
|
|
250
|
+
for (const target of targets) {
|
|
251
|
+
const staleMsg = inspectStaleInstall(target, source);
|
|
252
|
+
const result = await copyTextIdempotent("skill-sync", source, target);
|
|
253
|
+
if (staleMsg && result.status === "written") {
|
|
254
|
+
result.message = result.message ? `${staleMsg}; ${result.message}` : staleMsg;
|
|
255
|
+
}
|
|
256
|
+
results.push(result);
|
|
257
|
+
}
|
|
258
|
+
return results;
|
|
259
|
+
}
|
|
238
260
|
async function cleanupDeprecatedSkills(projectRoot) {
|
|
239
261
|
const results = [];
|
|
240
262
|
for (const rel of DEPRECATED_SKILL_DIRS) {
|
|
@@ -864,6 +886,7 @@ export {
|
|
|
864
886
|
installFabricArchiveSkill,
|
|
865
887
|
installFabricReviewSkill,
|
|
866
888
|
installFabricImportSkill,
|
|
889
|
+
installFabricSyncSkill,
|
|
867
890
|
cleanupDeprecatedSkills,
|
|
868
891
|
installSharedSkillLib,
|
|
869
892
|
installArchiveHintHook,
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadProjectConfig,
|
|
4
|
+
saveProjectConfig
|
|
5
|
+
} from "./chunk-LFIKMVY7.js";
|
|
6
|
+
import {
|
|
7
|
+
loadGlobalConfig,
|
|
8
|
+
resolveGlobalRoot,
|
|
9
|
+
saveGlobalConfig
|
|
10
|
+
} from "./chunk-RYAFBNES.js";
|
|
11
|
+
|
|
12
|
+
// src/store/store-ops.ts
|
|
13
|
+
import {
|
|
14
|
+
addMountedStore,
|
|
15
|
+
bindRequiredStore,
|
|
16
|
+
detachMountedStore,
|
|
17
|
+
explainStore
|
|
18
|
+
} from "@fenglimg/fabric-shared";
|
|
19
|
+
var NO_GLOBAL_CONFIG = "no global Fabric config found \u2014 run `fabric install --global <url>` first";
|
|
20
|
+
function requireConfig(globalRoot) {
|
|
21
|
+
const config = loadGlobalConfig(globalRoot);
|
|
22
|
+
if (config === null) {
|
|
23
|
+
throw new Error(NO_GLOBAL_CONFIG);
|
|
24
|
+
}
|
|
25
|
+
return config;
|
|
26
|
+
}
|
|
27
|
+
function storeList(globalRoot = resolveGlobalRoot()) {
|
|
28
|
+
return requireConfig(globalRoot).stores;
|
|
29
|
+
}
|
|
30
|
+
function storeAdd(store, globalRoot = resolveGlobalRoot()) {
|
|
31
|
+
const next = addMountedStore(requireConfig(globalRoot), store);
|
|
32
|
+
saveGlobalConfig(next, globalRoot);
|
|
33
|
+
return next;
|
|
34
|
+
}
|
|
35
|
+
function storeRemove(alias, globalRoot = resolveGlobalRoot()) {
|
|
36
|
+
const result = detachMountedStore(requireConfig(globalRoot), alias);
|
|
37
|
+
saveGlobalConfig(result.config, globalRoot);
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
function storeExplain(alias, globalRoot = resolveGlobalRoot()) {
|
|
41
|
+
return explainStore(requireConfig(globalRoot), alias);
|
|
42
|
+
}
|
|
43
|
+
var NO_PROJECT_CONFIG = "no project Fabric config \u2014 run `fabric install` in this repo first";
|
|
44
|
+
function requireProjectConfig(projectRoot) {
|
|
45
|
+
const config = loadProjectConfig(projectRoot);
|
|
46
|
+
if (config === null) {
|
|
47
|
+
throw new Error(NO_PROJECT_CONFIG);
|
|
48
|
+
}
|
|
49
|
+
return config;
|
|
50
|
+
}
|
|
51
|
+
function storeBind(projectRoot, entry) {
|
|
52
|
+
const config = requireProjectConfig(projectRoot);
|
|
53
|
+
const next = {
|
|
54
|
+
...config,
|
|
55
|
+
required_stores: bindRequiredStore(config.required_stores ?? [], entry)
|
|
56
|
+
};
|
|
57
|
+
saveProjectConfig(next, projectRoot);
|
|
58
|
+
return next;
|
|
59
|
+
}
|
|
60
|
+
function storeSwitchWrite(projectRoot, alias) {
|
|
61
|
+
const config = requireProjectConfig(projectRoot);
|
|
62
|
+
const next = { ...config, active_write_store: alias };
|
|
63
|
+
saveProjectConfig(next, projectRoot);
|
|
64
|
+
return next;
|
|
65
|
+
}
|
|
66
|
+
function missingRequiredStores(projectRoot, globalRoot = resolveGlobalRoot()) {
|
|
67
|
+
const project = loadProjectConfig(projectRoot);
|
|
68
|
+
if (project === null || project.required_stores === void 0) {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
const global = loadGlobalConfig(globalRoot);
|
|
72
|
+
const mounted = new Set(
|
|
73
|
+
(global?.stores ?? []).flatMap((s) => [s.alias, s.store_uuid])
|
|
74
|
+
);
|
|
75
|
+
return project.required_stores.filter((r) => !mounted.has(r.id));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
storeList,
|
|
80
|
+
storeAdd,
|
|
81
|
+
storeRemove,
|
|
82
|
+
storeExplain,
|
|
83
|
+
storeBind,
|
|
84
|
+
storeSwitchWrite,
|
|
85
|
+
missingRequiredStores
|
|
86
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadProjectConfig
|
|
4
|
+
} from "./chunk-LFIKMVY7.js";
|
|
5
|
+
import {
|
|
6
|
+
loadGlobalConfig,
|
|
7
|
+
resolveGlobalRoot
|
|
8
|
+
} from "./chunk-RYAFBNES.js";
|
|
9
|
+
|
|
10
|
+
// src/store/scope-explain.ts
|
|
11
|
+
import {
|
|
12
|
+
createStoreResolver
|
|
13
|
+
} from "@fenglimg/fabric-shared";
|
|
14
|
+
function buildResolveInput(projectRoot, globalRoot = resolveGlobalRoot()) {
|
|
15
|
+
const global = loadGlobalConfig(globalRoot);
|
|
16
|
+
if (global === null) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const project = loadProjectConfig(projectRoot);
|
|
20
|
+
return {
|
|
21
|
+
uid: global.uid,
|
|
22
|
+
mountedStores: global.stores.map((s) => ({
|
|
23
|
+
store_uuid: s.store_uuid,
|
|
24
|
+
alias: s.alias,
|
|
25
|
+
...s.remote === void 0 ? {} : { remote: s.remote },
|
|
26
|
+
writable: s.writable ?? true,
|
|
27
|
+
personal: s.personal ?? false
|
|
28
|
+
})),
|
|
29
|
+
requiredStores: (project?.required_stores ?? []).map((r) => ({
|
|
30
|
+
id: r.id,
|
|
31
|
+
...r.suggested_remote === void 0 ? {} : { suggested_remote: r.suggested_remote }
|
|
32
|
+
})),
|
|
33
|
+
...project?.active_write_store === void 0 ? {} : { activeWriteAlias: project.active_write_store }
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function scopeExplain(projectRoot, scope, globalRoot = resolveGlobalRoot()) {
|
|
37
|
+
const input = buildResolveInput(projectRoot, globalRoot);
|
|
38
|
+
if (input === null) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const resolver = createStoreResolver();
|
|
42
|
+
return {
|
|
43
|
+
scope,
|
|
44
|
+
readSet: resolver.resolveReadSet(input),
|
|
45
|
+
writeTarget: resolver.resolveWriteTarget(input, scope).target
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
buildResolveInput,
|
|
51
|
+
scopeExplain
|
|
52
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/store/project-config-io.ts
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { fabricConfigSchema } from "@fenglimg/fabric-shared";
|
|
7
|
+
function projectConfigPath(projectRoot) {
|
|
8
|
+
return join(projectRoot, ".fabric", "fabric-config.json");
|
|
9
|
+
}
|
|
10
|
+
function loadProjectConfig(projectRoot) {
|
|
11
|
+
const path = projectConfigPath(projectRoot);
|
|
12
|
+
if (!existsSync(path)) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return fabricConfigSchema.parse(JSON.parse(readFileSync(path, "utf8")));
|
|
16
|
+
}
|
|
17
|
+
function saveProjectConfig(config, projectRoot) {
|
|
18
|
+
const validated = fabricConfigSchema.parse(config);
|
|
19
|
+
mkdirSync(join(projectRoot, ".fabric"), { recursive: true });
|
|
20
|
+
writeFileSync(projectConfigPath(projectRoot), `${JSON.stringify(validated, null, 2)}
|
|
21
|
+
`, "utf8");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
loadProjectConfig,
|
|
26
|
+
saveProjectConfig
|
|
27
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/store/global-config-io.ts
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
5
|
+
import { homedir } from "os";
|
|
6
|
+
import { join } from "path";
|
|
7
|
+
import { globalConfigSchema } from "@fenglimg/fabric-shared";
|
|
8
|
+
function resolveGlobalRoot() {
|
|
9
|
+
return join(process.env.FABRIC_HOME ?? homedir(), ".fabric");
|
|
10
|
+
}
|
|
11
|
+
function globalConfigPath(globalRoot = resolveGlobalRoot()) {
|
|
12
|
+
return join(globalRoot, "fabric-global.json");
|
|
13
|
+
}
|
|
14
|
+
function loadGlobalConfig(globalRoot = resolveGlobalRoot()) {
|
|
15
|
+
const path = globalConfigPath(globalRoot);
|
|
16
|
+
if (!existsSync(path)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return globalConfigSchema.parse(JSON.parse(readFileSync(path, "utf8")));
|
|
20
|
+
}
|
|
21
|
+
function saveGlobalConfig(config, globalRoot = resolveGlobalRoot()) {
|
|
22
|
+
const validated = globalConfigSchema.parse(config);
|
|
23
|
+
mkdirSync(globalRoot, { recursive: true });
|
|
24
|
+
writeFileSync(globalConfigPath(globalRoot), `${JSON.stringify(validated, null, 2)}
|
|
25
|
+
`, "utf8");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
resolveGlobalRoot,
|
|
30
|
+
globalConfigPath,
|
|
31
|
+
loadGlobalConfig,
|
|
32
|
+
saveGlobalConfig
|
|
33
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadProjectConfig
|
|
4
|
+
} from "./chunk-LFIKMVY7.js";
|
|
5
|
+
import {
|
|
6
|
+
loadGlobalConfig,
|
|
7
|
+
resolveGlobalRoot
|
|
8
|
+
} from "./chunk-RYAFBNES.js";
|
|
9
|
+
|
|
10
|
+
// src/store/info-ops.ts
|
|
11
|
+
function whoami(globalRoot = resolveGlobalRoot()) {
|
|
12
|
+
const config = loadGlobalConfig(globalRoot);
|
|
13
|
+
if (config === null) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
uid: config.uid,
|
|
18
|
+
stores: config.stores.map((s) => ({
|
|
19
|
+
alias: s.alias,
|
|
20
|
+
store_uuid: s.store_uuid,
|
|
21
|
+
local_only: s.remote === void 0
|
|
22
|
+
}))
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function projectStatus(projectRoot, globalRoot = resolveGlobalRoot()) {
|
|
26
|
+
const global = loadGlobalConfig(globalRoot);
|
|
27
|
+
const project = loadProjectConfig(projectRoot);
|
|
28
|
+
return {
|
|
29
|
+
uid: global?.uid ?? null,
|
|
30
|
+
mounted: (global?.stores ?? []).map((s) => s.alias),
|
|
31
|
+
project_id: project?.project_id ?? null,
|
|
32
|
+
required: (project?.required_stores ?? []).map((r) => r.id),
|
|
33
|
+
active_write_store: project?.active_write_store ?? null
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
whoami,
|
|
39
|
+
projectStatus
|
|
40
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
buildResolveInput
|
|
4
|
+
} from "./chunk-L4Q55UC4.js";
|
|
5
|
+
import {
|
|
6
|
+
loadProjectConfig
|
|
7
|
+
} from "./chunk-LFIKMVY7.js";
|
|
8
|
+
import {
|
|
9
|
+
resolveGlobalRoot
|
|
10
|
+
} from "./chunk-RYAFBNES.js";
|
|
11
|
+
|
|
12
|
+
// src/store/bindings-io.ts
|
|
13
|
+
import { writeBindingsSnapshot } from "@fenglimg/fabric-shared";
|
|
14
|
+
var DEFAULT_WRITE_SCOPE = "team";
|
|
15
|
+
function regenerateBindingsSnapshot(projectRoot, options) {
|
|
16
|
+
const globalRoot = options.globalRoot ?? resolveGlobalRoot();
|
|
17
|
+
const resolveInput = buildResolveInput(projectRoot, globalRoot);
|
|
18
|
+
if (resolveInput === null) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const project = loadProjectConfig(projectRoot);
|
|
22
|
+
if (project?.project_id === void 0) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
return writeBindingsSnapshot({
|
|
26
|
+
globalRoot,
|
|
27
|
+
projectId: project.project_id,
|
|
28
|
+
resolveInput,
|
|
29
|
+
writeScope: options.writeScope ?? DEFAULT_WRITE_SCOPE,
|
|
30
|
+
now: options.now
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export {
|
|
35
|
+
regenerateBindingsSnapshot
|
|
36
|
+
};
|
|
@@ -10,6 +10,16 @@ import {
|
|
|
10
10
|
getDoctorTranslator,
|
|
11
11
|
t
|
|
12
12
|
} from "./chunk-PWLW3B57.js";
|
|
13
|
+
import {
|
|
14
|
+
missingRequiredStores
|
|
15
|
+
} from "./chunk-HFQVXY6P.js";
|
|
16
|
+
import {
|
|
17
|
+
loadProjectConfig
|
|
18
|
+
} from "./chunk-LFIKMVY7.js";
|
|
19
|
+
import {
|
|
20
|
+
loadGlobalConfig,
|
|
21
|
+
resolveGlobalRoot
|
|
22
|
+
} from "./chunk-RYAFBNES.js";
|
|
13
23
|
|
|
14
24
|
// src/commands/doctor.ts
|
|
15
25
|
import { confirm, isCancel } from "@clack/prompts";
|
|
@@ -24,6 +34,53 @@ import {
|
|
|
24
34
|
runDoctorHistoryAll,
|
|
25
35
|
runDoctorReport
|
|
26
36
|
} from "@fenglimg/fabric-server";
|
|
37
|
+
|
|
38
|
+
// src/store/doctor-checks.ts
|
|
39
|
+
import { join } from "path";
|
|
40
|
+
import { findStoreExecutableViolations, storeRelativePath } from "@fenglimg/fabric-shared";
|
|
41
|
+
function storeDoctorChecks(projectRoot, globalRoot = resolveGlobalRoot()) {
|
|
42
|
+
const diagnostics = [];
|
|
43
|
+
const global = loadGlobalConfig(globalRoot);
|
|
44
|
+
if (global === null) {
|
|
45
|
+
diagnostics.push({
|
|
46
|
+
code: "no_global_config",
|
|
47
|
+
severity: "warn",
|
|
48
|
+
message: "no global Fabric config \u2014 run `fabric install --global <url>`"
|
|
49
|
+
});
|
|
50
|
+
return diagnostics;
|
|
51
|
+
}
|
|
52
|
+
for (const missing of missingRequiredStores(projectRoot, globalRoot)) {
|
|
53
|
+
diagnostics.push({
|
|
54
|
+
code: "missing_required_store",
|
|
55
|
+
severity: "warn",
|
|
56
|
+
ref: missing.id,
|
|
57
|
+
message: `required store '${missing.id}' is not mounted; run \`fabric store add\``
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
for (const store of global.stores) {
|
|
61
|
+
if (store.remote === void 0 && store.personal !== true) {
|
|
62
|
+
diagnostics.push({
|
|
63
|
+
code: "local_only_store",
|
|
64
|
+
severity: "info",
|
|
65
|
+
ref: store.alias,
|
|
66
|
+
message: `store '${store.alias}' is local-only; add a git remote to back it up`
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const violations = findStoreExecutableViolations(join(globalRoot, storeRelativePath(store.store_uuid)));
|
|
70
|
+
if (violations.length > 0) {
|
|
71
|
+
diagnostics.push({
|
|
72
|
+
code: "executable_in_store",
|
|
73
|
+
severity: "warn",
|
|
74
|
+
ref: store.alias,
|
|
75
|
+
message: `store '${store.alias}' contains executable/script files (${violations.slice(0, 3).join(", ")}${violations.length > 3 ? ", \u2026" : ""}) \u2014 stores are data-only; Fabric never runs them (S65)`
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return diagnostics;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/commands/doctor.ts
|
|
83
|
+
import { buildDebugBundle } from "@fenglimg/fabric-shared";
|
|
27
84
|
var FIX_KNOWLEDGE_CODE_LABELS = {
|
|
28
85
|
knowledge_orphan_demote_required: "demote (maturity)",
|
|
29
86
|
knowledge_stale_archive_required: "archive (git mv)",
|
|
@@ -62,6 +119,14 @@ var doctorCommand = defineCommand({
|
|
|
62
119
|
description: t("cli.doctor.args.strict.description"),
|
|
63
120
|
default: false
|
|
64
121
|
},
|
|
122
|
+
// v2.1.0-rc.1 P6 (S40): emit a redacted diagnostic bundle (config + store
|
|
123
|
+
// diagnostics; events excluded by default). Every string is secret-redacted
|
|
124
|
+
// so the bundle is safe to paste into a bug report. Read-only.
|
|
125
|
+
"debug-bundle": {
|
|
126
|
+
type: "boolean",
|
|
127
|
+
description: "Emit a redacted diagnostic bundle (config + store health) for bug reports",
|
|
128
|
+
default: false
|
|
129
|
+
},
|
|
65
130
|
// rc.7 T11: skip the safety confirm before mutations. Required for any
|
|
66
131
|
// non-tty invocation that wants to run --fix-knowledge without setting
|
|
67
132
|
// FABRIC_NONINTERACTIVE=1 in the environment.
|
|
@@ -154,6 +219,24 @@ var doctorCommand = defineCommand({
|
|
|
154
219
|
const citeCoverage = args["cite-coverage"] === true;
|
|
155
220
|
const enrichDesc = args["enrich-descriptions"] === true;
|
|
156
221
|
const archiveHistory = args["archive-history"] === true;
|
|
222
|
+
if (args["debug-bundle"] === true) {
|
|
223
|
+
const globalRoot = resolveGlobalRoot();
|
|
224
|
+
let config = {};
|
|
225
|
+
try {
|
|
226
|
+
config = {
|
|
227
|
+
global: loadGlobalConfig(globalRoot) ?? null,
|
|
228
|
+
project: loadProjectConfig(resolution.target) ?? null
|
|
229
|
+
};
|
|
230
|
+
} catch {
|
|
231
|
+
config = {};
|
|
232
|
+
}
|
|
233
|
+
const bundle = buildDebugBundle({
|
|
234
|
+
config,
|
|
235
|
+
diagnostics: collectStoreDiagnostics(resolution.target)
|
|
236
|
+
});
|
|
237
|
+
writeStdout(JSON.stringify(bundle, null, 2));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
157
240
|
if (args.since !== void 0) {
|
|
158
241
|
try {
|
|
159
242
|
parseSinceDuration(args.since);
|
|
@@ -317,8 +400,15 @@ var doctorCommand = defineCommand({
|
|
|
317
400
|
} else {
|
|
318
401
|
report = await runDoctorReport(resolution.target);
|
|
319
402
|
}
|
|
403
|
+
const storeDiagnostics = collectStoreDiagnostics(resolution.target);
|
|
320
404
|
if (args.json === true) {
|
|
321
|
-
writeStdout(
|
|
405
|
+
writeStdout(
|
|
406
|
+
JSON.stringify(
|
|
407
|
+
{ ...fixKnowledgeReport ?? fixReport ?? report, store_diagnostics: storeDiagnostics },
|
|
408
|
+
null,
|
|
409
|
+
2
|
|
410
|
+
)
|
|
411
|
+
);
|
|
322
412
|
} else {
|
|
323
413
|
if (fixKnowledgeReport !== null) {
|
|
324
414
|
writeStdout(fixKnowledgeReport.message);
|
|
@@ -332,6 +422,7 @@ var doctorCommand = defineCommand({
|
|
|
332
422
|
writeStdout(dt("cli.doctor.fix-dry-run-banner"));
|
|
333
423
|
}
|
|
334
424
|
renderHumanReport(report, dt, args.verbose === true);
|
|
425
|
+
renderStoreDiagnostics(storeDiagnostics);
|
|
335
426
|
}
|
|
336
427
|
await emitDoctorRunEventBestEffort(resolution.target, {
|
|
337
428
|
mode: fixKnowledge ? "fix-knowledge" : "lint",
|
|
@@ -366,6 +457,25 @@ function renderHumanReport(report, dt, verbose) {
|
|
|
366
457
|
writeIssueSection(dt("doctor.section.warnings"), report.warnings, opts);
|
|
367
458
|
renderPayloadLimits(report, dt);
|
|
368
459
|
}
|
|
460
|
+
function collectStoreDiagnostics(projectRoot) {
|
|
461
|
+
try {
|
|
462
|
+
return storeDoctorChecks(projectRoot);
|
|
463
|
+
} catch {
|
|
464
|
+
return [];
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
function renderStoreDiagnostics(diagnostics) {
|
|
468
|
+
if (diagnostics.length === 0) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
writeStdout("");
|
|
472
|
+
writeStdout(paint.ai("store health"));
|
|
473
|
+
for (const diagnostic of diagnostics) {
|
|
474
|
+
const mark = diagnostic.severity === "warn" ? symbol.warn : "[info]";
|
|
475
|
+
const ref = diagnostic.ref === void 0 ? "" : ` [${diagnostic.ref}]`;
|
|
476
|
+
writeStdout(`${mark}${ref} ${diagnostic.message}`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
369
479
|
function renderPayloadLimits(report, dt) {
|
|
370
480
|
const limits = report.summary.payload_limits;
|
|
371
481
|
if (limits === void 0) {
|
package/dist/index.js
CHANGED
|
@@ -11,9 +11,17 @@ import { defineCommand, runMain } from "citty";
|
|
|
11
11
|
|
|
12
12
|
// src/commands/index.ts
|
|
13
13
|
var allCommands = {
|
|
14
|
-
install: () => import("./install-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
install: () => import("./install-2HDO5FTQ.js").then((module) => module.default),
|
|
15
|
+
// v2.1.0-rc.1 P3: multi-store lifecycle command group (list/add/remove/explain).
|
|
16
|
+
store: () => import("./store-XTSE5TY6.js").then((module) => module.default),
|
|
17
|
+
// v2.1.0-rc.1 P3 (S9/S17/S37): multi-store pull --rebase + push, conflict resume.
|
|
18
|
+
sync: () => import("./sync-BJCWDPNC.js").then((module) => module.default),
|
|
19
|
+
// v2.1.0-rc.1 P3 (F5): read-only identity/status info commands.
|
|
20
|
+
whoami: () => import("./whoami-B6AEMSEV.js").then((module) => module.default),
|
|
21
|
+
status: () => import("./status-GLQWLWH6.js").then((module) => module.default),
|
|
22
|
+
"scope-explain": () => import("./scope-explain-2F2R5URO.js").then((module) => module.default),
|
|
23
|
+
doctor: () => import("./doctor-QVNPHLJK.js").then((module) => module.default),
|
|
24
|
+
uninstall: () => import("./uninstall-TAXSUSKH.js").then((module) => module.default),
|
|
17
25
|
config: () => import("./config-XJIPZNUP.js").then((module) => module.default),
|
|
18
26
|
"plan-context-hint": () => import("./plan-context-hint-FC6P3WFE.js").then((module) => module.default),
|
|
19
27
|
// v2.0.0-rc.23 TASK-014 (F8c): S5 onboard-slot coverage. Used by the
|
|
@@ -27,7 +35,7 @@ var allCommands = {
|
|
|
27
35
|
var main = defineCommand({
|
|
28
36
|
meta: {
|
|
29
37
|
name: "fabric",
|
|
30
|
-
version: "2.0.
|
|
38
|
+
version: "2.1.0-rc.2",
|
|
31
39
|
description: t("cli.main.description")
|
|
32
40
|
},
|
|
33
41
|
subCommands: allCommands
|