@fenglimg/fabric-shared 2.3.0-rc.12 → 2.3.0-rc.15

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/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  BOOTSTRAP_REGEX,
8
8
  matchBootstrapCanonicalLocale,
9
9
  resolveBootstrapCanonical
10
- } from "./chunk-KFFBQRL5.js";
10
+ } from "./chunk-DNIICOSG.js";
11
11
  import "./chunk-LXNCAKJZ.js";
12
12
  import {
13
13
  PROTECTED_TOKENS,
@@ -16,7 +16,7 @@ import {
16
16
  enMessages,
17
17
  resolveFabricLocale,
18
18
  zhCNMessages
19
- } from "./chunk-YLIWE46B.js";
19
+ } from "./chunk-47M6HKBU.js";
20
20
  import {
21
21
  GLOBAL_BINDINGS_DIR,
22
22
  GLOBAL_STATE_DIR,
@@ -40,6 +40,7 @@ import {
40
40
  resolveGlobalLocale,
41
41
  resolveGlobalRoot,
42
42
  saveGlobalConfig,
43
+ saveGlobalConfigAsync,
43
44
  storeAliasSchema,
44
45
  storeIdentitySchema,
45
46
  storeKnowledgeTypeDir,
@@ -51,7 +52,7 @@ import {
51
52
  storeRelativePath,
52
53
  storeRelativePathForMount,
53
54
  storeUuidSchema
54
- } from "./chunk-ASS2KBB7.js";
55
+ } from "./chunk-OX6DWUK4.js";
55
56
  import {
56
57
  atomicWriteJson,
57
58
  withFileLock
@@ -116,7 +117,7 @@ import {
116
117
  scopeCoordinateSchema,
117
118
  scopeRoot,
118
119
  structuredWarningSchema
119
- } from "./chunk-TEITGZY3.js";
120
+ } from "./chunk-5M3HB554.js";
120
121
 
121
122
  // src/schemas/agents-meta.ts
122
123
  import { z } from "zod";
@@ -1646,12 +1647,11 @@ async function initStore(absDir, identity, options = {}) {
1646
1647
  await mkdir(join2(absDir, STORE_LAYOUT.knowledgeDir, STORE_PENDING_DIR), { recursive: true });
1647
1648
  await mkdir(join2(absDir, STORE_LAYOUT.bindingsDir), { recursive: true });
1648
1649
  await mkdir(join2(absDir, STORE_LAYOUT.stateDir), { recursive: true });
1649
- await writeFile(identityFile, `${JSON.stringify(parsed, null, 2)}
1650
- `, "utf8");
1651
1650
  await writeFile(join2(absDir, ".gitignore"), STORE_GITIGNORE, "utf8");
1652
1651
  if (options.git !== false) {
1653
1652
  await git(absDir, ["init", "-b", "main"]);
1654
1653
  }
1654
+ await atomicWriteJson(identityFile, parsed, { indent: 2 });
1655
1655
  const readBack = await readStoreIdentityAsync(absDir);
1656
1656
  if (readBack === null) {
1657
1657
  throw new Error(`store init wrote an unrecognizable store.json at ${absDir}`);
@@ -1699,41 +1699,78 @@ async function readKnowledgeAcrossStores(stores) {
1699
1699
  function storeProjectsPath(storeDir) {
1700
1700
  return join2(storeDir, STORE_LAYOUT.projectsFile);
1701
1701
  }
1702
+ function storeProjectsLockPath(storeDir) {
1703
+ return `${storeProjectsPath(storeDir)}.lock`;
1704
+ }
1702
1705
  async function readStoreProjects(storeDir) {
1703
1706
  const path = storeProjectsPath(storeDir);
1707
+ let text;
1708
+ try {
1709
+ text = await readFile2(path, "utf8");
1710
+ } catch (err) {
1711
+ if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
1712
+ return [];
1713
+ }
1714
+ throw err;
1715
+ }
1704
1716
  let raw;
1705
1717
  try {
1706
- raw = JSON.parse(await readFile2(path, "utf8"));
1718
+ raw = JSON.parse(text);
1707
1719
  } catch {
1708
- return [];
1720
+ throw new Error(
1721
+ `projects.json at ${path} is not valid JSON \u2014 refusing to treat as empty (would risk overwrite on next add)`
1722
+ );
1709
1723
  }
1710
1724
  const parsed = storeProjectsFileSchema.safeParse(raw);
1711
- return parsed.success ? parsed.data.projects : [];
1725
+ if (!parsed.success) {
1726
+ throw new Error(
1727
+ `projects.json at ${path} failed schema validation \u2014 refusing to treat as empty (would risk overwrite on next add): ${parsed.error.message}`
1728
+ );
1729
+ }
1730
+ return parsed.data.projects;
1712
1731
  }
1713
1732
  async function storeHasProject(storeDir, id) {
1714
1733
  return (await readStoreProjects(storeDir)).some((p) => p.id === id);
1715
1734
  }
1716
1735
  async function addStoreProject(storeDir, project) {
1717
1736
  const parsed = storeProjectSchema.parse(project);
1718
- const existing = await readStoreProjects(storeDir);
1719
- if (existing.some((p) => p.id === parsed.id)) {
1720
- throw new Error(`project '${parsed.id}' already exists in store at ${storeDir}`);
1721
- }
1722
- const next = [...existing, parsed];
1723
- const validated = storeProjectsFileSchema.parse({ projects: next });
1724
- await writeFile(storeProjectsPath(storeDir), `${JSON.stringify(validated, null, 2)}
1725
- `, "utf8");
1726
- return validated.projects;
1737
+ return withFileLock(storeProjectsLockPath(storeDir), async () => {
1738
+ const existing = await readStoreProjects(storeDir);
1739
+ if (existing.some((p) => p.id === parsed.id)) {
1740
+ throw new Error(`project '${parsed.id}' already exists in store at ${storeDir}`);
1741
+ }
1742
+ const next = [...existing, parsed];
1743
+ const validated = storeProjectsFileSchema.parse({ projects: next });
1744
+ await atomicWriteJson(storeProjectsPath(storeDir), validated, { indent: 2 });
1745
+ return validated.projects;
1746
+ });
1727
1747
  }
1728
1748
  async function aggregatePendingAcrossStores(stores) {
1729
- const lists = await Promise.all(stores.map(
1730
- async (store) => (await listMarkdown(join2(store.dir, STORE_LAYOUT.knowledgeDir, STORE_PENDING_DIR))).map((file) => ({
1731
- store_uuid: store.store_uuid,
1732
- alias: store.alias,
1733
- type: STORE_PENDING_DIR,
1734
- file
1735
- }))
1736
- ));
1749
+ const lists = await Promise.all(
1750
+ stores.map(async (store) => {
1751
+ const pendingRoot = join2(store.dir, STORE_LAYOUT.knowledgeDir, STORE_PENDING_DIR);
1752
+ const refs = [];
1753
+ for (const type of STORE_KNOWLEDGE_TYPE_DIRS) {
1754
+ for (const file of await listMarkdown(join2(pendingRoot, type))) {
1755
+ refs.push({
1756
+ store_uuid: store.store_uuid,
1757
+ alias: store.alias,
1758
+ type: STORE_PENDING_DIR,
1759
+ file
1760
+ });
1761
+ }
1762
+ }
1763
+ for (const file of await listMarkdown(pendingRoot)) {
1764
+ refs.push({
1765
+ store_uuid: store.store_uuid,
1766
+ alias: store.alias,
1767
+ type: STORE_PENDING_DIR,
1768
+ file
1769
+ });
1770
+ }
1771
+ return refs;
1772
+ })
1773
+ );
1737
1774
  return lists.flat();
1738
1775
  }
1739
1776
 
@@ -2101,7 +2138,8 @@ var MCP_STORE_AWARE_TOOLS = [
2101
2138
  "fab_get_knowledge_sections",
2102
2139
  "fab_archive_scan",
2103
2140
  "fab_propose",
2104
- "fab_review"
2141
+ "fab_review",
2142
+ "fab_pending"
2105
2143
  ];
2106
2144
  var storeAwareEntrySchema = z11.object({
2107
2145
  stable_id: z11.string(),
@@ -2130,7 +2168,10 @@ var MCP_STORE_AWARE_CONTRACTS = {
2130
2168
  surfacesEntries: false,
2131
2169
  echoesWrittenStore: true
2132
2170
  },
2133
- fab_review: { tool: "fab_review", surfacesEntries: true, echoesWrittenStore: true }
2171
+ fab_review: { tool: "fab_review", surfacesEntries: true, echoesWrittenStore: true },
2172
+ // W3-K K2: read-only list/search lifted from fab_review — surfaces pending/
2173
+ // canonical entries with store provenance, does not write.
2174
+ fab_pending: { tool: "fab_pending", surfacesEntries: true, echoesWrittenStore: false }
2134
2175
  };
2135
2176
 
2136
2177
  // src/schemas/bindings-snapshot.ts
@@ -3180,6 +3221,54 @@ var fileMutatedEventSchema = z16.object({
3180
3221
  source_event_id: z16.string().optional(),
3181
3222
  store_id: z16.string().optional()
3182
3223
  });
3224
+ var storeMountedEventSchema = z16.object({
3225
+ ...eventLedgerEnvelopeSchema,
3226
+ event_type: z16.literal("store_mounted"),
3227
+ alias: z16.string(),
3228
+ store_uuid: z16.string(),
3229
+ personal: z16.boolean().optional(),
3230
+ source: z16.string().optional()
3231
+ });
3232
+ var storeDetachedEventSchema = z16.object({
3233
+ ...eventLedgerEnvelopeSchema,
3234
+ event_type: z16.literal("store_detached"),
3235
+ alias: z16.string(),
3236
+ store_uuid: z16.string().optional(),
3237
+ source: z16.string().optional()
3238
+ });
3239
+ var storeBoundEventSchema = z16.object({
3240
+ ...eventLedgerEnvelopeSchema,
3241
+ event_type: z16.literal("store_bound"),
3242
+ alias: z16.string(),
3243
+ store_uuid: z16.string().optional(),
3244
+ project: z16.string().optional(),
3245
+ source: z16.string().optional()
3246
+ });
3247
+ var writeStoreSwitchedEventSchema = z16.object({
3248
+ ...eventLedgerEnvelopeSchema,
3249
+ event_type: z16.literal("write_store_switched"),
3250
+ alias: z16.string(),
3251
+ previous_alias: z16.string().optional(),
3252
+ // Named switch_kind (not `kind`) so it never shadows the envelope
3253
+ // kind: "fabric-event" discriminator required by every ledger row.
3254
+ switch_kind: z16.enum(["project_write", "personal"]).optional(),
3255
+ source: z16.string().optional()
3256
+ });
3257
+ var writeRouteChangedEventSchema = z16.object({
3258
+ ...eventLedgerEnvelopeSchema,
3259
+ event_type: z16.literal("write_route_changed"),
3260
+ scope: z16.string(),
3261
+ alias: z16.string(),
3262
+ previous_alias: z16.string().optional(),
3263
+ source: z16.string().optional()
3264
+ });
3265
+ var narrowHintFailedEventSchema = z16.object({
3266
+ ...eventLedgerEnvelopeSchema,
3267
+ event_type: z16.literal("narrow_hint_failed"),
3268
+ hook_name: z16.string(),
3269
+ reason: z16.string(),
3270
+ bin: z16.string().optional()
3271
+ });
3183
3272
  var knowledgeBodyReadEventSchema = z16.object({
3184
3273
  ...eventLedgerEnvelopeSchema,
3185
3274
  event_type: z16.literal("knowledge_body_read"),
@@ -3292,6 +3381,14 @@ var eventLedgerEventSchema = z16.discriminatedUnion("event_type", [
3292
3381
  // lifecycle-refactor Wave 2 — dormant-hook activation markers.
3293
3382
  sessionEndedEventSchema,
3294
3383
  fileMutatedEventSchema,
3384
+ // ISS-20260711-127: store topology admin events
3385
+ storeMountedEventSchema,
3386
+ storeDetachedEventSchema,
3387
+ storeBoundEventSchema,
3388
+ writeStoreSwitchedEventSchema,
3389
+ writeRouteChangedEventSchema,
3390
+ // ISS-20260711-215: narrow_hint_failed — CLI failure observability for narrow hook
3391
+ narrowHintFailedEventSchema,
3295
3392
  // KT-DEC-0030: knowledge_body_read — PostToolUse native-Read consumption marker
3296
3393
  // (replaces knowledge_consumed as the funnel's "body opened" signal).
3297
3394
  knowledgeBodyReadEventSchema,
@@ -3621,6 +3718,7 @@ export {
3621
3718
  metaUpdatedEventSchema,
3622
3719
  migrateRequiredStores,
3623
3720
  mountedStoreSchema,
3721
+ narrowHintFailedEventSchema,
3624
3722
  normalizeCiteTag,
3625
3723
  normalizeLocale,
3626
3724
  nudgeModeSchema,
@@ -3679,6 +3777,7 @@ export {
3679
3777
  ruleDescriptionIndexItemSchema,
3680
3778
  ruleDescriptionSchema,
3681
3779
  saveGlobalConfig,
3780
+ saveGlobalConfigAsync,
3682
3781
  saveProjectConfig,
3683
3782
  scanForSecrets,
3684
3783
  scopeCoordinateSchema,
@@ -3694,14 +3793,17 @@ export {
3694
3793
  skillTriggerCandidateEventSchema,
3695
3794
  storeAliasSchema,
3696
3795
  storeAwareEntrySchema,
3796
+ storeBoundEventSchema,
3697
3797
  storeCountersPath,
3698
3798
  storeCountersSchema,
3799
+ storeDetachedEventSchema,
3699
3800
  storeHasProject,
3700
3801
  storeIdentitySchema,
3701
3802
  storeKnowledgeTypeDir,
3702
3803
  storeMountGroup,
3703
3804
  storeMountNameSchema,
3704
3805
  storeMountSubPath,
3806
+ storeMountedEventSchema,
3705
3807
  storeProjectSchema,
3706
3808
  storeProjectsFileSchema,
3707
3809
  storeReadSetSchema,
@@ -3716,7 +3818,9 @@ export {
3716
3818
  uidSchema,
3717
3819
  withDerivedAgentsMetaNodeDefaults,
3718
3820
  writeBindingsSnapshot,
3821
+ writeRouteChangedEventSchema,
3719
3822
  writeRouteSchema,
3823
+ writeStoreSwitchedEventSchema,
3720
3824
  writeTargetSchema,
3721
3825
  writtenToStoreSchema,
3722
3826
  zhCNMessages