@fenglimg/fabric-cli 2.2.0-rc.3 → 2.2.0-rc.8

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 (75) hide show
  1. package/README.md +8 -5
  2. package/dist/{chunk-5LQIHYFC.js → chunk-27HK6H5Y.js} +10 -5
  3. package/dist/{chunk-F6ITRM7T.js → chunk-2KBCTMID.js} +29 -6
  4. package/dist/{chunk-XC5RUHLK.js → chunk-3IOLS5EK.js} +23 -38
  5. package/dist/{chunk-XHHCRDIR.js → chunk-CMDW3PYK.js} +105 -220
  6. package/dist/chunk-FEOPLBGA.js +150 -0
  7. package/dist/{chunk-XCBVSGCS.js → chunk-FNHDQTPC.js} +1 -10
  8. package/dist/{chunk-2CY4BMTH.js → chunk-HORSMSZL.js} +9 -5
  9. package/dist/{doctor-J4O3X54I.js → chunk-JTHWLUD3.js} +103 -51
  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-QPAW6IYT.js +387 -0
  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-REZDNH4A.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-2COC3DO3.js +3277 -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-PANEGKU2.js → status-4R3TM4FJ.js} +8 -5
  28. package/dist/store-HOCORVL3.js +563 -0
  29. package/dist/{sync-EA5HZMXM.js → sync-DT5UJMMR.js} +36 -13
  30. package/dist/{uninstall-F75MPKQC.js → uninstall-62F4LNKI.js} +62 -140
  31. package/dist/{whoami-66YKY5DZ.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 +301 -161
  38. package/templates/hooks/knowledge-hint-broad.cjs +426 -207
  39. package/templates/hooks/knowledge-hint-narrow.cjs +56 -56
  40. package/templates/hooks/lib/banner-i18n.cjs +31 -0
  41. package/templates/hooks/lib/bindings-snapshot-reader.cjs +117 -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/lib/summary-fallback.cjs +82 -19
  47. package/templates/hooks/post-tooluse-mutation.cjs +112 -11
  48. package/templates/skills/fabric/SKILL.md +94 -0
  49. package/templates/skills/fabric-archive/SKILL.md +29 -26
  50. package/templates/skills/fabric-archive/ref/dry-run-scope.md +1 -1
  51. package/templates/skills/fabric-archive/ref/i18n-policy.md +2 -3
  52. package/templates/skills/fabric-archive/ref/phase-1-5-onboard.md +2 -3
  53. package/templates/skills/fabric-archive/ref/phase-1-cross-session.md +1 -1
  54. package/templates/skills/fabric-archive/ref/phase-2-5-viability.md +1 -1
  55. package/templates/skills/fabric-archive/ref/phase-3-6-related-edges.md +18 -0
  56. package/templates/skills/fabric-archive/ref/phase-3-7-semantic-scope.md +47 -0
  57. package/templates/skills/fabric-audit/SKILL.md +13 -3
  58. package/templates/skills/fabric-connect/SKILL.md +3 -3
  59. package/templates/skills/fabric-import/SKILL.md +7 -7
  60. package/templates/skills/fabric-import/ref/i18n-policy.md +2 -3
  61. package/templates/skills/fabric-import/ref/state-recovery.md +1 -2
  62. package/templates/skills/fabric-review/SKILL.md +5 -5
  63. package/templates/skills/fabric-review/ref/cite-contract.md +1 -1
  64. package/templates/skills/fabric-review/ref/i18n-policy.md +2 -3
  65. package/templates/skills/fabric-review/ref/output-contract.md +1 -1
  66. package/templates/skills/fabric-review/ref/per-mode-flows.md +2 -2
  67. package/templates/skills/fabric-review/ref/worked-examples.md +1 -1
  68. package/templates/skills/fabric-store/SKILL.md +1 -1
  69. package/templates/skills/fabric-sync/SKILL.md +1 -1
  70. package/templates/skills/lib/shared-policy.md +2 -2
  71. package/dist/chunk-5ZUMLCD5.js +0 -248
  72. package/dist/install-BULNDUIM.js +0 -2816
  73. package/dist/store-66NK2FTQ.js +0 -443
  74. package/templates/hooks/configs/cursor-hooks.json +0 -30
  75. package/templates/hooks/lib/cite-contract-reminder.cjs +0 -179
@@ -26,7 +26,7 @@ description: 多 store git 同步辅助 — 遍历挂载的知识 store, pull --
26
26
  ## Phase 2 — AI-assisted conflict resolution (仅冲突时)
27
27
 
28
28
  冲突 store 的工作区停在 rebase 中途。辅助用户:
29
- 1. 展示冲突文件 (store 知识树 `.fabric/knowledge/<type>/*.md` 中的 `<<<<<<<`/`=======`/`>>>>>>>` 段)。
29
+ 1. 展示冲突文件 (store 知识树 `knowledge/<type>/*.md` 中的 `<<<<<<<`/`=======`/`>>>>>>>` 段)。
30
30
  2. 对每个冲突,MUST 解释两侧 (ours = 本地草稿/晋升, theirs = 远端协作者) 并给出**合并建议**(知识条目通常可并存或取更成熟 maturity)。NEVER 擅自丢弃任一侧未经用户确认。
31
31
  3. 用户解决后 → `fabric sync --continue` (git rebase --continue + 恢复遍历剩余 store)。
32
32
  4. 用户选择放弃该 store → `fabric sync --abort` (git rebase --abort,该 store 留未同步,继续遍历其余)。
@@ -11,13 +11,13 @@ When rendering bilingual (zh-CN ↔ en) output, prose is translated but the
11
11
  following classes of token appear **verbatim in both variants**:
12
12
 
13
13
  - **MCP tool + field names**: `fab_extract_knowledge`, `fab_review`,
14
- `fab_recall`, `fab_plan_context`, `fab_get_knowledge_sections`,
14
+ `fab_recall`, `fab_archive_scan`,
15
15
  `relevance_scope`, `relevance_paths`, `source_sessions`, `proposed_reason`,
16
16
  `session_context`, `intent_clues`, `tech_stack`, `impact`, `must_read_if`,
17
17
  `evidence_paths`, `tags`, `pending_path`, `layer`.
18
18
  - **Enum / routing values**: `narrow`, `broad`, `team`, `personal`, `draft`,
19
19
  `verified`, `proven`, `knowledge_scope_degraded`.
20
- - **Imperatives + paths**: `MUST`, `NEVER`, `.fabric/knowledge/`, file paths.
20
+ - **Imperatives + paths**: `MUST`, `NEVER`, `knowledge/pending`, file paths.
21
21
 
22
22
  The authoritative machine-checked list is `PROTECTED_TOKENS` in
23
23
  `@fenglimg/fabric-shared` (enforced by `scripts/lint-protected-tokens.ts`).
@@ -1,248 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- loadGlobalConfig,
4
- loadProjectConfig,
5
- resolveGlobalRoot,
6
- saveGlobalConfig,
7
- saveProjectConfig
8
- } from "./chunk-XCBVSGCS.js";
9
-
10
- // src/store/store-ops.ts
11
- import { execFileSync } from "child_process";
12
- import { randomUUID } from "crypto";
13
- import { existsSync, lstatSync, mkdirSync, readdirSync, readlinkSync, rmSync, symlinkSync } from "fs";
14
- import { join } from "path";
15
- import {
16
- addMountedStore,
17
- bindRequiredStore,
18
- detachMountedStore,
19
- explainStore,
20
- initStore,
21
- STORES_ROOT_DIR,
22
- storeRelativePath
23
- } from "@fenglimg/fabric-shared";
24
- var NO_GLOBAL_CONFIG = "no global Fabric config found \u2014 run `fabric install --global <url>` first";
25
- function requireConfig(globalRoot) {
26
- const config = loadGlobalConfig(globalRoot);
27
- if (config === null) {
28
- throw new Error(NO_GLOBAL_CONFIG);
29
- }
30
- return config;
31
- }
32
- function storeList(globalRoot = resolveGlobalRoot()) {
33
- return requireConfig(globalRoot).stores;
34
- }
35
- var STORE_BY_ALIAS_DIR = "by-alias";
36
- function syncStoreAliasLinks(globalRoot = resolveGlobalRoot()) {
37
- const result = { created: [], removed: [], errors: [] };
38
- const config = loadGlobalConfig(globalRoot);
39
- if (config === null) {
40
- return result;
41
- }
42
- const byAliasDir = join(globalRoot, STORES_ROOT_DIR, STORE_BY_ALIAS_DIR);
43
- const desired = new Map(config.stores.map((s) => [s.alias, s.store_uuid]));
44
- try {
45
- mkdirSync(byAliasDir, { recursive: true });
46
- } catch {
47
- return result;
48
- }
49
- let existing = [];
50
- try {
51
- existing = readdirSync(byAliasDir);
52
- } catch {
53
- existing = [];
54
- }
55
- for (const name of existing) {
56
- if (desired.has(name)) {
57
- continue;
58
- }
59
- try {
60
- rmSync(join(byAliasDir, name), { force: true, recursive: false });
61
- result.removed.push(name);
62
- } catch {
63
- result.errors.push(name);
64
- }
65
- }
66
- for (const [alias, uuid] of desired) {
67
- const link = join(byAliasDir, alias);
68
- const target = join("..", uuid);
69
- try {
70
- let current = null;
71
- try {
72
- if (lstatSync(link).isSymbolicLink()) {
73
- current = readlinkSync(link);
74
- }
75
- } catch {
76
- current = null;
77
- }
78
- if (current === target) {
79
- continue;
80
- }
81
- rmSync(link, { force: true });
82
- symlinkSync(target, link);
83
- result.created.push(alias);
84
- } catch {
85
- result.errors.push(alias);
86
- }
87
- }
88
- return result;
89
- }
90
- function detectAliasLinkDrift(globalRoot = resolveGlobalRoot()) {
91
- const config = loadGlobalConfig(globalRoot);
92
- if (config === null) {
93
- return [];
94
- }
95
- const byAliasDir = join(globalRoot, STORES_ROOT_DIR, STORE_BY_ALIAS_DIR);
96
- if (!existsSync(byAliasDir)) {
97
- return [];
98
- }
99
- const drifted = [];
100
- for (const store of config.stores) {
101
- const link = join(byAliasDir, store.alias);
102
- const target = join("..", store.store_uuid);
103
- try {
104
- if (!lstatSync(link).isSymbolicLink() || readlinkSync(link) !== target) {
105
- drifted.push(store.alias);
106
- }
107
- } catch {
108
- drifted.push(store.alias);
109
- }
110
- }
111
- return drifted;
112
- }
113
- function storeAdd(store, globalRoot = resolveGlobalRoot()) {
114
- const next = addMountedStore(requireConfig(globalRoot), store);
115
- saveGlobalConfig(next, globalRoot);
116
- syncStoreAliasLinks(globalRoot);
117
- return next;
118
- }
119
- function storeCreate(alias, now, options = {}) {
120
- const globalRoot = options.globalRoot ?? resolveGlobalRoot();
121
- const config = requireConfig(globalRoot);
122
- const uuid = options.uuid ?? randomUUID();
123
- const storeDir = join(globalRoot, storeRelativePath(uuid));
124
- initStore(
125
- storeDir,
126
- { store_uuid: uuid, created_at: now, canonical_alias: alias },
127
- { git: options.git }
128
- );
129
- if (options.remote !== void 0 && options.git !== false) {
130
- gitRemoteAdd(storeDir, options.remote);
131
- }
132
- const mounted = options.remote === void 0 ? { store_uuid: uuid, alias } : { store_uuid: uuid, alias, remote: options.remote };
133
- const next = addMountedStore(config, mounted);
134
- saveGlobalConfig(next, globalRoot);
135
- syncStoreAliasLinks(globalRoot);
136
- return { config: next, store_uuid: uuid, storeDir };
137
- }
138
- function gitRemoteAdd(storeDir, remote) {
139
- try {
140
- execFileSync("git", ["remote", "add", "origin", remote], {
141
- cwd: storeDir,
142
- stdio: ["ignore", "ignore", "pipe"]
143
- });
144
- } catch {
145
- try {
146
- execFileSync("git", ["remote", "set-url", "origin", remote], {
147
- cwd: storeDir,
148
- stdio: ["ignore", "ignore", "pipe"]
149
- });
150
- } catch {
151
- }
152
- }
153
- }
154
- function storeGitRemote(uuid, globalRoot = resolveGlobalRoot()) {
155
- const storeDir = join(globalRoot, storeRelativePath(uuid));
156
- if (!existsSync(storeDir)) {
157
- return void 0;
158
- }
159
- try {
160
- const out = execFileSync("git", ["remote", "get-url", "origin"], {
161
- cwd: storeDir,
162
- stdio: ["ignore", "pipe", "pipe"],
163
- encoding: "utf8"
164
- });
165
- const trimmed = out.trim();
166
- return trimmed.length > 0 ? trimmed : void 0;
167
- } catch {
168
- return void 0;
169
- }
170
- }
171
- function assertStoreMountable(uuid, globalRoot = resolveGlobalRoot()) {
172
- const storeDir = join(globalRoot, storeRelativePath(uuid));
173
- if (!existsSync(join(storeDir, "store.json"))) {
174
- throw new Error(
175
- `cannot mount store ${uuid}: no store tree at ${storeDir} \u2014 clone it first (\`fabric install --global --url <remote>\`) or create it locally, then re-run \`fabric store add\`. Refusing to register a phantom store.`
176
- );
177
- }
178
- }
179
- function storeRemove(alias, globalRoot = resolveGlobalRoot()) {
180
- const result = detachMountedStore(requireConfig(globalRoot), alias);
181
- saveGlobalConfig(result.config, globalRoot);
182
- syncStoreAliasLinks(globalRoot);
183
- return result;
184
- }
185
- function storeExplain(alias, globalRoot = resolveGlobalRoot()) {
186
- return explainStore(requireConfig(globalRoot), alias);
187
- }
188
- var NO_PROJECT_CONFIG = "no project Fabric config \u2014 run `fabric install` in this repo first";
189
- function requireProjectConfig(projectRoot) {
190
- const config = loadProjectConfig(projectRoot);
191
- if (config === null) {
192
- throw new Error(NO_PROJECT_CONFIG);
193
- }
194
- return config;
195
- }
196
- function storeBind(projectRoot, entry) {
197
- const config = requireProjectConfig(projectRoot);
198
- const next = {
199
- ...config,
200
- required_stores: bindRequiredStore(config.required_stores ?? [], entry)
201
- };
202
- saveProjectConfig(next, projectRoot);
203
- return next;
204
- }
205
- function storeSwitchWrite(projectRoot, alias) {
206
- const config = requireProjectConfig(projectRoot);
207
- const next = { ...config, active_write_store: alias };
208
- saveProjectConfig(next, projectRoot);
209
- return next;
210
- }
211
- function missingRequiredStores(projectRoot, globalRoot = resolveGlobalRoot()) {
212
- const project = loadProjectConfig(projectRoot);
213
- if (project === null || project.required_stores === void 0) {
214
- return [];
215
- }
216
- const global = loadGlobalConfig(globalRoot);
217
- const mounted = new Set(
218
- (global?.stores ?? []).flatMap((s) => [s.alias, s.store_uuid])
219
- );
220
- return project.required_stores.filter((r) => !mounted.has(r.id));
221
- }
222
- function unboundAvailableStores(projectRoot, globalRoot = resolveGlobalRoot()) {
223
- const global = loadGlobalConfig(globalRoot);
224
- if (global === null) {
225
- return [];
226
- }
227
- const project = loadProjectConfig(projectRoot);
228
- const declared = new Set((project?.required_stores ?? []).map((r) => r.id));
229
- return global.stores.filter(
230
- (s) => s.personal !== true && !declared.has(s.alias) && !declared.has(s.store_uuid)
231
- );
232
- }
233
-
234
- export {
235
- storeList,
236
- syncStoreAliasLinks,
237
- detectAliasLinkDrift,
238
- storeAdd,
239
- storeCreate,
240
- storeGitRemote,
241
- assertStoreMountable,
242
- storeRemove,
243
- storeExplain,
244
- storeBind,
245
- storeSwitchWrite,
246
- missingRequiredStores,
247
- unboundAvailableStores
248
- };