@fenglimg/fabric-shared 2.2.0-rc.3 → 2.2.0-rc.4

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.
@@ -0,0 +1,128 @@
1
+ // src/node/atomic-write.ts
2
+ import { appendFile, mkdir, open, readFile, rename, stat, unlink, writeFile } from "fs/promises";
3
+ import { dirname } from "path";
4
+ import { randomUUID } from "crypto";
5
+ function makeTmpSuffix() {
6
+ const rand = Math.floor(Math.random() * 65535).toString(16).padStart(4, "0");
7
+ return `.${process.pid}.${Date.now()}.${rand}.tmp`;
8
+ }
9
+ async function atomicWriteText(path, content, opts) {
10
+ const tmpPath = path + makeTmpSuffix();
11
+ try {
12
+ if (opts?.fsync) {
13
+ const fd = await open(tmpPath, "w");
14
+ try {
15
+ await fd.writeFile(content, "utf8");
16
+ await fd.datasync();
17
+ } finally {
18
+ await fd.close();
19
+ }
20
+ } else {
21
+ await writeFile(tmpPath, content, "utf8");
22
+ }
23
+ await rename(tmpPath, path);
24
+ } catch (err) {
25
+ try {
26
+ await unlink(tmpPath);
27
+ } catch {
28
+ }
29
+ throw err;
30
+ }
31
+ }
32
+ async function atomicWriteJson(path, value, opts) {
33
+ const indent = opts?.indent ?? 2;
34
+ const content = JSON.stringify(value, null, indent) + "\n";
35
+ await atomicWriteText(path, content, { fsync: opts?.fsync });
36
+ }
37
+ function isErrnoException(err) {
38
+ return err instanceof Error && typeof err.code === "string";
39
+ }
40
+ function sleep(ms) {
41
+ return new Promise((resolve) => setTimeout(resolve, ms));
42
+ }
43
+ async function withFileLock(lockPath, fn, opts = {}) {
44
+ const staleMs = opts.staleMs ?? 1e4;
45
+ const retryDelayMs = opts.retryDelayMs ?? 20;
46
+ const maxWaitMs = opts.maxWaitMs ?? 1e4;
47
+ await mkdir(dirname(lockPath), { recursive: true });
48
+ const token = `${process.pid}.${randomUUID()}`;
49
+ const start = Date.now();
50
+ for (; ; ) {
51
+ let handle;
52
+ try {
53
+ handle = await open(lockPath, "wx");
54
+ } catch (err) {
55
+ if (!isErrnoException(err) || err.code !== "EEXIST") throw err;
56
+ try {
57
+ const st = await stat(lockPath);
58
+ if (Date.now() - st.mtimeMs > staleMs) {
59
+ const staleToken = await readFile(lockPath, "utf8").catch(() => null);
60
+ if (staleToken !== null) {
61
+ await unlinkIfToken(lockPath, staleToken);
62
+ }
63
+ continue;
64
+ }
65
+ } catch {
66
+ continue;
67
+ }
68
+ if (Date.now() - start > maxWaitMs) {
69
+ throw new Error(`withFileLock: timed out acquiring ${lockPath} after ${maxWaitMs}ms`);
70
+ }
71
+ await sleep(retryDelayMs);
72
+ continue;
73
+ }
74
+ try {
75
+ await handle.writeFile(token, "utf8");
76
+ await handle.close();
77
+ return await fn();
78
+ } finally {
79
+ await unlinkIfToken(lockPath, token);
80
+ }
81
+ }
82
+ }
83
+ async function unlinkIfToken(lockPath, expected) {
84
+ try {
85
+ const current = await readFile(lockPath, "utf8");
86
+ if (current === expected) {
87
+ await unlink(lockPath).catch(() => void 0);
88
+ }
89
+ } catch {
90
+ }
91
+ }
92
+ function createLedgerWriteQueue() {
93
+ const chains = /* @__PURE__ */ new Map();
94
+ async function doAppend(path, line) {
95
+ const normalized = line.endsWith("\n") ? line : line + "\n";
96
+ await appendFile(path, normalized, "utf8");
97
+ }
98
+ function enqueue(path, work) {
99
+ const prev = chains.get(path) ?? Promise.resolve();
100
+ const result = prev.catch(() => void 0).then(() => work());
101
+ const chainSlot = result.then(
102
+ () => void 0,
103
+ () => void 0
104
+ );
105
+ chains.set(path, chainSlot);
106
+ chainSlot.finally(() => {
107
+ if (chains.get(path) === chainSlot) {
108
+ chains.delete(path);
109
+ }
110
+ });
111
+ return result;
112
+ }
113
+ return {
114
+ append(path, line) {
115
+ return enqueue(path, () => doAppend(path, line));
116
+ },
117
+ runExclusive(path, fn) {
118
+ return enqueue(path, fn);
119
+ }
120
+ };
121
+ }
122
+
123
+ export {
124
+ atomicWriteText,
125
+ atomicWriteJson,
126
+ withFileLock,
127
+ createLedgerWriteQueue
128
+ };
@@ -390,6 +390,11 @@ var enMessages = {
390
390
  "doctor.check.counter_desync.message.plural": "{count} knowledge counters desynced from observed stable_ids. {counterPath} = {current} but observed {observedId}. Run `fabric doctor --fix` to bump counters.",
391
391
  "doctor.check.counter_desync.remediation": "Run `fabric doctor --fix` to bump agents.meta.json counters to the maximum observed counter value.",
392
392
  "doctor.check.counter_desync.ok": "agents.meta.json counters envelope is consistent with observed stable_ids.",
393
+ "doctor.check.store_counter_drift.name": "Store counter drift",
394
+ "doctor.check.store_counter_drift.message.singular": "{count} store counter is below its on-disk max stable_id ({detail}). The next allocation in that store would re-mint an existing id. Run `fabric doctor --fix` to floor the store counters.json.",
395
+ "doctor.check.store_counter_drift.message.plural": "{count} store counters are below their on-disk max stable_id ({detail}). The next allocation in those stores would re-mint an existing id. Run `fabric doctor --fix` to floor the store counters.json.",
396
+ "doctor.check.store_counter_drift.remediation": "Run `fabric doctor --fix` to floor each store's counters.json at the highest stable_id observed on disk (the floor never lowers \u2014 KT-DEC-0004 monotonic invariant).",
397
+ "doctor.check.store_counter_drift.ok": "Every read-set store's counters.json is floored at its on-disk max stable_id.",
393
398
  "doctor.check.preexisting_root_files.name": "Preexisting root markdown",
394
399
  "doctor.check.preexisting_root_files.ok": "No CLAUDE.md or AGENTS.md detected at project root.",
395
400
  "doctor.check.preexisting_root_files.message": "{files} detected at project root. These root files are not auto-loaded by Fabric MCP.",
@@ -529,6 +534,11 @@ var enMessages = {
529
534
  "doctor.check.knowledge_summary_opaque.ok": "{opaque}/{total} entries have summary == stable_id; opacity ratio is within the healthy band.",
530
535
  "doctor.check.knowledge_summary_opaque.message.warn": "{opaque}/{total} entries ({pct}%) have description.summary equal to their stable_id, exceeding the {threshold}% threshold. Narrow-hint output renders as `<id> \xB7 <id>`, signaling nothing useful, and AI clients skip the fetch. First opaque: {sample}.",
531
536
  "doctor.check.knowledge_summary_opaque.remediation": "Run the fabric-review skill to rewrite opaque summaries with one short human-readable phrase. The rc.35 hint renderer fallback (TASK-06) will also synthesize a temporary summary from the entry's `## Summary` section.",
537
+ // v2.2 W4 (G-GUARD / A6): store scope lint.
538
+ "doctor.check.store_scope_lint.name": "Store scope lint",
539
+ "doctor.check.store_scope_lint.ok": "All read-set store entries carry valid scope metadata (semantic_scope + visibility_store, no personal leak, no dangling project).",
540
+ "doctor.check.store_scope_lint.message": "{total} store scope issue(s): {breakdown}. e.g. {sample}.",
541
+ "doctor.check.store_scope_lint.remediation": "Run `fabric store backfill-scope` to add missing semantic_scope/visibility_store; `fabric store re-scope` to fix a dangling project: coordinate; move any personal-scope entry out of a shared store (personal knowledge lives only in your personal store, R5#3).",
532
542
  "doctor.check.skill_md_yaml_invalid.name": "Skill markdown YAML",
533
543
  "doctor.check.skill_md_yaml_invalid.ok": "All .claude/.codex SKILL.md frontmatter values parse as strict YAML.",
534
544
  "doctor.check.skill_md_yaml_invalid.message.singular": "{count} SKILL.md frontmatter value contains an unquoted ': ' that strict YAML parsers reject (Claude Code tolerates it; Codex CLI drops the skill at load). First: {detail}.",
@@ -1413,6 +1423,11 @@ var zhCNMessages = {
1413
1423
  "doctor.check.counter_desync.message.plural": "{count} \u4E2A knowledge counters \u4E0E\u89C2\u6D4B\u5230\u7684 stable_ids \u4E0D\u540C\u6B65\u3002{counterPath} = {current}\uFF0C\u4F46\u68C0\u6D4B\u5230 {observedId}\u3002\u8FD0\u884C `fabric doctor --fix` bump counters\u3002",
1414
1424
  "doctor.check.counter_desync.remediation": "\u8FD0\u884C `fabric doctor --fix` \u5C06 agents.meta.json counters \u63D0\u5347\u5230\u89C2\u6D4B\u5230\u7684\u6700\u5927 counter \u503C\u3002",
1415
1425
  "doctor.check.counter_desync.ok": "agents.meta.json counters envelope \u4E0E\u89C2\u6D4B\u5230\u7684 stable_ids \u4E00\u81F4\u3002",
1426
+ "doctor.check.store_counter_drift.name": "Store counter drift",
1427
+ "doctor.check.store_counter_drift.message.singular": "{count} \u4E2A store counter \u4F4E\u4E8E\u78C1\u76D8\u4E0A\u7684\u6700\u5927 stable_id\uFF08{detail}\uFF09\u3002\u8BE5 store \u4E0B\u4E00\u6B21\u94F8\u53F7\u4F1A\u590D\u7528\u5DF2\u5B58\u5728\u7684 id\u3002\u8FD0\u884C `fabric doctor --fix` \u5C06 store counters.json \u63D0\u5347\u5230\u78C1\u76D8\u6700\u5927\u503C\u3002",
1428
+ "doctor.check.store_counter_drift.message.plural": "{count} \u4E2A store counter \u4F4E\u4E8E\u78C1\u76D8\u4E0A\u7684\u6700\u5927 stable_id\uFF08{detail}\uFF09\u3002\u8FD9\u4E9B store \u4E0B\u4E00\u6B21\u94F8\u53F7\u4F1A\u590D\u7528\u5DF2\u5B58\u5728\u7684 id\u3002\u8FD0\u884C `fabric doctor --fix` \u5C06 store counters.json \u63D0\u5347\u5230\u78C1\u76D8\u6700\u5927\u503C\u3002",
1429
+ "doctor.check.store_counter_drift.remediation": "\u8FD0\u884C `fabric doctor --fix` \u5C06\u6BCF\u4E2A store \u7684 counters.json \u63D0\u5347\uFF08floor\uFF09\u5230\u78C1\u76D8\u4E0A\u89C2\u6D4B\u5230\u7684\u6700\u5927 stable_id\uFF08floor \u53EA\u5347\u4E0D\u964D\u2014\u2014KT-DEC-0004 \u5355\u8C03\u4E0D\u53D8\u91CF\uFF09\u3002",
1430
+ "doctor.check.store_counter_drift.ok": "read-set \u5185\u6BCF\u4E2A store \u7684 counters.json \u90FD\u5DF2 floor \u5230\u78C1\u76D8\u6700\u5927 stable_id\u3002",
1416
1431
  "doctor.check.preexisting_root_files.name": "Preexisting root markdown",
1417
1432
  "doctor.check.preexisting_root_files.ok": "project root \u672A\u68C0\u6D4B\u5230 CLAUDE.md \u6216 AGENTS.md\u3002",
1418
1433
  "doctor.check.preexisting_root_files.message": "project root \u68C0\u6D4B\u5230 {files}\u3002\u8FD9\u4E9B root files \u4E0D\u4F1A\u88AB Fabric MCP \u81EA\u52A8\u52A0\u8F7D\u3002",
@@ -1552,6 +1567,11 @@ var zhCNMessages = {
1552
1567
  "doctor.check.knowledge_summary_opaque.ok": "{opaque}/{total} \u4E2A entry \u7684 summary == stable_id\uFF0C\u6BD4\u4F8B\u5728\u5065\u5EB7\u8303\u56F4\u5185\u3002",
1553
1568
  "doctor.check.knowledge_summary_opaque.message.warn": "{opaque}/{total} \u4E2A entry ({pct}%) \u7684 description.summary \u7B49\u4E8E stable_id\uFF0C\u8D85\u8FC7 {threshold}% \u9608\u503C\u3002narrow hint \u8F93\u51FA\u4F1A\u53D8\u6210 `<id> \xB7 <id>` \u800C\u975E\u771F\u5B9E\u6982\u8981\uFF0CAI \u770B\u4E0D\u5230\u4FE1\u606F\u4F1A\u4E3B\u52A8\u8DF3\u8FC7 fetch\u3002\u9996\u6279\u4E0D\u900F\u660E: {sample}\u3002",
1554
1569
  "doctor.check.knowledge_summary_opaque.remediation": "\u8C03 fabric-review skill \u91CD\u5199\u4E0D\u900F\u660E summary \u4E3A\u4E00\u53E5\u4EBA\u7C7B\u53EF\u8BFB\u7684\u6982\u8981\u3002rc.35 hint renderer fallback (TASK-06) \u4E5F\u4F1A\u4ECE entry \u7684 `## Summary` \u6BB5\u81EA\u52A8\u5408\u6210\u4E34\u65F6 summary\u3002",
1570
+ // v2.2 W4 (G-GUARD / A6): store scope lint。
1571
+ "doctor.check.store_scope_lint.name": "Store scope lint",
1572
+ "doctor.check.store_scope_lint.ok": "read-set \u5185\u6240\u6709 store \u6761\u76EE scope \u5143\u6570\u636E\u9F50\u5907(semantic_scope + visibility_store,\u65E0 personal \u6CC4\u6F0F,\u65E0 dangling project)\u3002",
1573
+ "doctor.check.store_scope_lint.message": "{total} \u4E2A store scope \u95EE\u9898: {breakdown}\u3002\u4F8B\u5982 {sample}\u3002",
1574
+ "doctor.check.store_scope_lint.remediation": "\u8C03 `fabric store backfill-scope` \u8865\u7F3A\u5931\u7684 semantic_scope/visibility_store;`fabric store re-scope` \u4FEE dangling \u7684 project: \u5750\u6807;\u628A personal-scope \u6761\u76EE\u79FB\u51FA shared store(personal \u77E5\u8BC6\u53EA\u5B58\u4E2A\u4EBA store,R5#3)\u3002",
1555
1575
  "doctor.check.skill_md_yaml_invalid.name": "Skill markdown YAML",
1556
1576
  "doctor.check.skill_md_yaml_invalid.ok": "\u6240\u6709 .claude/.codex SKILL.md frontmatter values \u90FD\u80FD\u6309 strict YAML \u89E3\u6790\u3002",
1557
1577
  "doctor.check.skill_md_yaml_invalid.message.singular": "{count} \u4E2A SKILL.md frontmatter value \u5305\u542B\u672A\u52A0\u5F15\u53F7\u7684 ': '\uFF0Cstrict YAML parsers \u4F1A\u62D2\u7EDD\uFF08Claude Code tolerates it\uFF1BCodex CLI drops the skill at load\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
@@ -39,6 +39,9 @@ var GenericConfigError = class extends ConfigError {
39
39
  var StoreWriteTargetUnresolvedError = class extends ConfigError {
40
40
  code = "store_write_target_unresolved";
41
41
  };
42
+ var PersonalScopeLeakError = class extends ConfigError {
43
+ code = "personal_scope_leak";
44
+ };
42
45
 
43
46
  // src/errors/rule-error.ts
44
47
  var RuleError = class extends FabricError {
@@ -82,6 +85,7 @@ export {
82
85
  ConfigPathInvalidError,
83
86
  GenericConfigError,
84
87
  StoreWriteTargetUnresolvedError,
88
+ PersonalScopeLeakError,
85
89
  RuleError,
86
90
  RuleValidationError,
87
91
  IOFabricError,
@@ -31,6 +31,9 @@ declare class GenericConfigError extends ConfigError {
31
31
  declare class StoreWriteTargetUnresolvedError extends ConfigError {
32
32
  readonly code = "store_write_target_unresolved";
33
33
  }
34
+ declare class PersonalScopeLeakError extends ConfigError {
35
+ readonly code = "personal_scope_leak";
36
+ }
34
37
 
35
38
  declare abstract class RuleError extends FabricError {
36
39
  readonly httpStatus: number;
@@ -65,4 +68,4 @@ declare class InitFrameworkUnknownError extends InitError {
65
68
  readonly code = "init_framework_unknown";
66
69
  }
67
70
 
68
- export { ConfigError, ConfigPathInvalidError, FabricError, GenericConfigError, GenericIOError, IOFabricError, InitError, InitFrameworkUnknownError, MCPError, McpToolError, PathEscapeError, RuleError, RuleValidationError, StoreWriteTargetUnresolvedError };
71
+ export { ConfigError, ConfigPathInvalidError, FabricError, GenericConfigError, GenericIOError, IOFabricError, InitError, InitFrameworkUnknownError, MCPError, McpToolError, PathEscapeError, PersonalScopeLeakError, RuleError, RuleValidationError, StoreWriteTargetUnresolvedError };
@@ -10,10 +10,11 @@ import {
10
10
  MCPError,
11
11
  McpToolError,
12
12
  PathEscapeError,
13
+ PersonalScopeLeakError,
13
14
  RuleError,
14
15
  RuleValidationError,
15
16
  StoreWriteTargetUnresolvedError
16
- } from "../chunk-VW5QGPIN.js";
17
+ } from "../chunk-VDSM73PK.js";
17
18
  export {
18
19
  ConfigError,
19
20
  ConfigPathInvalidError,
@@ -26,6 +27,7 @@ export {
26
27
  MCPError,
27
28
  McpToolError,
28
29
  PathEscapeError,
30
+ PersonalScopeLeakError,
29
31
  RuleError,
30
32
  RuleValidationError,
31
33
  StoreWriteTargetUnresolvedError
@@ -7,7 +7,7 @@ import {
7
7
  normalizeLocale,
8
8
  resolveFabricLocale,
9
9
  zhCNMessages
10
- } from "../chunk-QSD4PN4W.js";
10
+ } from "../chunk-KUYCTRFI.js";
11
11
  export {
12
12
  PROTECTED_TOKENS,
13
13
  createTranslator,
@@ -15,6 +15,7 @@ interface RuleDescription {
15
15
  knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes";
16
16
  maturity?: "draft" | "verified" | "proven";
17
17
  knowledge_layer?: "personal" | "team";
18
+ semantic_scope?: string;
18
19
  layer_reason?: string;
19
20
  created_at?: string;
20
21
  tags?: string[];
@@ -149,6 +150,7 @@ declare const fabricConfigSchema: z.ZodObject<{
149
150
  suggested_remote?: string | undefined;
150
151
  }>, "many">>;
151
152
  active_write_store: z.ZodOptional<z.ZodString>;
153
+ active_project: z.ZodOptional<z.ZodString>;
152
154
  scanIgnores: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
153
155
  audit_mode: z.ZodOptional<z.ZodEnum<["strict", "warn", "off"]>>;
154
156
  mcpPayloadLimits: z.ZodOptional<z.ZodObject<{
@@ -265,6 +267,7 @@ declare const fabricConfigSchema: z.ZodObject<{
265
267
  suggested_remote?: string | undefined;
266
268
  }[] | undefined;
267
269
  active_write_store?: string | undefined;
270
+ active_project?: string | undefined;
268
271
  scanIgnores?: string[] | undefined;
269
272
  audit_mode?: "strict" | "warn" | "off" | undefined;
270
273
  mcpPayloadLimits?: {
@@ -295,6 +298,7 @@ declare const fabricConfigSchema: z.ZodObject<{
295
298
  suggested_remote?: string | undefined;
296
299
  }[] | undefined;
297
300
  active_write_store?: string | undefined;
301
+ active_project?: string | undefined;
298
302
  scanIgnores?: string[] | undefined;
299
303
  audit_mode?: "strict" | "warn" | "off" | undefined;
300
304
  mcpPayloadLimits?: {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AgentsMetaNode, a as AgentsIdentitySource, b as AgentsLayer, c as AgentsTopologyType, H as HumanLockEntry, f as fabricConfigSchema, F as FabricConfig, d as AgentsMeta, L as LedgerEntry } from './index-Dm4IJWwB.js';
2
- export { e as AgentsActivationTier, g as AgentsMetaCountersEnvelope, h as AgentsMetaKnowledgeTypeCounters, i as AgentsMetaNodeActivation, j as AiLedgerEntry, k as AuditMode, C as ClientPaths, D as DefaultLayerFilter, l as FabricLanguage, m as HumanLedgerEntry, M as McpPayloadLimits, R as RuleDescription, n as RuleDescriptionIndexItem, o as auditModeSchema, p as clientPathsSchema, q as defaultLayerFilterSchema, r as fabricLanguageSchema, s as mcpPayloadLimitsSchema, t as planContextTopKSchema, u as selectionTokenTtlMsSchema } from './index-Dm4IJWwB.js';
1
+ import { A as AgentsMetaNode, a as AgentsIdentitySource, b as AgentsLayer, c as AgentsTopologyType, H as HumanLockEntry, f as fabricConfigSchema, F as FabricConfig, d as AgentsMeta, L as LedgerEntry } from './index-BqA89S9q.js';
2
+ export { e as AgentsActivationTier, g as AgentsMetaCountersEnvelope, h as AgentsMetaKnowledgeTypeCounters, i as AgentsMetaNodeActivation, j as AiLedgerEntry, k as AuditMode, C as ClientPaths, D as DefaultLayerFilter, l as FabricLanguage, m as HumanLedgerEntry, M as McpPayloadLimits, R as RuleDescription, n as RuleDescriptionIndexItem, o as auditModeSchema, p as clientPathsSchema, q as defaultLayerFilterSchema, r as fabricLanguageSchema, s as mcpPayloadLimitsSchema, t as planContextTopKSchema, u as selectionTokenTtlMsSchema } from './index-BqA89S9q.js';
3
3
  import { Translator } from './i18n/index.js';
4
4
  export { Locale, Messages, PROTECTED_TOKENS, ProtectedToken, TranslationKey, createTranslator, defaultMessages, detectNodeLocale, enMessages, normalizeLocale, resolveFabricLocale, zhCNMessages } from './i18n/index.js';
5
5
  import { z } from 'zod';
@@ -1413,6 +1413,49 @@ declare const storeIdentitySchema: z.ZodObject<{
1413
1413
  allowed_scopes?: string[] | undefined;
1414
1414
  }>;
1415
1415
  type StoreIdentity = z.infer<typeof storeIdentitySchema>;
1416
+ declare const STORE_PROJECT_ID_PATTERN: RegExp;
1417
+ declare const storeProjectSchema: z.ZodObject<{
1418
+ id: z.ZodString;
1419
+ name: z.ZodOptional<z.ZodString>;
1420
+ created_at: z.ZodString;
1421
+ }, "strict", z.ZodTypeAny, {
1422
+ created_at: string;
1423
+ id: string;
1424
+ name?: string | undefined;
1425
+ }, {
1426
+ created_at: string;
1427
+ id: string;
1428
+ name?: string | undefined;
1429
+ }>;
1430
+ type StoreProject = z.infer<typeof storeProjectSchema>;
1431
+ declare const storeProjectsFileSchema: z.ZodObject<{
1432
+ projects: z.ZodDefault<z.ZodArray<z.ZodObject<{
1433
+ id: z.ZodString;
1434
+ name: z.ZodOptional<z.ZodString>;
1435
+ created_at: z.ZodString;
1436
+ }, "strict", z.ZodTypeAny, {
1437
+ created_at: string;
1438
+ id: string;
1439
+ name?: string | undefined;
1440
+ }, {
1441
+ created_at: string;
1442
+ id: string;
1443
+ name?: string | undefined;
1444
+ }>, "many">>;
1445
+ }, "strict", z.ZodTypeAny, {
1446
+ projects: {
1447
+ created_at: string;
1448
+ id: string;
1449
+ name?: string | undefined;
1450
+ }[];
1451
+ }, {
1452
+ projects?: {
1453
+ created_at: string;
1454
+ id: string;
1455
+ name?: string | undefined;
1456
+ }[] | undefined;
1457
+ }>;
1458
+ type StoreProjectsFile = z.infer<typeof storeProjectsFileSchema>;
1416
1459
  declare const requiredStoreEntrySchema: z.ZodObject<{
1417
1460
  id: z.ZodString;
1418
1461
  suggested_remote: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodLiteral<"$personal">]>>;
@@ -1427,6 +1470,8 @@ type RequiredStoreEntry = z.infer<typeof requiredStoreEntrySchema>;
1427
1470
  declare const STORE_KNOWLEDGE_TYPE_DIRS: readonly ["models", "decisions", "guidelines", "pitfalls", "processes"];
1428
1471
  declare const STORE_LAYOUT: {
1429
1472
  readonly identityFile: "store.json";
1473
+ readonly projectsFile: "projects.json";
1474
+ readonly countersFile: "counters.json";
1430
1475
  readonly knowledgeDir: "knowledge";
1431
1476
  readonly bindingsDir: "bindings";
1432
1477
  readonly stateDir: "state";
@@ -3054,8 +3099,42 @@ interface MountedStoreDir {
3054
3099
  }
3055
3100
  declare function listStoreKnowledge(store: MountedStoreDir): StoreKnowledgeRef[];
3056
3101
  declare function readKnowledgeAcrossStores(stores: MountedStoreDir[]): StoreKnowledgeRef[];
3102
+ declare function readStoreProjects(storeDir: string): StoreProject[];
3103
+ declare function storeHasProject(storeDir: string, id: string): boolean;
3104
+ declare function addStoreProject(storeDir: string, project: StoreProject): StoreProject[];
3057
3105
  declare function aggregatePendingAcrossStores(stores: MountedStoreDir[]): StoreKnowledgeRef[];
3058
3106
 
3107
+ declare function storeCountersPath(storeDir: string): string;
3108
+ declare function readStoreCounters(storeDir: string): AgentsMetaCounters;
3109
+ /**
3110
+ * Allocate the next stable_id for `(layer, type)` in the given store and persist
3111
+ * the advanced counter to `<storeDir>/counters.json`.
3112
+ *
3113
+ * The read → mutate → atomic-write is guarded by a cross-process advisory lock
3114
+ * keyed on the counters path so two concurrent allocate calls (two windows
3115
+ * approving knowledge into the same store at once) can never read the same
3116
+ * counter and mint a duplicate id (the same invariant the retired
3117
+ * KnowledgeIdAllocator held over agents.meta).
3118
+ */
3119
+ declare function allocateStoreKnowledgeId(layer: Layer, type: KnowledgeType, storeDir: string): Promise<StableId>;
3120
+ /**
3121
+ * Floor a store's `counters.json` at the highest stable_id actually present on
3122
+ * disk, persisting and returning the reconciled envelope.
3123
+ *
3124
+ * This is the producer↔consumer bridge (W4 F1): a BULK import (`store migrate`)
3125
+ * writes entries whose ids were minted elsewhere (collision-remapped from
3126
+ * disk-max) WITHOUT advancing this store's counters.json. Without reconciliation
3127
+ * the next `allocateStoreKnowledgeId` would start from a stale zero and re-mint
3128
+ * an already-present id. Flooring is also the self-heal `doctor` runs to repair a
3129
+ * drifted ledger.
3130
+ *
3131
+ * Floor — never lower — preserves the monotonic invariant (KT-DEC-0004): a slot
3132
+ * already advanced past disk-max (because the highest entry was deleted) keeps
3133
+ * its higher value. Sync write (no lock) because the only callers run in
3134
+ * exclusive one-shot contexts (post-migrate CLI step, `doctor --fix`).
3135
+ */
3136
+ declare function reconcileStoreCounters(storeDir: string): AgentsMetaCounters;
3137
+
3059
3138
  declare function resolveGlobalRoot(): string;
3060
3139
  declare function globalConfigPath(globalRoot?: string): string;
3061
3140
  declare function loadGlobalConfig(globalRoot?: string): GlobalConfig | null;
@@ -4054,14 +4133,14 @@ declare const initContextDomainGroupSchema: z.ZodObject<{
4054
4133
  topology_type: z.ZodOptional<z.ZodEnum<["mirror", "cross-cutting"]>>;
4055
4134
  target_path: z.ZodOptional<z.ZodString>;
4056
4135
  }, "strip", z.ZodTypeAny, {
4057
- paths: string[];
4058
4136
  name: string;
4137
+ paths: string[];
4059
4138
  summary?: string | undefined;
4060
4139
  target_path?: string | undefined;
4061
4140
  topology_type?: "mirror" | "cross-cutting" | undefined;
4062
4141
  }, {
4063
- paths: string[];
4064
4142
  name: string;
4143
+ paths: string[];
4065
4144
  summary?: string | undefined;
4066
4145
  target_path?: string | undefined;
4067
4146
  topology_type?: "mirror" | "cross-cutting" | undefined;
@@ -4156,14 +4235,14 @@ declare const initContextSchema: z.ZodObject<{
4156
4235
  topology_type: z.ZodOptional<z.ZodEnum<["mirror", "cross-cutting"]>>;
4157
4236
  target_path: z.ZodOptional<z.ZodString>;
4158
4237
  }, "strip", z.ZodTypeAny, {
4159
- paths: string[];
4160
4238
  name: string;
4239
+ paths: string[];
4161
4240
  summary?: string | undefined;
4162
4241
  target_path?: string | undefined;
4163
4242
  topology_type?: "mirror" | "cross-cutting" | undefined;
4164
4243
  }, {
4165
- paths: string[];
4166
4244
  name: string;
4245
+ paths: string[];
4167
4246
  summary?: string | undefined;
4168
4247
  target_path?: string | undefined;
4169
4248
  topology_type?: "mirror" | "cross-cutting" | undefined;
@@ -4209,8 +4288,8 @@ declare const initContextSchema: z.ZodObject<{
4209
4288
  }[] | undefined;
4210
4289
  }[];
4211
4290
  domain_groups: {
4212
- paths: string[];
4213
4291
  name: string;
4292
+ paths: string[];
4214
4293
  summary?: string | undefined;
4215
4294
  target_path?: string | undefined;
4216
4295
  topology_type?: "mirror" | "cross-cutting" | undefined;
@@ -4244,8 +4323,8 @@ declare const initContextSchema: z.ZodObject<{
4244
4323
  }[] | undefined;
4245
4324
  }[];
4246
4325
  domain_groups: {
4247
- paths: string[];
4248
4326
  name: string;
4327
+ paths: string[];
4249
4328
  summary?: string | undefined;
4250
4329
  target_path?: string | undefined;
4251
4330
  topology_type?: "mirror" | "cross-cutting" | undefined;
@@ -11361,4 +11440,4 @@ declare function resolveRetrievalBudget(overrides?: RetrievalBudgetOverrides): R
11361
11440
  /** Exposed for tests / introspection — the raw profile table. */
11362
11441
  declare function retrievalBudgetProfile(profile: RetrievalBudgetProfile): ResolvedRetrievalBudget;
11363
11442
 
11364
- export { AGENTS_META_IDENTITY_SOURCES, AGENTS_META_LAYERS, AGENTS_META_TOPOLOGY_TYPES, AgentsIdentitySource, AgentsLayer, AgentsMeta, type AgentsMetaCounters, AgentsMetaCountersSchema, AgentsMetaNode, AgentsTopologyType, type AssistantTurnObservedEvent, type BootstrapMarkerMigratedEvent, type CandidateFileEntry, type CandidateFileFamily, type CiteCommitment, type CiteCommitmentOperator, type CiteCommitmentOperatorKind, type CiteContractPolicyActivatedEvent, type CitePolicyActivatedEvent, type CiteTag, type ClaudeHookPathMigratedEvent, type ClaudeSkillPathMigratedEvent, type ClientCapabilitySnapshotEvent, type CodexSkillPathMigratedEvent, type CrossStoreLintInput, type CrossStoreRefViolation, DEFAULT_RETRIEVAL_BUDGET_PROFILE, type DebugBundle, type DebugBundleInput, type DoctorRunEvent, type DriftDetectedEvent, type EditIntentCheckedEvent, type EntryLayer, type EntryScopeMetadata, type EventLedgerEvent, type EventLedgerEventInput, type EventLedgerEventType, type EventLedgerTruncatedEvent, type EventsRotatedEvent, FabricConfig, type FabricConfigSchemaShape, type FabricEvent, type FailureStage, type FailureTrace, type FileMutatedEvent, type FindStoreExecutableViolationsOptions, type ForensicAssertion, type ForensicAssertionConfidence, type ForensicAssertionCoverage, type ForensicAssertionType, type ForensicCodeSample, type ForensicEntryPoint, type ForensicEvidenceAnchor, type ForensicFramework, type ForensicReadme, type ForensicReport, type ForensicSamplingBudget, type ForensicTopology, GLOBAL_BINDINGS_DIR, GLOBAL_REF_PATTERN, GLOBAL_STATE_DIR, type GlobalConfig, type GlobalRef, type GraphEdgeCandidateRequestedEvent, type HookSignalEmittedEvent, type HookSurfaceEmittedEvent, HumanLockEntry, type HumanLockFile, type InitContext, type InitContextDomainGroup, type InitContextFramework, type InitContextInterviewTrailEntry, type InitContextInvariant, type InitContextInvariantConfidenceSnapshot, type InitContextSourceEvidence, type InitScanCompletedEvent, type InitStoreOptions, type InstallDiffAppliedEvent, KNOWLEDGE_TEST_INDEX_SCHEMA_VERSION, KNOWN_SCOPE_PREFIXES, type KnowledgeArchiveAttemptedEvent, type KnowledgeArchivedEvent, type KnowledgeConsumedEvent, type KnowledgeContextPlannedEvent, type KnowledgeDeferredEvent, type KnowledgeDemotedEvent, type KnowledgeDriftDetectedEvent, type KnowledgeEnrichedEvent, type KnowledgeIdRedirectEvent, type KnowledgeLayerChangedEvent, type KnowledgeMetaAutoHealedEvent, type KnowledgePathDangledEvent, type KnowledgePromoteFailedEvent, type KnowledgePromoteStartedEvent, type KnowledgePromotedEvent, type KnowledgeProposedEvent, type KnowledgeProvenance, type KnowledgeRejectedEvent, type KnowledgeScopeDegradedEvent, type KnowledgeSectionsFetchedEvent, type KnowledgeSelectionEvent, type KnowledgeSlugRenamedEvent, type KnowledgeTestIndex, type KnowledgeTestLink, type KnowledgeTestOrphanAnnotation, KnowledgeType, type KnowledgeUnarchivedEvent, Layer, type LedgerAppendedEvent, LedgerEntry, type LlmJudgeRunEvent, type LocalKnowledgeId, type LockApprovedEvent, type LockDriftEvent, MCP_STORE_AWARE_CONTRACTS, MCP_STORE_AWARE_TOOLS, type McpConfigMigratedEvent, type McpEventLedgerEvent, type McpStdioTraceEvent, type McpStoreAwareContract, type McpStoreAwareTool, type MetaReconciledEvent, type MetaReconciledOnStartupEvent, type MetaUpdatedEvent, type MountedStore, type MountedStoreDir, ONBOARD_SLOT_NAMES, ONBOARD_SLOT_TOTAL, type OnboardSlot, PARITY_CLIENTS, PARITY_SURFACES, PERSONAL_SCOPE, PERSONAL_STORE_SENTINEL, PROJECT_ROOT_SIGNALS, type PanelFieldGroup, type PanelFieldMeta, type ParityCapability, type ParityClient, type ParityClientExpectation, type ParityMatrix, type ParitySurface, type ParseCiteLineResult, type ParsedGlobalRef, type PayloadGuardObservedEvent, type PendingAutoArchivedEvent, type PrecompactObservedEvent, type ProjectRootGoldenCase, type ProjectRootResolution, type ProjectRootResolver, type ProjectRootSignal, type ProjectRootSignals, type QualifiedCandidate, type QualifiedIdResolution, REDACTION_PLACEHOLDER_PREFIX, type ReadSetEntry, type ReadSetGoldenCase, type ReapplyCompletedEvent, type RelevanceMigrationRunEvent, type RequiredStoreEntry, type ResolutionCandidate, type ResolutionResult, type ResolutionWarning, type ResolveOptions, type ResolvedBindingsSnapshot, type ResolvedEntry, type ResolvedRetrievalBudget, ResolverNotImplementedError, type RetrievalBudgetOverrides, type RetrievalBudgetProfile, SCOPE_COORDINATE_PATTERN, STORES_ROOT_DIR, STORE_GITIGNORE, STORE_KNOWLEDGE_TYPE_DIRS, STORE_LAYOUT, STORE_PENDING_DIR, STORE_RESOLVER_WARNING_CODES, STORE_UUID_PATTERN, type ScanRecommendationInput, type ScopeCoordinate, type SecretFinding, type ServeLockClearedEvent, type SessionArchiveAttemptedEvent, type SessionEndedEvent, type SkillInvocationCompletedEvent, type SkillInvocationStartedEvent, type SkillPhaseTransitionEvent, type SkillTriggerCandidateEvent, StableId, type StoreAwareEntry, type StoreCounters, type StoreExplain, type StoreIdentity, type StoreKnowledgeRef, type StoreLayout, type StoreReadSet, type StoreResolveInput, type StoreResolver, type StoreResolverWarning, type StoreResolverWarningCode, type StoreVisibility, Translator, UID_SEGMENT_PATTERN, type Uid, type ValidateResult, type WriteBindingsSnapshotOptions, type WriteTarget, type WrittenToStore, addMountedStore, agentsIdentitySourceSchema, agentsLayerSchema, agentsMetaNodeSchema, agentsMetaSchema, agentsTopologyTypeSchema, aggregatePendingAcrossStores, aiLedgerEntrySchema, allocateKnowledgeId, assistantTurnObservedEventSchema, bindRequiredStore, bindingsSnapshotPath, bootstrapMarkerMigratedEventSchema, buildDebugBundle, buildFailureTrace, buildScanRecommendations, buildStoreResolveInput, candidateFileEntrySchema, citeContractPolicyActivatedEventSchema, citePolicyActivatedEventSchema, claudeHookPathMigratedEventSchema, claudeSkillPathMigratedEventSchema, clientCapabilitySnapshotEventSchema, codexSkillPathMigratedEventSchema, createProjectRootResolver, createStoreResolver, defaultAgentsMetaCounters, deriveAgentsMetaIdentitySource, deriveAgentsMetaLayer, deriveAgentsMetaStableId, deriveAgentsMetaTopologyType, detachMountedStore, doctorRunEventSchema, driftDetectedEventSchema, editIntentCheckedEventSchema, entryScopeMetadataSchema, eventLedgerEventSchema, eventLedgerTruncatedEventSchema, eventsRotatedEventSchema, explainStore, fabricConfigSchema, fabricEventSchema, fileMutatedEventSchema, findMountedStore, findStoreExecutableViolations, forensicAssertionCoverageSchema, forensicAssertionSchema, forensicCodeSampleSchema, forensicEntryPointSchema, forensicEvidenceAnchorSchema, forensicFrameworkSchema, forensicReadmeSchema, forensicReportSchema, forensicSamplingBudgetSchema, forensicTopologySchema, formatGlobalRef, getPanelFieldByKey, getPanelFields, globalConfigPath, globalConfigSchema, globalRefSchema, graphEdgeCandidateRequestedEventSchema, hasSecrets, hookSignalEmittedEventSchema, hookSurfaceEmittedEventSchema, humanLedgerEntrySchema, humanLockEntrySchema, humanLockFileSchema, initContextDomainGroupSchema, initContextFrameworkSchema, initContextInterviewTrailEntrySchema, initContextInvariantConfidenceSnapshotSchema, initContextInvariantSchema, initContextSchema, initContextSourceEvidenceSchema, initScanCompletedEventSchema, initStore, installDiffAppliedEventSchema, isKnowledgeStableId, isPersonalLeakIntoSharedStore, isPersonalScope, knowledgeArchiveAttemptedEventSchema, knowledgeArchivedEventSchema, knowledgeConsumedEventSchema, knowledgeContextPlannedEventSchema, knowledgeDeferredEventSchema, knowledgeDemotedEventSchema, knowledgeDriftDetectedEventSchema, knowledgeEnrichedEventSchema, knowledgeIdRedirectEventSchema, knowledgeLayerChangedEventSchema, knowledgeMetaAutoHealedEventSchema, knowledgePathDangledEventSchema, knowledgePromoteFailedEventSchema, knowledgePromoteStartedEventSchema, knowledgePromotedEventSchema, knowledgeProposedEventSchema, knowledgeProvenanceSchema, knowledgeRejectedEventSchema, knowledgeScopeDegradedEventSchema, knowledgeSectionsFetchedEventSchema, knowledgeSelectionEventSchema, knowledgeSlugRenamedEventSchema, knowledgeTestIndexSchema, knowledgeTestLinkSchema, knowledgeTestOrphanAnnotationSchema, knowledgeUnarchivedEventSchema, ledgerAppendedEventSchema, ledgerEntrySchema, lintCrossStoreReferences, listStoreKnowledge, llmJudgeRunEventSchema, loadGlobalConfig, loadProjectConfig, localKnowledgeIdSchema, lockApprovedEventSchema, lockDriftEventSchema, mcpConfigMigratedEventSchema, mcpEventLedgerEventSchema, mcpStdioTraceEventSchema, metaReconciledEventSchema, metaReconciledOnStartupEventSchema, metaUpdatedEventSchema, mountedStoreSchema, normalizeCiteTag, onboardSlotSchema, parityCapabilitySchema, parityClientExpectationSchema, parityClientSchema, parityMatrixSchema, paritySurfaceSchema, parseCiteLine, parseGlobalRef, payloadGuardObservedEventSchema, pendingAutoArchivedEventSchema, precompactObservedEventSchema, projectConfigPath, projectRootGoldenCaseSchema, projectRootGoldenFileSchema, projectRootResolutionSchema, projectRootSignalSchema, projectRootSignalsSchema, readBindingsSnapshot, readKnowledgeAcrossStores, readSetEntrySchema, readSetGoldenCaseSchema, readSetGoldenFileSchema, readStoreIdentity, reapplyCompletedEventSchema, recognizeStoreDir, redactSecrets, relevanceMigrationRunEventSchema, requiredStoreEntrySchema, resolveCandidates, resolveGlobalRoot, resolveRetrievalBudget, resolveStoreQualifiedId, resolvedBindingsSnapshotSchema, retrievalBudgetProfile, ruleDescriptionIndexItemSchema, ruleDescriptionSchema, saveGlobalConfig, saveProjectConfig, scanForSecrets, scopeCoordinateSchema, scopeRoot, scrubRemoteUrl, serveLockClearedEventSchema, sessionArchiveAttemptedEventSchema, sessionEndedEventSchema, skillInvocationCompletedEventSchema, skillInvocationStartedEventSchema, skillPhaseTransitionEventSchema, skillTriggerCandidateEventSchema, storeAwareEntrySchema, storeCountersSchema, storeIdentitySchema, storeKnowledgeTypeDir, storeReadSetSchema, storeRelativePath, storeResolveInputSchema, storeResolverWarningCodeSchema, storeResolverWarningSchema, storeUuidSchema, tokenize, uidSchema, withDerivedAgentsMetaNodeDefaults, writeBindingsSnapshot, writeTargetSchema, writtenToStoreSchema };
11443
+ export { AGENTS_META_IDENTITY_SOURCES, AGENTS_META_LAYERS, AGENTS_META_TOPOLOGY_TYPES, AgentsIdentitySource, AgentsLayer, AgentsMeta, type AgentsMetaCounters, AgentsMetaCountersSchema, AgentsMetaNode, AgentsTopologyType, type AssistantTurnObservedEvent, type BootstrapMarkerMigratedEvent, type CandidateFileEntry, type CandidateFileFamily, type CiteCommitment, type CiteCommitmentOperator, type CiteCommitmentOperatorKind, type CiteContractPolicyActivatedEvent, type CitePolicyActivatedEvent, type CiteTag, type ClaudeHookPathMigratedEvent, type ClaudeSkillPathMigratedEvent, type ClientCapabilitySnapshotEvent, type CodexSkillPathMigratedEvent, type CrossStoreLintInput, type CrossStoreRefViolation, DEFAULT_RETRIEVAL_BUDGET_PROFILE, type DebugBundle, type DebugBundleInput, type DoctorRunEvent, type DriftDetectedEvent, type EditIntentCheckedEvent, type EntryLayer, type EntryScopeMetadata, type EventLedgerEvent, type EventLedgerEventInput, type EventLedgerEventType, type EventLedgerTruncatedEvent, type EventsRotatedEvent, FabricConfig, type FabricConfigSchemaShape, type FabricEvent, type FailureStage, type FailureTrace, type FileMutatedEvent, type FindStoreExecutableViolationsOptions, type ForensicAssertion, type ForensicAssertionConfidence, type ForensicAssertionCoverage, type ForensicAssertionType, type ForensicCodeSample, type ForensicEntryPoint, type ForensicEvidenceAnchor, type ForensicFramework, type ForensicReadme, type ForensicReport, type ForensicSamplingBudget, type ForensicTopology, GLOBAL_BINDINGS_DIR, GLOBAL_REF_PATTERN, GLOBAL_STATE_DIR, type GlobalConfig, type GlobalRef, type GraphEdgeCandidateRequestedEvent, type HookSignalEmittedEvent, type HookSurfaceEmittedEvent, HumanLockEntry, type HumanLockFile, type InitContext, type InitContextDomainGroup, type InitContextFramework, type InitContextInterviewTrailEntry, type InitContextInvariant, type InitContextInvariantConfidenceSnapshot, type InitContextSourceEvidence, type InitScanCompletedEvent, type InitStoreOptions, type InstallDiffAppliedEvent, KNOWLEDGE_TEST_INDEX_SCHEMA_VERSION, KNOWN_SCOPE_PREFIXES, type KnowledgeArchiveAttemptedEvent, type KnowledgeArchivedEvent, type KnowledgeConsumedEvent, type KnowledgeContextPlannedEvent, type KnowledgeDeferredEvent, type KnowledgeDemotedEvent, type KnowledgeDriftDetectedEvent, type KnowledgeEnrichedEvent, type KnowledgeIdRedirectEvent, type KnowledgeLayerChangedEvent, type KnowledgeMetaAutoHealedEvent, type KnowledgePathDangledEvent, type KnowledgePromoteFailedEvent, type KnowledgePromoteStartedEvent, type KnowledgePromotedEvent, type KnowledgeProposedEvent, type KnowledgeProvenance, type KnowledgeRejectedEvent, type KnowledgeScopeDegradedEvent, type KnowledgeSectionsFetchedEvent, type KnowledgeSelectionEvent, type KnowledgeSlugRenamedEvent, type KnowledgeTestIndex, type KnowledgeTestLink, type KnowledgeTestOrphanAnnotation, KnowledgeType, type KnowledgeUnarchivedEvent, Layer, type LedgerAppendedEvent, LedgerEntry, type LlmJudgeRunEvent, type LocalKnowledgeId, type LockApprovedEvent, type LockDriftEvent, MCP_STORE_AWARE_CONTRACTS, MCP_STORE_AWARE_TOOLS, type McpConfigMigratedEvent, type McpEventLedgerEvent, type McpStdioTraceEvent, type McpStoreAwareContract, type McpStoreAwareTool, type MetaReconciledEvent, type MetaReconciledOnStartupEvent, type MetaUpdatedEvent, type MountedStore, type MountedStoreDir, ONBOARD_SLOT_NAMES, ONBOARD_SLOT_TOTAL, type OnboardSlot, PARITY_CLIENTS, PARITY_SURFACES, PERSONAL_SCOPE, PERSONAL_STORE_SENTINEL, PROJECT_ROOT_SIGNALS, type PanelFieldGroup, type PanelFieldMeta, type ParityCapability, type ParityClient, type ParityClientExpectation, type ParityMatrix, type ParitySurface, type ParseCiteLineResult, type ParsedGlobalRef, type PayloadGuardObservedEvent, type PendingAutoArchivedEvent, type PrecompactObservedEvent, type ProjectRootGoldenCase, type ProjectRootResolution, type ProjectRootResolver, type ProjectRootSignal, type ProjectRootSignals, type QualifiedCandidate, type QualifiedIdResolution, REDACTION_PLACEHOLDER_PREFIX, type ReadSetEntry, type ReadSetGoldenCase, type ReapplyCompletedEvent, type RelevanceMigrationRunEvent, type RequiredStoreEntry, type ResolutionCandidate, type ResolutionResult, type ResolutionWarning, type ResolveOptions, type ResolvedBindingsSnapshot, type ResolvedEntry, type ResolvedRetrievalBudget, ResolverNotImplementedError, type RetrievalBudgetOverrides, type RetrievalBudgetProfile, SCOPE_COORDINATE_PATTERN, STORES_ROOT_DIR, STORE_GITIGNORE, STORE_KNOWLEDGE_TYPE_DIRS, STORE_LAYOUT, STORE_PENDING_DIR, STORE_PROJECT_ID_PATTERN, STORE_RESOLVER_WARNING_CODES, STORE_UUID_PATTERN, type ScanRecommendationInput, type ScopeCoordinate, type SecretFinding, type ServeLockClearedEvent, type SessionArchiveAttemptedEvent, type SessionEndedEvent, type SkillInvocationCompletedEvent, type SkillInvocationStartedEvent, type SkillPhaseTransitionEvent, type SkillTriggerCandidateEvent, StableId, type StoreAwareEntry, type StoreCounters, type StoreExplain, type StoreIdentity, type StoreKnowledgeRef, type StoreLayout, type StoreProject, type StoreProjectsFile, type StoreReadSet, type StoreResolveInput, type StoreResolver, type StoreResolverWarning, type StoreResolverWarningCode, type StoreVisibility, Translator, UID_SEGMENT_PATTERN, type Uid, type ValidateResult, type WriteBindingsSnapshotOptions, type WriteTarget, type WrittenToStore, addMountedStore, addStoreProject, agentsIdentitySourceSchema, agentsLayerSchema, agentsMetaNodeSchema, agentsMetaSchema, agentsTopologyTypeSchema, aggregatePendingAcrossStores, aiLedgerEntrySchema, allocateKnowledgeId, allocateStoreKnowledgeId, assistantTurnObservedEventSchema, bindRequiredStore, bindingsSnapshotPath, bootstrapMarkerMigratedEventSchema, buildDebugBundle, buildFailureTrace, buildScanRecommendations, buildStoreResolveInput, candidateFileEntrySchema, citeContractPolicyActivatedEventSchema, citePolicyActivatedEventSchema, claudeHookPathMigratedEventSchema, claudeSkillPathMigratedEventSchema, clientCapabilitySnapshotEventSchema, codexSkillPathMigratedEventSchema, createProjectRootResolver, createStoreResolver, defaultAgentsMetaCounters, deriveAgentsMetaIdentitySource, deriveAgentsMetaLayer, deriveAgentsMetaStableId, deriveAgentsMetaTopologyType, detachMountedStore, doctorRunEventSchema, driftDetectedEventSchema, editIntentCheckedEventSchema, entryScopeMetadataSchema, eventLedgerEventSchema, eventLedgerTruncatedEventSchema, eventsRotatedEventSchema, explainStore, fabricConfigSchema, fabricEventSchema, fileMutatedEventSchema, findMountedStore, findStoreExecutableViolations, forensicAssertionCoverageSchema, forensicAssertionSchema, forensicCodeSampleSchema, forensicEntryPointSchema, forensicEvidenceAnchorSchema, forensicFrameworkSchema, forensicReadmeSchema, forensicReportSchema, forensicSamplingBudgetSchema, forensicTopologySchema, formatGlobalRef, getPanelFieldByKey, getPanelFields, globalConfigPath, globalConfigSchema, globalRefSchema, graphEdgeCandidateRequestedEventSchema, hasSecrets, hookSignalEmittedEventSchema, hookSurfaceEmittedEventSchema, humanLedgerEntrySchema, humanLockEntrySchema, humanLockFileSchema, initContextDomainGroupSchema, initContextFrameworkSchema, initContextInterviewTrailEntrySchema, initContextInvariantConfidenceSnapshotSchema, initContextInvariantSchema, initContextSchema, initContextSourceEvidenceSchema, initScanCompletedEventSchema, initStore, installDiffAppliedEventSchema, isKnowledgeStableId, isPersonalLeakIntoSharedStore, isPersonalScope, knowledgeArchiveAttemptedEventSchema, knowledgeArchivedEventSchema, knowledgeConsumedEventSchema, knowledgeContextPlannedEventSchema, knowledgeDeferredEventSchema, knowledgeDemotedEventSchema, knowledgeDriftDetectedEventSchema, knowledgeEnrichedEventSchema, knowledgeIdRedirectEventSchema, knowledgeLayerChangedEventSchema, knowledgeMetaAutoHealedEventSchema, knowledgePathDangledEventSchema, knowledgePromoteFailedEventSchema, knowledgePromoteStartedEventSchema, knowledgePromotedEventSchema, knowledgeProposedEventSchema, knowledgeProvenanceSchema, knowledgeRejectedEventSchema, knowledgeScopeDegradedEventSchema, knowledgeSectionsFetchedEventSchema, knowledgeSelectionEventSchema, knowledgeSlugRenamedEventSchema, knowledgeTestIndexSchema, knowledgeTestLinkSchema, knowledgeTestOrphanAnnotationSchema, knowledgeUnarchivedEventSchema, ledgerAppendedEventSchema, ledgerEntrySchema, lintCrossStoreReferences, listStoreKnowledge, llmJudgeRunEventSchema, loadGlobalConfig, loadProjectConfig, localKnowledgeIdSchema, lockApprovedEventSchema, lockDriftEventSchema, mcpConfigMigratedEventSchema, mcpEventLedgerEventSchema, mcpStdioTraceEventSchema, metaReconciledEventSchema, metaReconciledOnStartupEventSchema, metaUpdatedEventSchema, mountedStoreSchema, normalizeCiteTag, onboardSlotSchema, parityCapabilitySchema, parityClientExpectationSchema, parityClientSchema, parityMatrixSchema, paritySurfaceSchema, parseCiteLine, parseGlobalRef, payloadGuardObservedEventSchema, pendingAutoArchivedEventSchema, precompactObservedEventSchema, projectConfigPath, projectRootGoldenCaseSchema, projectRootGoldenFileSchema, projectRootResolutionSchema, projectRootSignalSchema, projectRootSignalsSchema, readBindingsSnapshot, readKnowledgeAcrossStores, readSetEntrySchema, readSetGoldenCaseSchema, readSetGoldenFileSchema, readStoreCounters, readStoreIdentity, readStoreProjects, reapplyCompletedEventSchema, recognizeStoreDir, reconcileStoreCounters, redactSecrets, relevanceMigrationRunEventSchema, requiredStoreEntrySchema, resolveCandidates, resolveGlobalRoot, resolveRetrievalBudget, resolveStoreQualifiedId, resolvedBindingsSnapshotSchema, retrievalBudgetProfile, ruleDescriptionIndexItemSchema, ruleDescriptionSchema, saveGlobalConfig, saveProjectConfig, scanForSecrets, scopeCoordinateSchema, scopeRoot, scrubRemoteUrl, serveLockClearedEventSchema, sessionArchiveAttemptedEventSchema, sessionEndedEventSchema, skillInvocationCompletedEventSchema, skillInvocationStartedEventSchema, skillPhaseTransitionEventSchema, skillTriggerCandidateEventSchema, storeAwareEntrySchema, storeCountersPath, storeCountersSchema, storeHasProject, storeIdentitySchema, storeKnowledgeTypeDir, storeProjectSchema, storeProjectsFileSchema, storeReadSetSchema, storeRelativePath, storeResolveInputSchema, storeResolverWarningCodeSchema, storeResolverWarningSchema, storeUuidSchema, tokenize, uidSchema, withDerivedAgentsMetaNodeDefaults, writeBindingsSnapshot, writeTargetSchema, writtenToStoreSchema };
package/dist/index.js CHANGED
@@ -1,4 +1,12 @@
1
- import "./chunk-LXNCAKJZ.js";
1
+ import {
2
+ BOOTSTRAP_CANONICAL,
3
+ BOOTSTRAP_MARKER_BEGIN,
4
+ BOOTSTRAP_MARKER_END,
5
+ BOOTSTRAP_REGEX,
6
+ LEGACY_KB_MARKER_BEGIN,
7
+ LEGACY_KB_MARKER_END,
8
+ LEGACY_KB_REGEX
9
+ } from "./chunk-AFT7DB4P.js";
2
10
  import {
3
11
  PROTECTED_TOKENS,
4
12
  createTranslator,
@@ -8,7 +16,11 @@ import {
8
16
  normalizeLocale,
9
17
  resolveFabricLocale,
10
18
  zhCNMessages
11
- } from "./chunk-QSD4PN4W.js";
19
+ } from "./chunk-KUYCTRFI.js";
20
+ import {
21
+ atomicWriteJson,
22
+ withFileLock
23
+ } from "./chunk-4N6DMOOW.js";
12
24
  import {
13
25
  FabExtractKnowledgeInputSchema,
14
26
  FabExtractKnowledgeInputShape,
@@ -57,15 +69,7 @@ import {
57
69
  recallOutputSchema,
58
70
  structuredWarningSchema
59
71
  } from "./chunk-355LUDLW.js";
60
- import {
61
- BOOTSTRAP_CANONICAL,
62
- BOOTSTRAP_MARKER_BEGIN,
63
- BOOTSTRAP_MARKER_END,
64
- BOOTSTRAP_REGEX,
65
- LEGACY_KB_MARKER_BEGIN,
66
- LEGACY_KB_MARKER_END,
67
- LEGACY_KB_REGEX
68
- } from "./chunk-AFT7DB4P.js";
72
+ import "./chunk-LXNCAKJZ.js";
69
73
 
70
74
  // src/schemas/agents-meta.ts
71
75
  import { z } from "zod";
@@ -358,6 +362,18 @@ var storeIdentitySchema = z5.object({
358
362
  // time in P2). Open coordinate strings — see schemas/scope.ts.
359
363
  allowed_scopes: z5.array(z5.string()).optional()
360
364
  }).strict();
365
+ var STORE_PROJECT_ID_PATTERN = /^[a-z0-9_-]+$/u;
366
+ var storeProjectSchema = z5.object({
367
+ // Single scope segment forming the `project:<id>` coordinate. Immutable.
368
+ id: z5.string().regex(STORE_PROJECT_ID_PATTERN, "project id must be a single lowercase [a-z0-9_-] segment"),
369
+ // Optional human-facing label surfaced in `store project list`.
370
+ name: z5.string().optional(),
371
+ // ISO-8601. When the project was first registered in this store.
372
+ created_at: z5.string()
373
+ }).strict();
374
+ var storeProjectsFileSchema = z5.object({
375
+ projects: z5.array(storeProjectSchema).default([])
376
+ }).strict();
361
377
  var requiredStoreEntrySchema = z5.object({
362
378
  id: z5.string().min(1),
363
379
  suggested_remote: z5.union([z5.string().min(1), z5.literal(PERSONAL_STORE_SENTINEL)]).optional()
@@ -371,6 +387,16 @@ var STORE_KNOWLEDGE_TYPE_DIRS = [
371
387
  ];
372
388
  var STORE_LAYOUT = {
373
389
  identityFile: "store.json",
390
+ // Store-internal project registry (W1/A2). Committed parallel to store.json.
391
+ projectsFile: "projects.json",
392
+ // v2.2 W4 (agents.meta decolo) — per-store monotonic stable_id counters.
393
+ // COMMITTED parallel to store.json/projects.json (NOT gitignored like the
394
+ // derived agents.meta) because the counter ledger is non-derivable state that
395
+ // must travel with the store on clone: a fresh clone rebuilding from disk-max
396
+ // would re-mint a deleted entry's id and corrupt cite history (KT-DEC-0004
397
+ // monotonic invariant). Replaces the retired co-location
398
+ // <projectRoot>/.fabric/agents.meta.json#counters.
399
+ countersFile: "counters.json",
374
400
  knowledgeDir: "knowledge",
375
401
  bindingsDir: "bindings",
376
402
  stateDir: "state"
@@ -455,6 +481,15 @@ var fabricConfigSchema = z6.object({
455
481
  // activeWriteAlias. Absent → no active write store yet. Personal-scope
456
482
  // writes always target the implicit personal store regardless (R5#3).
457
483
  active_write_store: z6.string().optional(),
484
+ // v2.1 global-refactor (W1/A2 — store project registry): the project this repo
485
+ // currently participates in, as the SINGLE scope segment forming the
486
+ // `project:<id>` coordinate (schemas/scope.ts). Set by `store bind --project
487
+ // <id>` (validated against the bound store's projects.json). Drives:
488
+ // - write: project-scoped writes get `semantic_scope: project:<active_project>`.
489
+ // - recall: keep `project:<active_project>` + non-project coords, drop other
490
+ // `project:*` entries (G-FILTER).
491
+ // Absent → the repo has no project binding; recall does not project-filter.
492
+ active_project: z6.string().optional(),
458
493
  // rc.17 (R-cut): the dev/test fixture-path config field was removed
459
494
  // end-to-end. The `EXTERNAL_FIXTURE_PATH` env var is now the sole source
460
495
  // consumed by `resolveDevMode()`. No z.preprocess alias — pre-rc.17
@@ -1491,7 +1526,7 @@ function resolveCandidates(candidates, options = {}) {
1491
1526
 
1492
1527
  // src/store/core.ts
1493
1528
  import { execFileSync } from "child_process";
1494
- import { existsSync as existsSync2, mkdirSync, readdirSync as readdirSync2, writeFileSync } from "fs";
1529
+ import { existsSync as existsSync2, mkdirSync, readdirSync as readdirSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
1495
1530
  import { join as join2 } from "path";
1496
1531
  var STORE_PENDING_DIR = "pending";
1497
1532
  var STORE_GITIGNORE = [
@@ -1546,6 +1581,38 @@ function listStoreKnowledge(store) {
1546
1581
  function readKnowledgeAcrossStores(stores) {
1547
1582
  return stores.flatMap((store) => listStoreKnowledge(store));
1548
1583
  }
1584
+ function storeProjectsPath(storeDir) {
1585
+ return join2(storeDir, STORE_LAYOUT.projectsFile);
1586
+ }
1587
+ function readStoreProjects(storeDir) {
1588
+ const path = storeProjectsPath(storeDir);
1589
+ if (!existsSync2(path)) {
1590
+ return [];
1591
+ }
1592
+ let raw;
1593
+ try {
1594
+ raw = JSON.parse(readFileSync2(path, "utf8"));
1595
+ } catch {
1596
+ return [];
1597
+ }
1598
+ const parsed = storeProjectsFileSchema.safeParse(raw);
1599
+ return parsed.success ? parsed.data.projects : [];
1600
+ }
1601
+ function storeHasProject(storeDir, id) {
1602
+ return readStoreProjects(storeDir).some((p) => p.id === id);
1603
+ }
1604
+ function addStoreProject(storeDir, project) {
1605
+ const parsed = storeProjectSchema.parse(project);
1606
+ const existing = readStoreProjects(storeDir);
1607
+ if (existing.some((p) => p.id === parsed.id)) {
1608
+ throw new Error(`project '${parsed.id}' already exists in store at ${storeDir}`);
1609
+ }
1610
+ const next = [...existing, parsed];
1611
+ const validated = storeProjectsFileSchema.parse({ projects: next });
1612
+ writeFileSync(storeProjectsPath(storeDir), `${JSON.stringify(validated, null, 2)}
1613
+ `, "utf8");
1614
+ return validated.projects;
1615
+ }
1549
1616
  function aggregatePendingAcrossStores(stores) {
1550
1617
  return stores.flatMap(
1551
1618
  (store) => listMarkdown(join2(store.dir, STORE_LAYOUT.knowledgeDir, STORE_PENDING_DIR)).map((file) => ({
@@ -1557,47 +1624,122 @@ function aggregatePendingAcrossStores(stores) {
1557
1624
  );
1558
1625
  }
1559
1626
 
1627
+ // src/store/store-counters.ts
1628
+ import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync as readdirSync3, writeFileSync as writeFileSync2 } from "fs";
1629
+ import { join as join3 } from "path";
1630
+ function storeCountersPath(storeDir) {
1631
+ return join3(storeDir, STORE_LAYOUT.countersFile);
1632
+ }
1633
+ function readStoreCounters(storeDir) {
1634
+ let raw;
1635
+ try {
1636
+ raw = readFileSync3(storeCountersPath(storeDir), "utf8");
1637
+ } catch {
1638
+ return defaultAgentsMetaCounters();
1639
+ }
1640
+ let parsed;
1641
+ try {
1642
+ parsed = JSON.parse(raw);
1643
+ } catch {
1644
+ return defaultAgentsMetaCounters();
1645
+ }
1646
+ const result = AgentsMetaCountersSchema.safeParse(parsed);
1647
+ return result.success ? result.data : defaultAgentsMetaCounters();
1648
+ }
1649
+ async function allocateStoreKnowledgeId(layer, type, storeDir) {
1650
+ const countersPath = storeCountersPath(storeDir);
1651
+ return withFileLock(`${countersPath}.lock`, async () => {
1652
+ const counters = readStoreCounters(storeDir);
1653
+ const { id, nextCounters } = allocateKnowledgeId(layer, type, counters);
1654
+ await atomicWriteJson(countersPath, nextCounters, { indent: 2 });
1655
+ return id;
1656
+ });
1657
+ }
1658
+ function readEntryId(file) {
1659
+ let content;
1660
+ try {
1661
+ content = readFileSync3(file, "utf8");
1662
+ } catch {
1663
+ return null;
1664
+ }
1665
+ const match = content.match(/^id:\s*(\S+)\s*$/mu);
1666
+ if (match) {
1667
+ return match[1] ?? null;
1668
+ }
1669
+ const stem = file.slice(file.lastIndexOf("/") + 1).replace(/\.md$/u, "");
1670
+ const idPart = stem.split("--")[0];
1671
+ return idPart.length > 0 ? idPart : null;
1672
+ }
1673
+ function reconcileStoreCounters(storeDir) {
1674
+ const current = readStoreCounters(storeDir);
1675
+ const next = {
1676
+ KP: { ...current.KP },
1677
+ KT: { ...current.KT }
1678
+ };
1679
+ for (const type of STORE_KNOWLEDGE_TYPE_DIRS) {
1680
+ const dir = join3(storeDir, STORE_LAYOUT.knowledgeDir, type);
1681
+ if (!existsSync3(dir)) {
1682
+ continue;
1683
+ }
1684
+ for (const name of readdirSync3(dir)) {
1685
+ if (!name.endsWith(".md")) {
1686
+ continue;
1687
+ }
1688
+ const parsed = parseKnowledgeId(readEntryId(join3(dir, name)) ?? "");
1689
+ if (parsed === null) {
1690
+ continue;
1691
+ }
1692
+ const layerKey = parsed.layer === "personal" ? "KP" : "KT";
1693
+ const typeCode = KNOWLEDGE_TYPE_CODES[parsed.type];
1694
+ next[layerKey][typeCode] = Math.max(next[layerKey][typeCode], parsed.counter);
1695
+ }
1696
+ }
1697
+ writeFileSync2(storeCountersPath(storeDir), `${JSON.stringify(next, null, 2)}
1698
+ `, "utf8");
1699
+ return next;
1700
+ }
1701
+
1560
1702
  // src/store/global-config-io.ts
1561
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
1703
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
1562
1704
  import { homedir } from "os";
1563
- import { join as join3 } from "path";
1705
+ import { join as join4 } from "path";
1564
1706
  function resolveGlobalRoot() {
1565
- return join3(process.env.FABRIC_HOME ?? homedir(), ".fabric");
1707
+ return join4(process.env.FABRIC_HOME ?? homedir(), ".fabric");
1566
1708
  }
1567
1709
  function globalConfigPath(globalRoot = resolveGlobalRoot()) {
1568
- return join3(globalRoot, "fabric-global.json");
1710
+ return join4(globalRoot, "fabric-global.json");
1569
1711
  }
1570
1712
  function loadGlobalConfig(globalRoot = resolveGlobalRoot()) {
1571
1713
  const path = globalConfigPath(globalRoot);
1572
- if (!existsSync3(path)) {
1714
+ if (!existsSync4(path)) {
1573
1715
  return null;
1574
1716
  }
1575
- return globalConfigSchema.parse(JSON.parse(readFileSync2(path, "utf8")));
1717
+ return globalConfigSchema.parse(JSON.parse(readFileSync4(path, "utf8")));
1576
1718
  }
1577
1719
  function saveGlobalConfig(config, globalRoot = resolveGlobalRoot()) {
1578
1720
  const validated = globalConfigSchema.parse(config);
1579
1721
  mkdirSync2(globalRoot, { recursive: true });
1580
- writeFileSync2(globalConfigPath(globalRoot), `${JSON.stringify(validated, null, 2)}
1722
+ writeFileSync3(globalConfigPath(globalRoot), `${JSON.stringify(validated, null, 2)}
1581
1723
  `, "utf8");
1582
1724
  }
1583
1725
 
1584
1726
  // src/store/project-config-io.ts
1585
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
1586
- import { join as join4 } from "path";
1727
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
1728
+ import { join as join5 } from "path";
1587
1729
  function projectConfigPath(projectRoot) {
1588
- return join4(projectRoot, ".fabric", "fabric-config.json");
1730
+ return join5(projectRoot, ".fabric", "fabric-config.json");
1589
1731
  }
1590
1732
  function loadProjectConfig(projectRoot) {
1591
1733
  const path = projectConfigPath(projectRoot);
1592
- if (!existsSync4(path)) {
1734
+ if (!existsSync5(path)) {
1593
1735
  return null;
1594
1736
  }
1595
- return fabricConfigSchema.parse(JSON.parse(readFileSync3(path, "utf8")));
1737
+ return fabricConfigSchema.parse(JSON.parse(readFileSync5(path, "utf8")));
1596
1738
  }
1597
1739
  function saveProjectConfig(config, projectRoot) {
1598
1740
  const validated = fabricConfigSchema.parse(config);
1599
- mkdirSync3(join4(projectRoot, ".fabric"), { recursive: true });
1600
- writeFileSync3(projectConfigPath(projectRoot), `${JSON.stringify(validated, null, 2)}
1741
+ mkdirSync3(join5(projectRoot, ".fabric"), { recursive: true });
1742
+ writeFileSync4(projectConfigPath(projectRoot), `${JSON.stringify(validated, null, 2)}
1601
1743
  `, "utf8");
1602
1744
  }
1603
1745
 
@@ -1847,8 +1989,8 @@ var resolvedBindingsSnapshotSchema = z14.object({
1847
1989
  }).strict();
1848
1990
 
1849
1991
  // src/store/bindings.ts
1850
- import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
1851
- import { join as join5, resolve, sep } from "path";
1992
+ import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
1993
+ import { join as join6, resolve, sep } from "path";
1852
1994
  var SAFE_PROJECT_ID = /^[A-Za-z0-9._-]+$/;
1853
1995
  function assertSafeProjectId(projectId) {
1854
1996
  if (!SAFE_PROJECT_ID.test(projectId) || projectId.includes("..")) {
@@ -1859,8 +2001,8 @@ function assertSafeProjectId(projectId) {
1859
2001
  }
1860
2002
  function bindingsSnapshotPath(globalRoot, projectId) {
1861
2003
  assertSafeProjectId(projectId);
1862
- const bindingsDir = resolve(join5(globalRoot, GLOBAL_STATE_DIR, GLOBAL_BINDINGS_DIR));
1863
- const path = resolve(join5(bindingsDir, `${projectId}_resolved.json`));
2004
+ const bindingsDir = resolve(join6(globalRoot, GLOBAL_STATE_DIR, GLOBAL_BINDINGS_DIR));
2005
+ const path = resolve(join6(bindingsDir, `${projectId}_resolved.json`));
1864
2006
  if (path !== bindingsDir && !path.startsWith(bindingsDir + sep)) {
1865
2007
  throw new Error(`bindingsSnapshotPath: resolved path escapes bindings dir for ${JSON.stringify(projectId)}`);
1866
2008
  }
@@ -1878,18 +2020,18 @@ function writeBindingsSnapshot(options) {
1878
2020
  write_target: target
1879
2021
  });
1880
2022
  const path = bindingsSnapshotPath(options.globalRoot, options.projectId);
1881
- mkdirSync4(join5(path, ".."), { recursive: true });
1882
- writeFileSync4(path, `${JSON.stringify(snapshot, null, 2)}
2023
+ mkdirSync4(join6(path, ".."), { recursive: true });
2024
+ writeFileSync5(path, `${JSON.stringify(snapshot, null, 2)}
1883
2025
  `, "utf8");
1884
2026
  return snapshot;
1885
2027
  }
1886
2028
  function readBindingsSnapshot(globalRoot, projectId) {
1887
2029
  const path = bindingsSnapshotPath(globalRoot, projectId);
1888
- if (!existsSync5(path)) {
2030
+ if (!existsSync6(path)) {
1889
2031
  return null;
1890
2032
  }
1891
2033
  try {
1892
- const parsed = resolvedBindingsSnapshotSchema.safeParse(JSON.parse(readFileSync4(path, "utf8")));
2034
+ const parsed = resolvedBindingsSnapshotSchema.safeParse(JSON.parse(readFileSync6(path, "utf8")));
1893
2035
  return parsed.success ? parsed.data : null;
1894
2036
  } catch {
1895
2037
  return null;
@@ -2967,11 +3109,13 @@ export {
2967
3109
  STORE_KNOWLEDGE_TYPE_DIRS,
2968
3110
  STORE_LAYOUT,
2969
3111
  STORE_PENDING_DIR,
3112
+ STORE_PROJECT_ID_PATTERN,
2970
3113
  STORE_RESOLVER_WARNING_CODES,
2971
3114
  STORE_UUID_PATTERN,
2972
3115
  StableIdSchema,
2973
3116
  UID_SEGMENT_PATTERN,
2974
3117
  addMountedStore,
3118
+ addStoreProject,
2975
3119
  agentsIdentitySourceSchema,
2976
3120
  agentsLayerSchema,
2977
3121
  agentsMetaNodeSchema,
@@ -2980,6 +3124,7 @@ export {
2980
3124
  aggregatePendingAcrossStores,
2981
3125
  aiLedgerEntrySchema,
2982
3126
  allocateKnowledgeId,
3127
+ allocateStoreKnowledgeId,
2983
3128
  annotateIntentRequestSchema,
2984
3129
  archiveScanAnnotations,
2985
3130
  archiveScanInputSchema,
@@ -3153,12 +3298,15 @@ export {
3153
3298
  readSetEntrySchema,
3154
3299
  readSetGoldenCaseSchema,
3155
3300
  readSetGoldenFileSchema,
3301
+ readStoreCounters,
3156
3302
  readStoreIdentity,
3303
+ readStoreProjects,
3157
3304
  reapplyCompletedEventSchema,
3158
3305
  recallAnnotations,
3159
3306
  recallInputSchema,
3160
3307
  recallOutputSchema,
3161
3308
  recognizeStoreDir,
3309
+ reconcileStoreCounters,
3162
3310
  redactSecrets,
3163
3311
  relevanceMigrationRunEventSchema,
3164
3312
  requiredStoreEntrySchema,
@@ -3186,9 +3334,13 @@ export {
3186
3334
  skillPhaseTransitionEventSchema,
3187
3335
  skillTriggerCandidateEventSchema,
3188
3336
  storeAwareEntrySchema,
3337
+ storeCountersPath,
3189
3338
  storeCountersSchema,
3339
+ storeHasProject,
3190
3340
  storeIdentitySchema,
3191
3341
  storeKnowledgeTypeDir,
3342
+ storeProjectSchema,
3343
+ storeProjectsFileSchema,
3192
3344
  storeReadSetSchema,
3193
3345
  storeRelativePath,
3194
3346
  storeResolveInputSchema,
@@ -1,124 +1,9 @@
1
- // src/node/atomic-write.ts
2
- import { appendFile, mkdir, open, readFile, rename, stat, unlink, writeFile } from "fs/promises";
3
- import { dirname } from "path";
4
- import { randomUUID } from "crypto";
5
- function makeTmpSuffix() {
6
- const rand = Math.floor(Math.random() * 65535).toString(16).padStart(4, "0");
7
- return `.${process.pid}.${Date.now()}.${rand}.tmp`;
8
- }
9
- async function atomicWriteText(path, content, opts) {
10
- const tmpPath = path + makeTmpSuffix();
11
- try {
12
- if (opts?.fsync) {
13
- const fd = await open(tmpPath, "w");
14
- try {
15
- await fd.writeFile(content, "utf8");
16
- await fd.datasync();
17
- } finally {
18
- await fd.close();
19
- }
20
- } else {
21
- await writeFile(tmpPath, content, "utf8");
22
- }
23
- await rename(tmpPath, path);
24
- } catch (err) {
25
- try {
26
- await unlink(tmpPath);
27
- } catch {
28
- }
29
- throw err;
30
- }
31
- }
32
- async function atomicWriteJson(path, value, opts) {
33
- const indent = opts?.indent ?? 2;
34
- const content = JSON.stringify(value, null, indent) + "\n";
35
- await atomicWriteText(path, content, { fsync: opts?.fsync });
36
- }
37
- function isErrnoException(err) {
38
- return err instanceof Error && typeof err.code === "string";
39
- }
40
- function sleep(ms) {
41
- return new Promise((resolve) => setTimeout(resolve, ms));
42
- }
43
- async function withFileLock(lockPath, fn, opts = {}) {
44
- const staleMs = opts.staleMs ?? 1e4;
45
- const retryDelayMs = opts.retryDelayMs ?? 20;
46
- const maxWaitMs = opts.maxWaitMs ?? 1e4;
47
- await mkdir(dirname(lockPath), { recursive: true });
48
- const token = `${process.pid}.${randomUUID()}`;
49
- const start = Date.now();
50
- for (; ; ) {
51
- let handle;
52
- try {
53
- handle = await open(lockPath, "wx");
54
- } catch (err) {
55
- if (!isErrnoException(err) || err.code !== "EEXIST") throw err;
56
- try {
57
- const st = await stat(lockPath);
58
- if (Date.now() - st.mtimeMs > staleMs) {
59
- const staleToken = await readFile(lockPath, "utf8").catch(() => null);
60
- if (staleToken !== null) {
61
- await unlinkIfToken(lockPath, staleToken);
62
- }
63
- continue;
64
- }
65
- } catch {
66
- continue;
67
- }
68
- if (Date.now() - start > maxWaitMs) {
69
- throw new Error(`withFileLock: timed out acquiring ${lockPath} after ${maxWaitMs}ms`);
70
- }
71
- await sleep(retryDelayMs);
72
- continue;
73
- }
74
- try {
75
- await handle.writeFile(token, "utf8");
76
- await handle.close();
77
- return await fn();
78
- } finally {
79
- await unlinkIfToken(lockPath, token);
80
- }
81
- }
82
- }
83
- async function unlinkIfToken(lockPath, expected) {
84
- try {
85
- const current = await readFile(lockPath, "utf8");
86
- if (current === expected) {
87
- await unlink(lockPath).catch(() => void 0);
88
- }
89
- } catch {
90
- }
91
- }
92
- function createLedgerWriteQueue() {
93
- const chains = /* @__PURE__ */ new Map();
94
- async function doAppend(path, line) {
95
- const normalized = line.endsWith("\n") ? line : line + "\n";
96
- await appendFile(path, normalized, "utf8");
97
- }
98
- function enqueue(path, work) {
99
- const prev = chains.get(path) ?? Promise.resolve();
100
- const result = prev.catch(() => void 0).then(() => work());
101
- const chainSlot = result.then(
102
- () => void 0,
103
- () => void 0
104
- );
105
- chains.set(path, chainSlot);
106
- chainSlot.finally(() => {
107
- if (chains.get(path) === chainSlot) {
108
- chains.delete(path);
109
- }
110
- });
111
- return result;
112
- }
113
- return {
114
- append(path, line) {
115
- return enqueue(path, () => doAppend(path, line));
116
- },
117
- runExclusive(path, fn) {
118
- return enqueue(path, fn);
119
- }
120
- };
121
- }
1
+ import {
2
+ atomicWriteJson,
3
+ atomicWriteText,
4
+ createLedgerWriteQueue,
5
+ withFileLock
6
+ } from "../chunk-4N6DMOOW.js";
122
7
  export {
123
8
  atomicWriteJson,
124
9
  atomicWriteText,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MCPError
3
- } from "../chunk-VW5QGPIN.js";
3
+ } from "../chunk-VDSM73PK.js";
4
4
 
5
5
  // src/node/mcp-payload-guard.ts
6
6
  var McpPayloadTooLargeError = class extends MCPError {
@@ -1,2 +1,2 @@
1
- export { e as AgentsActivationTier, a as AgentsIdentitySource, b as AgentsLayer, d as AgentsMeta, g as AgentsMetaCountersEnvelope, h as AgentsMetaKnowledgeTypeCounters, A as AgentsMetaNode, i as AgentsMetaNodeActivation, c as AgentsTopologyType, j as AiLedgerEntry, k as AuditMode, C as ClientPaths, D as DefaultLayerFilter, F as FabricConfig, l as FabricLanguage, m as HumanLedgerEntry, H as HumanLockEntry, L as LedgerEntry, M as McpPayloadLimits, R as RuleDescription, n as RuleDescriptionIndexItem } from '../index-Dm4IJWwB.js';
1
+ export { e as AgentsActivationTier, a as AgentsIdentitySource, b as AgentsLayer, d as AgentsMeta, g as AgentsMetaCountersEnvelope, h as AgentsMetaKnowledgeTypeCounters, A as AgentsMetaNode, i as AgentsMetaNodeActivation, c as AgentsTopologyType, j as AiLedgerEntry, k as AuditMode, C as ClientPaths, D as DefaultLayerFilter, F as FabricConfig, l as FabricLanguage, m as HumanLedgerEntry, H as HumanLockEntry, L as LedgerEntry, M as McpPayloadLimits, R as RuleDescription, n as RuleDescriptionIndexItem } from '../index-BqA89S9q.js';
2
2
  import 'zod';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fenglimg/fabric-shared",
3
- "version": "2.2.0-rc.3",
3
+ "version": "2.2.0-rc.4",
4
4
  "description": "Fabric shared types — Zod schemas, i18n, atomic-write helpers, MCP payload guard, error classes. Consumed by @fenglimg/fabric-server + @fenglimg/fabric-cli.",
5
5
  "license": "MIT",
6
6
  "author": "wangzhichao <fenglimg90@gmail.com>",