@fenglimg/fabric-cli 2.2.0-rc.4 → 2.2.0-rc.9

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.
Files changed (73) hide show
  1. package/README.md +8 -5
  2. package/dist/{chunk-5JG4QJLO.js → chunk-27HK6H5Y.js} +10 -5
  3. package/dist/{chunk-F6ITRM7T.js → chunk-2KBCTMID.js} +29 -6
  4. package/dist/chunk-3D7B2UAZ.js +149 -0
  5. package/dist/{chunk-XC5RUHLK.js → chunk-3IOLS5EK.js} +23 -38
  6. package/dist/{chunk-XHHCRDIR.js → chunk-7ZDXBOOU.js} +174 -211
  7. package/dist/{doctor-U5W4CX5I.js → chunk-E7HJUU34.js} +103 -51
  8. package/dist/{chunk-XCBVSGCS.js → chunk-FNHDQTPC.js} +1 -10
  9. package/dist/{chunk-2CY4BMTH.js → chunk-HORSMSZL.js} +9 -5
  10. package/dist/{chunk-BO4XIZWZ.js → chunk-NLNH64A3.js} +5 -18
  11. package/dist/{chunk-H3FE6VIK.js → chunk-PTGQAZEW.js} +13 -3
  12. package/dist/chunk-QFIVFZRH.js +13 -0
  13. package/dist/{chunk-5SSNE5GM.js → chunk-QPAW6IYT.js} +125 -39
  14. package/dist/{chunk-COI5VDFU.js → chunk-WA3DYGSY.js} +1 -2
  15. package/dist/{plan-context-hint-CHVZGOZ5.js → chunk-YM4XATJF.js} +29 -4
  16. package/dist/{config-VJMXCLXW.js → config-A3LTECAY.js} +4 -3
  17. package/dist/context-7NUKXDB6.js +117 -0
  18. package/dist/doctor-MDTZWKBK.js +24 -0
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.js +131 -21
  21. package/dist/info-7FKBTMVO.js +139 -0
  22. package/dist/install-v2-I6PJ6IFT.js +3279 -0
  23. package/dist/{metrics-RER6NLFC.js → metrics-HMFH4YHK.js} +1 -1
  24. package/dist/{onboard-coverage-JWQWDZW7.js → onboard-coverage-XSG77LL3.js} +48 -27
  25. package/dist/plan-context-hint-G75R4P4J.js +12 -0
  26. package/dist/{scope-explain-BWRWBCCP.js → scope-explain-HLJZ2M33.js} +3 -2
  27. package/dist/{status-7UFLWRX7.js → status-4R3TM4FJ.js} +8 -5
  28. package/dist/{store-ZEZMQVG7.js → store-HOCORVL3.js} +96 -350
  29. package/dist/{sync-EA5HZMXM.js → sync-DT5UJMMR.js} +36 -13
  30. package/dist/{uninstall-F75MPKQC.js → uninstall-IFN2KYBK.js} +71 -140
  31. package/dist/{whoami-3FRWYGML.js → whoami-ITGEFWH4.js} +9 -7
  32. package/package.json +7 -5
  33. package/templates/hooks/cite-policy-evict.cjs +5 -5
  34. package/templates/hooks/configs/README.md +14 -27
  35. package/templates/hooks/configs/claude-code.json +1 -1
  36. package/templates/hooks/configs/codex-hooks.json +3 -3
  37. package/templates/hooks/fabric-hint.cjs +326 -161
  38. package/templates/hooks/knowledge-hint-broad.cjs +431 -271
  39. package/templates/hooks/knowledge-hint-narrow.cjs +64 -77
  40. package/templates/hooks/lib/banner-i18n.cjs +31 -0
  41. package/templates/hooks/lib/bindings-snapshot-reader.cjs +118 -7
  42. package/templates/hooks/lib/cite-line-parser.cjs +12 -20
  43. package/templates/hooks/lib/client-adapter.cjs +66 -7
  44. package/templates/hooks/lib/nudge-policy.cjs +117 -0
  45. package/templates/hooks/lib/state-store.cjs +60 -0
  46. package/templates/hooks/post-tooluse-mutation.cjs +112 -11
  47. package/templates/skills/fabric/SKILL.md +100 -0
  48. package/templates/skills/fabric-archive/SKILL.md +29 -26
  49. package/templates/skills/fabric-archive/ref/dry-run-scope.md +1 -1
  50. package/templates/skills/fabric-archive/ref/i18n-policy.md +2 -3
  51. package/templates/skills/fabric-archive/ref/phase-1-5-onboard.md +2 -3
  52. package/templates/skills/fabric-archive/ref/phase-1-cross-session.md +1 -1
  53. package/templates/skills/fabric-archive/ref/phase-2-5-viability.md +1 -1
  54. package/templates/skills/fabric-archive/ref/phase-3-6-related-edges.md +18 -0
  55. package/templates/skills/fabric-archive/ref/phase-3-7-semantic-scope.md +47 -0
  56. package/templates/skills/fabric-audit/SKILL.md +13 -3
  57. package/templates/skills/fabric-connect/SKILL.md +3 -3
  58. package/templates/skills/fabric-import/SKILL.md +7 -7
  59. package/templates/skills/fabric-import/ref/i18n-policy.md +2 -3
  60. package/templates/skills/fabric-import/ref/state-recovery.md +1 -2
  61. package/templates/skills/fabric-review/SKILL.md +5 -5
  62. package/templates/skills/fabric-review/ref/cite-contract.md +1 -1
  63. package/templates/skills/fabric-review/ref/i18n-policy.md +2 -3
  64. package/templates/skills/fabric-review/ref/output-contract.md +1 -1
  65. package/templates/skills/fabric-review/ref/per-mode-flows.md +2 -2
  66. package/templates/skills/fabric-review/ref/worked-examples.md +1 -1
  67. package/templates/skills/fabric-store/SKILL.md +1 -1
  68. package/templates/skills/fabric-sync/SKILL.md +1 -1
  69. package/templates/skills/lib/shared-policy.md +2 -2
  70. package/dist/install-7XJ64WSC.js +0 -2743
  71. package/templates/hooks/configs/cursor-hooks.json +0 -30
  72. package/templates/hooks/lib/cite-contract-reminder.cjs +0 -179
  73. package/templates/hooks/lib/summary-fallback.cjs +0 -210
package/dist/index.js CHANGED
@@ -1,42 +1,56 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ renderDoctorFilteredHelp
4
+ } from "./chunk-E7HJUU34.js";
5
+ import "./chunk-3D7B2UAZ.js";
6
+ import "./chunk-WA3DYGSY.js";
7
+ import "./chunk-NLNH64A3.js";
8
+ import "./chunk-PTGQAZEW.js";
9
+ import "./chunk-EOT63RDH.js";
10
+ import "./chunk-QPAW6IYT.js";
11
+ import "./chunk-QFIVFZRH.js";
12
+ import "./chunk-FNHDQTPC.js";
2
13
  import {
3
14
  t
4
- } from "./chunk-2CY4BMTH.js";
15
+ } from "./chunk-HORSMSZL.js";
5
16
 
6
17
  // src/index.ts
7
18
  import { realpathSync } from "fs";
8
19
  import { resolve } from "path";
9
20
  import { fileURLToPath } from "url";
10
- import { defineCommand, runCommand, runMain } from "citty";
21
+ import { defineCommand, renderUsage, runCommand, runMain } from "citty";
11
22
 
12
23
  // src/commands/index.ts
13
24
  var allCommands = {
14
- install: () => import("./install-7XJ64WSC.js").then((module) => module.default),
25
+ // v2.2.0-rc.5: pipeline-based install with TUI renderer (EPIC-005/006/007/008)
26
+ install: () => import("./install-v2-I6PJ6IFT.js").then((module) => module.installCommand),
15
27
  // v2.1.0-rc.1 P3: multi-store lifecycle command group (list/add/remove/explain).
16
- store: () => import("./store-ZEZMQVG7.js").then((module) => module.default),
28
+ store: () => import("./store-HOCORVL3.js").then((module) => module.default),
17
29
  // v2.1.0-rc.1 P3 (S9/S17/S37): multi-store pull --rebase + push, conflict resume.
18
- sync: () => import("./sync-EA5HZMXM.js").then((module) => module.default),
30
+ sync: () => import("./sync-DT5UJMMR.js").then((module) => module.default),
31
+ // EPIC-010: Unified info command (replaces whoami/status/scope-explain).
32
+ info: () => import("./info-7FKBTMVO.js").then((module) => module.default),
19
33
  // v2.1.0-rc.1 P3 (F5): read-only identity/status info commands.
20
- whoami: () => import("./whoami-3FRWYGML.js").then((module) => module.default),
21
- status: () => import("./status-7UFLWRX7.js").then((module) => module.default),
22
- "scope-explain": () => import("./scope-explain-BWRWBCCP.js").then((module) => module.default),
23
- doctor: () => import("./doctor-U5W4CX5I.js").then((module) => module.default),
24
- uninstall: () => import("./uninstall-F75MPKQC.js").then((module) => module.default),
25
- config: () => import("./config-VJMXCLXW.js").then((module) => module.default),
26
- "plan-context-hint": () => import("./plan-context-hint-CHVZGOZ5.js").then((module) => module.default),
34
+ // DEPRECATED: Use `fabric info` instead. These will be removed in v3.
35
+ whoami: () => import("./whoami-ITGEFWH4.js").then((module) => module.default),
36
+ status: () => import("./status-4R3TM4FJ.js").then((module) => module.default),
37
+ "scope-explain": () => import("./scope-explain-HLJZ2M33.js").then((module) => module.default),
38
+ doctor: () => import("./doctor-MDTZWKBK.js").then((module) => module.default),
39
+ uninstall: () => import("./uninstall-IFN2KYBK.js").then((module) => module.default),
40
+ config: () => import("./config-A3LTECAY.js").then((module) => module.default),
41
+ "plan-context-hint": () => import("./plan-context-hint-G75R4P4J.js").then((module) => module.default),
27
42
  // v2.0.0-rc.23 TASK-014 (F8c): S5 onboard-slot coverage. Used by the
28
43
  // fabric-archive Skill's first-run phase to detect unclaimed slots.
29
- "onboard-coverage": () => import("./onboard-coverage-JWQWDZW7.js").then((module) => module.default),
44
+ "onboard-coverage": () => import("./onboard-coverage-XSG77LL3.js").then((module) => module.default),
30
45
  // v2.0.0-rc.37 NEW-34: text dashboard over .fabric/metrics.jsonl.
31
- metrics: () => import("./metrics-RER6NLFC.js").then((module) => module.default)
46
+ metrics: () => import("./metrics-HMFH4YHK.js").then((module) => module.default),
47
+ // Block 5 (Option X): show what SessionStart injects (shared renderer with the
48
+ // hook → byte-identical). --explain for per-entry provenance.
49
+ context: () => import("./context-7NUKXDB6.js").then((module) => module.default)
32
50
  };
33
51
 
34
52
  // src/lib/error-render.ts
35
- function hasActionHint(err) {
36
- if (err === null || typeof err !== "object") return false;
37
- const candidate = err;
38
- return typeof candidate.message === "string" && candidate.message.length > 0 && typeof candidate.actionHint === "string" && candidate.actionHint.length > 0;
39
- }
53
+ import { hasActionHint } from "@fenglimg/fabric-shared/errors";
40
54
  function renderFabricError(err, stream = process.stderr) {
41
55
  stream.write(`${err.message}
42
56
  `);
@@ -51,21 +65,117 @@ function renderTopLevelError(err, stream = process.stderr) {
51
65
  return "other";
52
66
  }
53
67
 
68
+ // src/lib/grouped-help.ts
69
+ function getGroupedCommands() {
70
+ const groups = [
71
+ {
72
+ name: "Setup",
73
+ commands: [
74
+ { name: "install", description: t("cli.help.group.setup.install") },
75
+ { name: "uninstall", description: t("cli.uninstall.description").split("\n")[0] ?? "Uninstall Fabric" },
76
+ { name: "config", description: t("cli.help.group.setup.config") }
77
+ ]
78
+ },
79
+ {
80
+ name: "Daily",
81
+ commands: [
82
+ { name: "sync", description: t("cli.help.group.daily.sync") },
83
+ { name: "info", description: t("cli.help.group.daily.info") }
84
+ ]
85
+ },
86
+ {
87
+ name: "Diagnostic",
88
+ commands: [
89
+ { name: "doctor", description: t("cli.help.group.diagnostic.doctor") }
90
+ ]
91
+ },
92
+ {
93
+ name: "Advanced",
94
+ commands: [
95
+ { name: "store", description: t("cli.help.group.advanced.store") },
96
+ {
97
+ name: "whoami",
98
+ description: t("cli.help.group.advanced.whoami"),
99
+ deprecated: true,
100
+ deprecatedNote: t("cli.help.group.advanced.whoami.deprecated")
101
+ },
102
+ {
103
+ name: "status",
104
+ description: t("cli.help.group.advanced.status"),
105
+ deprecated: true,
106
+ deprecatedNote: t("cli.help.group.advanced.status.deprecated")
107
+ },
108
+ {
109
+ name: "scope-explain",
110
+ description: t("cli.help.group.advanced.scope-explain"),
111
+ deprecated: true,
112
+ deprecatedNote: t("cli.help.group.advanced.scope-explain.deprecated")
113
+ }
114
+ ]
115
+ }
116
+ ];
117
+ return groups;
118
+ }
119
+ function renderGroupedHelp(cmd, version) {
120
+ const groups = getGroupedCommands();
121
+ const lines = [];
122
+ lines.push("fabric - Cross-client AI knowledge layer");
123
+ lines.push("");
124
+ lines.push(`First time? Run: fabric install`);
125
+ lines.push("");
126
+ for (const group of groups) {
127
+ lines.push(`${group.name}:`);
128
+ for (const command of group.commands) {
129
+ const name = command.name.padEnd(14);
130
+ let line = ` ${name}${command.description}`;
131
+ if (command.deprecated) {
132
+ line += ` (${command.deprecatedNote})`;
133
+ }
134
+ lines.push(line);
135
+ }
136
+ lines.push("");
137
+ }
138
+ lines.push(`Run \`fabric <command> --help\` for details.`);
139
+ return lines.join("\n");
140
+ }
141
+ async function customShowUsageGrouped(cmd, parent, version) {
142
+ const cmdMeta = await (typeof cmd.meta === "function" ? cmd.meta() : cmd.meta);
143
+ if (cmdMeta?.name === "fabric" && parent === void 0) {
144
+ const ver = version || cmdMeta?.version || "";
145
+ console.log(renderGroupedHelp(cmd, ver));
146
+ } else {
147
+ const { renderUsage: renderUsage2 } = await import("citty");
148
+ console.log(await renderUsage2(cmd, parent) + "\n");
149
+ }
150
+ }
151
+
54
152
  // src/index.ts
55
153
  var main = defineCommand({
56
154
  meta: {
57
155
  name: "fabric",
58
- version: "2.2.0-rc.4",
156
+ version: "2.2.0-rc.9",
59
157
  description: t("cli.main.description")
60
158
  },
61
159
  subCommands: allCommands
62
160
  });
161
+ async function customShowUsage(cmd, parent) {
162
+ const cmdMeta = await (typeof cmd.meta === "function" ? cmd.meta() : cmd.meta);
163
+ if (cmdMeta?.name === "doctor" && parent !== void 0) {
164
+ renderDoctorFilteredHelp();
165
+ return;
166
+ }
167
+ if (cmdMeta?.name === "fabric" && parent === void 0) {
168
+ await customShowUsageGrouped(cmd, parent, "2.2.0-rc.9");
169
+ return;
170
+ }
171
+ console.log(await renderUsage(cmd, parent) + "\n");
172
+ }
63
173
  async function run() {
64
174
  const rawArgs = process.argv.slice(2);
65
175
  const wantsHelp = rawArgs.some((arg) => arg === "--help" || arg === "-h");
66
176
  const wantsVersion = rawArgs.length === 1 && (rawArgs[0] === "--version" || rawArgs[0] === "-v");
67
177
  if (wantsHelp || wantsVersion) {
68
- await runMain(main, { rawArgs });
178
+ await runMain(main, { rawArgs, showUsage: customShowUsage });
69
179
  return;
70
180
  }
71
181
  try {
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ scopeExplain
4
+ } from "./chunk-EOT63RDH.js";
5
+ import {
6
+ projectStatus,
7
+ warnUnknownFlags,
8
+ whoami
9
+ } from "./chunk-27HK6H5Y.js";
10
+ import "./chunk-QPAW6IYT.js";
11
+ import "./chunk-QFIVFZRH.js";
12
+ import "./chunk-FNHDQTPC.js";
13
+ import {
14
+ getProjectTranslator
15
+ } from "./chunk-HORSMSZL.js";
16
+
17
+ // src/commands/info.ts
18
+ import { defineCommand } from "citty";
19
+ import { FabricError } from "@fenglimg/fabric-shared/errors";
20
+ var info_default = defineCommand({
21
+ meta: {
22
+ name: "info",
23
+ description: "Unified information command for Fabric identity, project status, and scope resolution"
24
+ },
25
+ args: {
26
+ // Subcommand detection
27
+ subcommand: {
28
+ type: "positional",
29
+ required: false,
30
+ description: "Subcommand: 'scope' for scope explanation"
31
+ },
32
+ scope: {
33
+ type: "positional",
34
+ required: false,
35
+ description: "Scope coordinate (used with 'scope' subcommand)"
36
+ },
37
+ // Flags
38
+ global: {
39
+ type: "boolean",
40
+ description: "Show global identity (whoami) instead of project status",
41
+ alias: "g"
42
+ },
43
+ json: {
44
+ type: "boolean",
45
+ description: "Emit machine-readable JSON instead of text"
46
+ }
47
+ },
48
+ run({ args }) {
49
+ warnUnknownFlags(["global", "g", "json"]);
50
+ const mode = resolveMode(args);
51
+ switch (mode) {
52
+ case "whoami":
53
+ runWhoami(args.json);
54
+ break;
55
+ case "scope-explain":
56
+ if (typeof args.scope !== "string" || args.scope.length === 0) {
57
+ console.error("Usage: fabric info scope <scope>");
58
+ process.exitCode = 1;
59
+ break;
60
+ }
61
+ runScopeExplain(args.scope);
62
+ break;
63
+ case "status":
64
+ default:
65
+ runStatus(args.json);
66
+ break;
67
+ }
68
+ }
69
+ });
70
+ function resolveMode(args) {
71
+ if (args.subcommand === "scope") {
72
+ return "scope-explain";
73
+ }
74
+ if (args.global === true) {
75
+ return "whoami";
76
+ }
77
+ return "status";
78
+ }
79
+ function runWhoami(json) {
80
+ const info = whoami();
81
+ if (json === true) {
82
+ console.log(JSON.stringify(info, null, 2));
83
+ return;
84
+ }
85
+ const t = getProjectTranslator();
86
+ if (info === null) {
87
+ console.log(t("cli.cmd.no-global-config"));
88
+ return;
89
+ }
90
+ console.log(t("cli.whoami.uid", { uid: info.uid }));
91
+ if (info.stores.length === 0) {
92
+ console.log(t("cli.whoami.stores-none"));
93
+ return;
94
+ }
95
+ console.log(t("cli.whoami.stores-label"));
96
+ const localOnly = t("cli.shared.local-only");
97
+ for (const store of info.stores) {
98
+ console.log(
99
+ ` ${store.alias} ${store.mount_name ?? store.store_uuid} ${store.store_uuid}${store.local_only ? ` ${localOnly}` : ""}`
100
+ );
101
+ }
102
+ }
103
+ function runStatus(json) {
104
+ const status = projectStatus(process.cwd());
105
+ if (json === true) {
106
+ console.log(JSON.stringify(status, null, 2));
107
+ return;
108
+ }
109
+ console.log(`uid: ${status.uid ?? "(no global config)"}`);
110
+ const projectIdLabel = status.project_id ?? (status.is_fabric_project ? "(unset)" : "(not a Fabric project)");
111
+ console.log(`project_id: ${projectIdLabel}`);
112
+ console.log(`mounted stores: ${status.mounted.length > 0 ? status.mounted.join(", ") : "(none)"}`);
113
+ console.log(`required: ${status.required.length > 0 ? status.required.join(", ") : "(none)"}`);
114
+ console.log(`default write: ${status.default_write_store ?? status.active_write_store ?? "(none \u2014 personal scope only)"}`);
115
+ console.log(`write routes: ${status.write_routes.length}`);
116
+ }
117
+ function runScopeExplain(scope) {
118
+ const projectRoot = process.cwd();
119
+ let result;
120
+ try {
121
+ result = scopeExplain(projectRoot, scope);
122
+ } catch (error) {
123
+ if (error instanceof FabricError) {
124
+ console.error(`${error.message}
125
+ \u2192 ${error.actionHint}`);
126
+ process.exitCode = 1;
127
+ return;
128
+ }
129
+ throw error;
130
+ }
131
+ if (result === null) {
132
+ console.log(getProjectTranslator(projectRoot)("cli.cmd.no-global-config"));
133
+ return;
134
+ }
135
+ console.log(JSON.stringify(result, null, 2));
136
+ }
137
+ export {
138
+ info_default as default
139
+ };