@fenglimg/fabric-shared 2.3.0-rc.12 → 2.3.0-rc.16
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-TEITGZY3.js → chunk-5M3HB554.js} +25 -1
- package/dist/{chunk-ASS2KBB7.js → chunk-OX6DWUK4.js} +31 -2
- package/dist/{chunk-KFFBQRL5.js → chunk-V7IUN5U2.js} +9 -7
- package/dist/{chunk-YLIWE46B.js → chunk-WXVFJBL5.js} +155 -33
- package/dist/i18n/index.js +3 -2
- package/dist/{index-B2e0wKJi.d.ts → index-KvxqMZV1.d.ts} +6 -0
- package/dist/index.d.ts +460 -21
- package/dist/index.js +266 -43
- package/dist/schemas/api-contracts.d.ts +144 -0
- package/dist/schemas/api-contracts.js +1 -1
- package/dist/templates/bootstrap-canonical.d.ts +2 -2
- package/dist/templates/bootstrap-canonical.js +3 -2
- package/dist/theme.d.ts +6 -3
- package/dist/theme.js +27 -5
- package/dist/types/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -709,7 +709,18 @@ var _fabReviewModifyChangesSchema = z3.object({
|
|
|
709
709
|
// impact are flow-arrays.
|
|
710
710
|
must_read_if: z3.string().optional(),
|
|
711
711
|
intent_clues: z3.array(z3.string()).optional(),
|
|
712
|
-
impact: z3.array(z3.string()).optional()
|
|
712
|
+
impact: z3.array(z3.string()).optional(),
|
|
713
|
+
// ISS-20260711-180: propose writes these; without them here zod .strip()
|
|
714
|
+
// silently drops modify patches (KT-PIT-0005 recurrence).
|
|
715
|
+
tech_stack: z3.array(z3.string()).optional(),
|
|
716
|
+
evidence_paths: z3.array(z3.string()).optional(),
|
|
717
|
+
onboard_slot: z3.enum([
|
|
718
|
+
"tech-stack-decision",
|
|
719
|
+
"architecture-pattern",
|
|
720
|
+
"code-style-tone",
|
|
721
|
+
"build-system-idiom",
|
|
722
|
+
"domain-vocabulary"
|
|
723
|
+
]).optional()
|
|
713
724
|
});
|
|
714
725
|
var FabReviewInputSchema = z3.discriminatedUnion("action", [
|
|
715
726
|
z3.object({
|
|
@@ -863,6 +874,8 @@ var _fabReviewListItemSchema = z3.object({
|
|
|
863
874
|
tags: z3.array(z3.string()).optional(),
|
|
864
875
|
title: z3.string().optional(),
|
|
865
876
|
summary: z3.string().optional(),
|
|
877
|
+
// ISS-20260712-011: triage UI needs proposed_reason without a second Read.
|
|
878
|
+
proposed_reason: z3.string().optional(),
|
|
866
879
|
// Store-only cutover: origin reflects the resolved store audience where the
|
|
867
880
|
// pending file lives; layer reflects the declared classification that will
|
|
868
881
|
// drive approval semantics.
|
|
@@ -902,10 +915,16 @@ var _fabReviewSearchItemSchema = z3.object({
|
|
|
902
915
|
// hits in the same array.
|
|
903
916
|
stable_id: z3.string().optional()
|
|
904
917
|
});
|
|
918
|
+
var _fabReviewFailedItemSchema = z3.object({
|
|
919
|
+
pending_path: z3.string(),
|
|
920
|
+
reason: z3.string()
|
|
921
|
+
});
|
|
905
922
|
var FabReviewOutputSchema = z3.discriminatedUnion("action", [
|
|
906
923
|
z3.object({
|
|
907
924
|
action: z3.literal("approve"),
|
|
908
925
|
approved: z3.array(z3.object({ pending_path: z3.string(), stable_id: z3.string() })),
|
|
926
|
+
// ISS-20260712-012: partial-failure surface so empty approved[] is not false-success.
|
|
927
|
+
failed: z3.array(_fabReviewFailedItemSchema).optional(),
|
|
909
928
|
warnings: z3.array(structuredWarningSchema).optional()
|
|
910
929
|
}),
|
|
911
930
|
z3.object({
|
|
@@ -953,6 +972,8 @@ var FabReviewOutputSchema = z3.discriminatedUnion("action", [
|
|
|
953
972
|
superseded_by: z3.string().optional()
|
|
954
973
|
})
|
|
955
974
|
),
|
|
975
|
+
// ISS-20260712-012: partial-failure surface for skipped/unresolvable paths.
|
|
976
|
+
failed: z3.array(_fabReviewFailedItemSchema).optional(),
|
|
956
977
|
warnings: z3.array(structuredWarningSchema).optional()
|
|
957
978
|
})
|
|
958
979
|
]);
|
|
@@ -984,6 +1005,9 @@ var FabReviewOutputShape = {
|
|
|
984
1005
|
approved: z3.array(z3.object({ pending_path: z3.string(), stable_id: z3.string() })).optional().describe(
|
|
985
1006
|
"Allocated stable ids paired with their original pending paths. Present when action=approve."
|
|
986
1007
|
),
|
|
1008
|
+
failed: z3.array(z3.object({ pending_path: z3.string(), reason: z3.string() })).optional().describe(
|
|
1009
|
+
"Paths that did not apply (approve/retire). Present when any path was skipped or failed."
|
|
1010
|
+
),
|
|
987
1011
|
rejected: z3.array(z3.string()).optional().describe(
|
|
988
1012
|
"Pending paths that were rejected (files retained on disk; doctor owns vacuum). Present when action=reject."
|
|
989
1013
|
),
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
atomicWriteJson,
|
|
3
|
+
withFileLock
|
|
4
|
+
} from "./chunk-C7WZPYZE.js";
|
|
5
|
+
|
|
1
6
|
// src/i18n/normalize-locale.ts
|
|
2
7
|
function normalizeLocale(raw) {
|
|
3
8
|
if (typeof raw !== "string") {
|
|
@@ -189,7 +194,8 @@ var globalConfigSchema = z.object({
|
|
|
189
194
|
}).passthrough();
|
|
190
195
|
|
|
191
196
|
// src/store/global-config-io.ts
|
|
192
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
197
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
198
|
+
import { mkdir } from "fs/promises";
|
|
193
199
|
import { homedir } from "os";
|
|
194
200
|
import { join } from "path";
|
|
195
201
|
function isTestRuntime() {
|
|
@@ -210,6 +216,9 @@ function resolveGlobalRoot() {
|
|
|
210
216
|
function globalConfigPath(globalRoot = resolveGlobalRoot()) {
|
|
211
217
|
return join(globalRoot, "fabric-global.json");
|
|
212
218
|
}
|
|
219
|
+
function globalConfigLockPath(globalRoot) {
|
|
220
|
+
return `${globalConfigPath(globalRoot)}.lock`;
|
|
221
|
+
}
|
|
213
222
|
function loadGlobalConfig(globalRoot = resolveGlobalRoot()) {
|
|
214
223
|
const path = globalConfigPath(globalRoot);
|
|
215
224
|
if (!existsSync(path)) {
|
|
@@ -217,11 +226,30 @@ function loadGlobalConfig(globalRoot = resolveGlobalRoot()) {
|
|
|
217
226
|
}
|
|
218
227
|
return globalConfigSchema.parse(JSON.parse(readFileSync(path, "utf8")));
|
|
219
228
|
}
|
|
229
|
+
async function saveGlobalConfigAsync(config, globalRoot = resolveGlobalRoot()) {
|
|
230
|
+
const validated = globalConfigSchema.parse(config);
|
|
231
|
+
await mkdir(globalRoot, { recursive: true });
|
|
232
|
+
const path = globalConfigPath(globalRoot);
|
|
233
|
+
await withFileLock(globalConfigLockPath(globalRoot), async () => {
|
|
234
|
+
await atomicWriteJson(path, validated, { indent: 2 });
|
|
235
|
+
});
|
|
236
|
+
}
|
|
220
237
|
function saveGlobalConfig(config, globalRoot = resolveGlobalRoot()) {
|
|
221
238
|
const validated = globalConfigSchema.parse(config);
|
|
222
239
|
mkdirSync(globalRoot, { recursive: true });
|
|
223
|
-
|
|
240
|
+
const path = globalConfigPath(globalRoot);
|
|
241
|
+
const tmpPath = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
242
|
+
try {
|
|
243
|
+
writeFileSync(tmpPath, `${JSON.stringify(validated, null, 2)}
|
|
224
244
|
`, "utf8");
|
|
245
|
+
renameSync(tmpPath, path);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
try {
|
|
248
|
+
unlinkSync(tmpPath);
|
|
249
|
+
} catch {
|
|
250
|
+
}
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
225
253
|
}
|
|
226
254
|
|
|
227
255
|
// src/i18n/resolve-global-locale.ts
|
|
@@ -269,6 +297,7 @@ export {
|
|
|
269
297
|
resolveGlobalRoot,
|
|
270
298
|
globalConfigPath,
|
|
271
299
|
loadGlobalConfig,
|
|
300
|
+
saveGlobalConfigAsync,
|
|
272
301
|
saveGlobalConfig,
|
|
273
302
|
resolveGlobalLocale
|
|
274
303
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveGlobalLocale
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OX6DWUK4.js";
|
|
4
4
|
|
|
5
5
|
// src/templates/bootstrap-canonical.ts
|
|
6
6
|
var BOOTSTRAP_MARKER_BEGIN = "<!-- fabric:bootstrap:begin -->";
|
|
@@ -36,8 +36,9 @@ var BOOTSTRAP_CANONICAL_ZH = `# Fabric Bootstrap
|
|
|
36
36
|
\u5B8C\u6574 maintainer \u7248\u89C1 \`docs/USER-QUICKSTART.md\`\u3002
|
|
37
37
|
|
|
38
38
|
## \u884C\u4E3A\u89C4\u5219
|
|
39
|
-
-
|
|
40
|
-
-
|
|
39
|
+
- **Pre-action gating (\u4FEE\u6539\u4EFB\u4F55\u6587\u4EF6\u524D MUST)**: \u2460 \u5148 \`fab_recall(paths=[<\u88AB\u6539\u6587\u4EF6>], session_id=<client-session-id>)\`\uFF1B\u2461 \u6309\u9700\u539F\u751F Read \u547D\u4E2D\u7684 \`entries[].read_path\` \u6B63\u6587(PostToolUse \u8BB0\u4E3A \`knowledge_body_read\`)\uFF1B\u2462 \u8DF3\u8FC7\u4E0D\u9002\u7528\u547D\u4E2D\u65F6\u8BF4 \`dismissed: <id> (<reason>)\`\u3002\`fab_recall\` \u4E0D\u518D\u6295\u9012\u6B63\u6587;lean \u9ED8\u8BA4\u63CF\u8FF0+\u7D22\u5F15\u5DF2\u591F\u53D1\u73B0\u6761\u76EE(KT-GLD-0005)\u3002PreToolUse \u4EC5\u8F6F nudge,\u5B88 KT-DEC-0007(\u975E permanent gate / \u65E0 \`decision:block\`)\u3002
|
|
40
|
+
- **Archive-as-truth**: \u8FDB canonical **\u552F\u4E00\u8DEF\u5F84** \u662F \`fab_propose\` \u2192 pending \u2192 \`fabric-review\`/\`fab_review\` \u5BA1\u6279\uFF1B\u7981\u6B62\u628A chat/log \u81EA\u52A8 promote \u8FDB canonical\u3002
|
|
41
|
+
- **\`.fabric/agents.meta.json\` \u4E25\u7981\u624B\u52A8\u7F16\u8F91**\uFF08co-location index \u5DF2\u9000\u5F79;\u77E5\u8BC6\u5728 mounted stores\uFF09\u3002\u5F02\u5E38\u65F6\u8DD1 \`fabric doctor\` / \`fabric doctor --fix\` \u81EA\u6108\u53EF\u4FEE\u590D\u9879\u3002
|
|
41
42
|
|
|
42
43
|
## \u77E5\u8BC6\u5E93(KB)
|
|
43
44
|
- **Discovery**:SessionStart hook \u5217 broad-scoped \u6761\u76EE(\u6761\u76EE\u6309 \`semantic_scope\` \u5206\u4E09\u5C42:\`team\` \u56E2\u961F\u901A\u7528 / \`project:<id>\` \u672C\u9879\u76EE\u4E13\u5C5E(\u4EC5\u5728\u7ED1\u5B9A\u8BE5\u9879\u76EE\u7684\u4ED3\u5E93\u6D6E\u73B0)/ \`personal\` \u4E2A\u4EBA \`KP-*\`,\u4E09\u8005\u5F15\u7528\u65B9\u5F0F\u76F8\u540C);edit \u6587\u4EF6\u65F6 PreToolUse hook \u53EF\u80FD\u89E6\u53D1 narrow hint\u3002
|
|
@@ -46,7 +47,7 @@ var BOOTSTRAP_CANONICAL_ZH = `# Fabric Bootstrap
|
|
|
46
47
|
- **session_id**: \u8C03\u7528 \`fab_recall\` \u65F6, \u52A1\u5FC5\u628A\u5F53\u524D client session id \u4F5C\u4E3A \`session_id\` \u53C2\u6570\u4F20\u5165(Claude Code \u7684 session id \u5728 stdin payload \u4E2D, Codex \u7684\u5BF9\u5E94 identifier \u540C\u7406)\u3002\u8FD9\u80FD\u8BA9 \`fabric doctor --archive-history\` \u4E0E \`fabric-hint.cjs\` Stop hook \u51C6\u786E\u8BC6\u522B\u8DE8\u4F1A\u8BDD debt \u72B6\u6001\u3002
|
|
47
48
|
- **Skills (4)**:\u5199\u6D41\u7A0B \`fabric-archive\`(\u542B source mode \u51B7\u542F\u52A8\u4ECE git/docs \u56DE\u704C)/ \`fabric-review\`(\u542B retire \u8BED\u4E49\u6DD8\u6C70 + relate \u5173\u8054\u5EFA\u8FB9 \u5B50\u6D41\u7A0B);store \u8FD0\u7EF4 \`fabric-store\` / \`fabric-sync\`\u3002
|
|
48
49
|
- **Language**:\u6E32\u67D3\u6309 \`~/.fabric/fabric-global.json\` \u7684 \`language\` \u5B57\u6BB5(machine-wide tone)\u3002
|
|
49
|
-
- **Archive cadence nudge** (rc.36): \
|
|
50
|
+
- **Archive cadence nudge** (rc.36 / finish\u2192archive): \u663E\u8457 decision \u6536\u53E3\u6216\u4E00\u6279 Edit \u8FBE\u5230 config \`archive_edit_threshold\`(\u9ED8\u8BA4 20) \u540E,\u5728\u5408\u9002\u56DE\u5408\u8F7B\u91CF\u81EA\u8C03 \`fabric-archive\`(\u540C turn \u6700\u591A 1 \u6B21;\u975E task engine / \u975E Stop-hook flood)\u3002Stop hook \u4EC5 soft threshold nudge,\u5B88 KT-DEC-0007 \u2014 archive \u6CA1\u5EFA\u7ACB\u9891\u7387\u4F1A\u8BA9 KB \u6162\u901F\u6B7B\u6389\u3002
|
|
50
51
|
- **Review backlog nudge** (rc.36): \u9700\u8981\u5224\u65AD pending backlog \u65F6\u8D70 \`fab_pending action="list"\` \u6216 \`fabric-review\` \u8FD4\u56DE\u7684 \`pending_path\`;\u4E0D\u8981 glob \u9879\u76EE\u672C\u5730 \`.fabric/knowledge/pending\`\u3002\u5F53\u53EF\u89C1 pending \u7D2F\u79EF >10 \u6761\u65F6,\u5728\u5408\u9002\u56DE\u5408\u4E3B\u52A8 propose \u8C03 \`fabric-review\` skill \u6279\u91CF\u5BA1,\u907F\u514D draft \u5361\u6B7B\u3002
|
|
51
52
|
|
|
52
53
|
## Self-archive policy (v2.2 C1: \u7CBE\u7B80\u8BF4\u660E\u4E66)
|
|
@@ -95,8 +96,9 @@ As a dev you only need to: run \`fabric install\` once per repo, use \`fabric st
|
|
|
95
96
|
See \`docs/USER-QUICKSTART.md\` for the full maintainer version.
|
|
96
97
|
|
|
97
98
|
## Behavior Rules
|
|
98
|
-
- **
|
|
99
|
-
- **
|
|
99
|
+
- **Pre-action gating (MUST before Edit/Write)**: (1) call \`fab_recall(paths=[<file-being-edited>], session_id=<client-session-id>)\`; (2) optionally native-Read selected \`entries[].read_path\` bodies (PostToolUse records \`knowledge_body_read\`); (3) when skipping a hit, say \`dismissed: <id> (<reason>)\`. \`fab_recall\` no longer delivers bodies; lean default is description+index discovery (KT-GLD-0005). PreToolUse is soft nudge only per KT-DEC-0007 (never permanent gate / no \`decision:block\`).
|
|
100
|
+
- **Archive-as-truth**: the **only** path into canonical is \`fab_propose\` \u2192 pending \u2192 \`fabric-review\`/\`fab_review\` approve; never auto-promote chat/logs into canonical.
|
|
101
|
+
- **Never hand-edit \`.fabric/agents.meta.json\`** (co-location index retired; knowledge lives in mounted stores). For anomalies run \`fabric doctor\` / \`fabric doctor --fix\` on fixable state.
|
|
100
102
|
|
|
101
103
|
## Knowledge Base (KB)
|
|
102
104
|
- **Discovery**: the SessionStart hook lists broad-scoped entries (scoped by \`semantic_scope\` across three tiers: \`team\` team-wide / \`project:<id>\` this-project-only (surfaces only in repos bound to that project) / \`personal\` \`KP-*\`, all three referenced the same way); editing a file may trigger a narrow hint via the PreToolUse hook.
|
|
@@ -105,7 +107,7 @@ See \`docs/USER-QUICKSTART.md\` for the full maintainer version.
|
|
|
105
107
|
- **session_id**: when calling \`fab_recall\`, always pass the current client session id as the \`session_id\` argument (Claude Code's session id is in the stdin payload; Codex's corresponding identifier likewise). This lets \`fabric doctor --archive-history\` and the \`fabric-hint.cjs\` Stop hook track cross-session debt accurately.
|
|
106
108
|
- **Skills (4)**: write flow \`fabric-archive\` (with source-mode cold-start backfill from git/docs) / \`fabric-review\` (with retire-deprecation + relate-edge sub-flows); store ops \`fabric-store\` / \`fabric-sync\`.
|
|
107
109
|
- **Language**: rendered per the \`language\` field in \`~/.fabric/fabric-global.json\` (machine-wide tone).
|
|
108
|
-
- **Archive cadence nudge** (rc.36): after
|
|
110
|
+
- **Archive cadence nudge** (rc.36 / finish\u2192archive): after a significant decision lands or an edit batch reaches config \`archive_edit_threshold\` (default 20), lightly self-trigger \`fabric-archive\` at a suitable turn (max 1 per turn; not a task engine / not Stop-hook flood). Stop hook remains a soft threshold nudge per KT-DEC-0007 \u2014 without an archive cadence the KB slowly dies.
|
|
109
111
|
- **Review backlog nudge** (rc.36): to judge the pending backlog, go through \`fab_pending action="list"\` or the \`pending_path\` returned by \`fabric-review\`; don't glob the project-local \`.fabric/knowledge/pending\`. When the visible pending count exceeds 10, proactively propose the \`fabric-review\` skill at a suitable turn to batch-review and avoid draft deadlock.
|
|
110
112
|
|
|
111
113
|
## Self-archive policy (v2.2 C1: lean spec)
|