@fenglimg/fabric-cli 2.2.0-rc.1 → 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.
Files changed (83) hide show
  1. package/README.md +8 -5
  2. package/dist/chunk-27HK6H5Y.js +69 -0
  3. package/dist/{chunk-AOE6AYI7.js → chunk-2KBCTMID.js} +31 -8
  4. package/dist/chunk-3D7B2UAZ.js +149 -0
  5. package/dist/{chunk-XC5RUHLK.js → chunk-3IOLS5EK.js} +23 -38
  6. package/dist/{plan-context-hint-FC6P3WFE.js → chunk-722JU5BP.js} +52 -12
  7. package/dist/{chunk-2R55HNVD.js → chunk-7ZDXBOOU.js} +234 -206
  8. package/dist/{doctor-YONYXDX6.js → chunk-E7HJUU34.js} +215 -52
  9. package/dist/chunk-EOT63RDH.js +36 -0
  10. package/dist/chunk-FNHDQTPC.js +16 -0
  11. package/dist/{chunk-2CY4BMTH.js → chunk-HORSMSZL.js} +9 -5
  12. package/dist/{chunk-BO4XIZWZ.js → chunk-NLNH64A3.js} +5 -18
  13. package/dist/{chunk-WU6GAPKH.js → chunk-PTGQAZEW.js} +12 -4
  14. package/dist/chunk-QFIVFZRH.js +13 -0
  15. package/dist/chunk-QPAW6IYT.js +387 -0
  16. package/dist/{chunk-COI5VDFU.js → chunk-WA3DYGSY.js} +1 -2
  17. package/dist/{config-XYRBZJDU.js → config-A3LTECAY.js} +4 -3
  18. package/dist/context-UJCGYOT6.js +117 -0
  19. package/dist/doctor-MDTZWKBK.js +24 -0
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +133 -22
  22. package/dist/info-7FKBTMVO.js +139 -0
  23. package/dist/install-v2-RINEA24K.js +3279 -0
  24. package/dist/{metrics-RER6NLFC.js → metrics-HMFH4YHK.js} +1 -1
  25. package/dist/{onboard-coverage-JWQWDZW7.js → onboard-coverage-XSG77LL3.js} +48 -27
  26. package/dist/plan-context-hint-5TNGH3R4.js +12 -0
  27. package/dist/{scope-explain-CDIZESP5.js → scope-explain-HLJZ2M33.js} +17 -6
  28. package/dist/status-4R3TM4FJ.js +37 -0
  29. package/dist/store-HOCORVL3.js +563 -0
  30. package/dist/{sync-UJ4BBCZJ.js → sync-DT5UJMMR.js} +197 -30
  31. package/dist/{uninstall-C3QXKOO6.js → uninstall-IFN2KYBK.js} +97 -140
  32. package/dist/whoami-ITGEFWH4.js +49 -0
  33. package/package.json +7 -5
  34. package/templates/hooks/cite-policy-evict.cjs +412 -160
  35. package/templates/hooks/configs/README.md +14 -27
  36. package/templates/hooks/configs/claude-code.json +17 -2
  37. package/templates/hooks/configs/codex-hooks.json +15 -3
  38. package/templates/hooks/fabric-hint.cjs +477 -176
  39. package/templates/hooks/knowledge-hint-broad.cjs +577 -274
  40. package/templates/hooks/knowledge-hint-narrow.cjs +113 -73
  41. package/templates/hooks/lib/banner-i18n.cjs +31 -0
  42. package/templates/hooks/lib/bindings-snapshot-reader.cjs +118 -7
  43. package/templates/hooks/lib/cite-line-parser.cjs +12 -20
  44. package/templates/hooks/lib/client-adapter.cjs +66 -7
  45. package/templates/hooks/lib/nudge-policy.cjs +117 -0
  46. package/templates/hooks/lib/state-store.cjs +60 -0
  47. package/templates/hooks/post-tooluse-mutation.cjs +386 -0
  48. package/templates/hooks/session-end-marker.cjs +140 -0
  49. package/templates/skills/fabric/SKILL.md +100 -0
  50. package/templates/skills/fabric-archive/SKILL.md +35 -24
  51. package/templates/skills/fabric-archive/ref/dry-run-scope.md +1 -1
  52. package/templates/skills/fabric-archive/ref/i18n-policy.md +2 -3
  53. package/templates/skills/fabric-archive/ref/phase-1-5-onboard.md +2 -3
  54. package/templates/skills/fabric-archive/ref/phase-1-cross-session.md +1 -1
  55. package/templates/skills/fabric-archive/ref/phase-2-5-viability.md +1 -1
  56. package/templates/skills/fabric-archive/ref/phase-3-6-related-edges.md +18 -0
  57. package/templates/skills/fabric-archive/ref/phase-3-7-semantic-scope.md +47 -0
  58. package/templates/skills/fabric-audit/SKILL.md +13 -3
  59. package/templates/skills/fabric-connect/SKILL.md +3 -3
  60. package/templates/skills/fabric-import/SKILL.md +7 -7
  61. package/templates/skills/fabric-import/ref/i18n-policy.md +2 -3
  62. package/templates/skills/fabric-import/ref/state-recovery.md +1 -2
  63. package/templates/skills/fabric-review/SKILL.md +14 -5
  64. package/templates/skills/fabric-review/ref/cite-contract.md +1 -1
  65. package/templates/skills/fabric-review/ref/i18n-policy.md +2 -3
  66. package/templates/skills/fabric-review/ref/output-contract.md +1 -1
  67. package/templates/skills/fabric-review/ref/per-mode-flows.md +2 -2
  68. package/templates/skills/fabric-review/ref/worked-examples.md +1 -1
  69. package/templates/skills/fabric-store/SKILL.md +1 -1
  70. package/templates/skills/fabric-sync/SKILL.md +1 -1
  71. package/templates/skills/lib/shared-policy.md +2 -2
  72. package/dist/chunk-4R2CYEA4.js +0 -116
  73. package/dist/chunk-L4Q55UC4.js +0 -52
  74. package/dist/chunk-LFIKMVY7.js +0 -27
  75. package/dist/chunk-RYAFBNES.js +0 -33
  76. package/dist/chunk-T5RPGCCM.js +0 -40
  77. package/dist/install-74ANPCCP.js +0 -2737
  78. package/dist/status-GLQWLWH6.js +0 -23
  79. package/dist/store-XB3ADT65.js +0 -144
  80. package/dist/whoami-2MLO4Y37.js +0 -36
  81. package/templates/hooks/configs/cursor-hooks.json +0 -18
  82. package/templates/hooks/lib/cite-contract-reminder.cjs +0 -179
  83. package/templates/hooks/lib/summary-fallback.cjs +0 -210
@@ -36,7 +36,7 @@ Inferred mode: `revisit` (Step 1 keyword "look at <id>").
36
36
 
37
37
  Skill flow:
38
38
 
39
- 1. Read `.fabric/knowledge/team/guidelines/KT-G-0003--indent-style.md`. Display body to user.
39
+ 1. Read the canonical path returned by `fab_review search` for `KT-G-0003`. Display body to user.
40
40
  2. AskUserQuestion `{options: ["approve", "modify", "reject", "skip"]}` — user picks `modify`.
41
41
  3. Skill detects user-stated intent "actually personal not team" — surface AskUserQuestion `{options: ["team", "personal"]}` with current layer=team noted; user confirms `personal`.
42
42
  4. Call:
@@ -39,6 +39,6 @@ description: 知识 store 运维门面 — 创建 / 挂载 / 绑定 / 列出 /
39
39
 
40
40
  - `store remove` 是 *detach ≠ delete*:从 registry 卸载但 MUST 保留磁盘 git 树。
41
41
  - `store add` MUST 拒绝磁盘无 store 树的 uuid (无「幽灵挂载」) —— 先 clone (`fabric install --global --url <remote>`) 或 `store create`。
42
- - 知识条目写在各 store 的 `.fabric/knowledge/` 下;本 skill 只管 store 生命周期,不写条目。
42
+ - 知识条目写在各 store 的 `knowledge/` 下;本 skill 只管 store 生命周期,不写条目。
43
43
  - Personal-scope 写永远落在隐式 personal store,与 active write store 无关。
44
44
  - Hook/skill NEVER 直接解析 store 或执行 store 内文件 (S65 RCE 防线:store 是数据-only);所有 store 状态 MUST 经 CLI JSON 输出获取。
@@ -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,116 +0,0 @@
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 { randomUUID } from "crypto";
14
- import { existsSync } from "fs";
15
- import { join } from "path";
16
- import {
17
- addMountedStore,
18
- bindRequiredStore,
19
- detachMountedStore,
20
- explainStore,
21
- initStore,
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
- function storeAdd(store, globalRoot = resolveGlobalRoot()) {
36
- const next = addMountedStore(requireConfig(globalRoot), store);
37
- saveGlobalConfig(next, globalRoot);
38
- return next;
39
- }
40
- function storeCreate(alias, now, options = {}) {
41
- const globalRoot = options.globalRoot ?? resolveGlobalRoot();
42
- const config = requireConfig(globalRoot);
43
- const uuid = options.uuid ?? randomUUID();
44
- const storeDir = join(globalRoot, storeRelativePath(uuid));
45
- initStore(
46
- storeDir,
47
- { store_uuid: uuid, created_at: now, canonical_alias: alias },
48
- { git: options.git }
49
- );
50
- const mounted = options.remote === void 0 ? { store_uuid: uuid, alias } : { store_uuid: uuid, alias, remote: options.remote };
51
- const next = addMountedStore(config, mounted);
52
- saveGlobalConfig(next, globalRoot);
53
- return { config: next, store_uuid: uuid, storeDir };
54
- }
55
- function assertStoreMountable(uuid, globalRoot = resolveGlobalRoot()) {
56
- const storeDir = join(globalRoot, storeRelativePath(uuid));
57
- if (!existsSync(join(storeDir, "store.json"))) {
58
- throw new Error(
59
- `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.`
60
- );
61
- }
62
- }
63
- function storeRemove(alias, globalRoot = resolveGlobalRoot()) {
64
- const result = detachMountedStore(requireConfig(globalRoot), alias);
65
- saveGlobalConfig(result.config, globalRoot);
66
- return result;
67
- }
68
- function storeExplain(alias, globalRoot = resolveGlobalRoot()) {
69
- return explainStore(requireConfig(globalRoot), alias);
70
- }
71
- var NO_PROJECT_CONFIG = "no project Fabric config \u2014 run `fabric install` in this repo first";
72
- function requireProjectConfig(projectRoot) {
73
- const config = loadProjectConfig(projectRoot);
74
- if (config === null) {
75
- throw new Error(NO_PROJECT_CONFIG);
76
- }
77
- return config;
78
- }
79
- function storeBind(projectRoot, entry) {
80
- const config = requireProjectConfig(projectRoot);
81
- const next = {
82
- ...config,
83
- required_stores: bindRequiredStore(config.required_stores ?? [], entry)
84
- };
85
- saveProjectConfig(next, projectRoot);
86
- return next;
87
- }
88
- function storeSwitchWrite(projectRoot, alias) {
89
- const config = requireProjectConfig(projectRoot);
90
- const next = { ...config, active_write_store: alias };
91
- saveProjectConfig(next, projectRoot);
92
- return next;
93
- }
94
- function missingRequiredStores(projectRoot, globalRoot = resolveGlobalRoot()) {
95
- const project = loadProjectConfig(projectRoot);
96
- if (project === null || project.required_stores === void 0) {
97
- return [];
98
- }
99
- const global = loadGlobalConfig(globalRoot);
100
- const mounted = new Set(
101
- (global?.stores ?? []).flatMap((s) => [s.alias, s.store_uuid])
102
- );
103
- return project.required_stores.filter((r) => !mounted.has(r.id));
104
- }
105
-
106
- export {
107
- storeList,
108
- storeAdd,
109
- storeCreate,
110
- assertStoreMountable,
111
- storeRemove,
112
- storeExplain,
113
- storeBind,
114
- storeSwitchWrite,
115
- missingRequiredStores
116
- };
@@ -1,52 +0,0 @@
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
- };
@@ -1,27 +0,0 @@
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
- };
@@ -1,33 +0,0 @@
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
- };
@@ -1,40 +0,0 @@
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
- };