@fenglimg/fabric-shared 2.3.0-rc.1 → 2.3.0-rc.3

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-SQKWD7X6.js";
10
+ } from "./chunk-KFFBQRL5.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-IFMFEX3V.js";
19
+ } from "./chunk-UPYKUYHN.js";
20
20
  import {
21
21
  GLOBAL_BINDINGS_DIR,
22
22
  GLOBAL_STATE_DIR,
@@ -51,7 +51,7 @@ import {
51
51
  storeRelativePath,
52
52
  storeRelativePathForMount,
53
53
  storeUuidSchema
54
- } from "./chunk-2GLIAZ5M.js";
54
+ } from "./chunk-ASS2KBB7.js";
55
55
  import {
56
56
  atomicWriteJson,
57
57
  withFileLock
@@ -116,7 +116,7 @@ import {
116
116
  scopeCoordinateSchema,
117
117
  scopeRoot,
118
118
  structuredWarningSchema
119
- } from "./chunk-D7HUHWBI.js";
119
+ } from "./chunk-7PS7LB5T.js";
120
120
 
121
121
  // src/schemas/agents-meta.ts
122
122
  import { z } from "zod";
@@ -355,6 +355,32 @@ var humanLockFileSchema = z4.object({
355
355
 
356
356
  // src/schemas/fabric-config.ts
357
357
  import { z as z5 } from "zod";
358
+ function isNonPersonalRequiredStore(entry) {
359
+ return entry.id !== PERSONAL_STORE_SENTINEL;
360
+ }
361
+ function refineMaxOneTeamStore(entries, ctx) {
362
+ const teamCount = entries.filter(isNonPersonalRequiredStore).length;
363
+ if (teamCount > 1) {
364
+ ctx.addIssue({
365
+ code: z5.ZodIssueCode.custom,
366
+ message: `a project may bind at most one team store (found ${teamCount}); run \`fabric install\` to migrate to the single team slot`
367
+ });
368
+ }
369
+ }
370
+ function migrateRequiredStores(config) {
371
+ const declared = config.required_stores;
372
+ if (declared === void 0) {
373
+ return config;
374
+ }
375
+ const team = declared.filter(isNonPersonalRequiredStore);
376
+ if (team.length <= 1) {
377
+ return config;
378
+ }
379
+ const personal = declared.filter((entry) => !isNonPersonalRequiredStore(entry));
380
+ const active = config.active_write_store;
381
+ const kept = (active !== void 0 ? team.find((entry) => entry.id === active) : void 0) ?? team[0];
382
+ return { ...config, required_stores: [...personal, kept] };
383
+ }
358
384
  var auditModeSchema = z5.enum(["strict", "warn", "off"]);
359
385
  var clientPathsSchema = z5.object({
360
386
  claudeCodeCLI: z5.string().optional(),
@@ -401,7 +427,9 @@ var fabricConfigSchema = z5.object({
401
427
  // `$personal` sentinel). Drives the read-set (required_stores ∪ implicit
402
428
  // personal, S11/S54) and `clone`'s missing-store onboarding (S51). Optional
403
429
  // + absent → read-set is just the implicit personal store.
404
- required_stores: z5.array(requiredStoreEntrySchema).optional(),
430
+ // W2 dual-slot (TASK-002 / R6): at most ONE non-personal (team-type) store —
431
+ // the two-slot model. >1 fails parse and is migrated by `migrateRequiredStores`.
432
+ required_stores: z5.array(requiredStoreEntrySchema).superRefine(refineMaxOneTeamStore).optional(),
405
433
  // v2.1.0-rc.1 P3 (S60 / `store switch-write`): alias of the store that
406
434
  // non-personal-scope writes land in for this project. Set by
407
435
  // `fabric store switch-write <alias>`; consumed as the resolver's
@@ -706,10 +734,13 @@ var fabricConfigSchema = z5.object({
706
734
  // sole retrieval knob (plan_context_top_k above); payload limits pass through
707
735
  // explicit `mcpPayloadLimits`, else the fixed PAYLOAD_LIMIT_DEFAULT_* guardrail.
708
736
  // v2.2 C2-vector (W2-T7): OPTIONAL dense-embedding semantic retrieval, layered
709
- // as a recall supplement after BM25. Default OFF (`--no-embed` is the baseline);
710
- // requires the operator to install the optional `fastembed` package absent →
711
- // text-only fallback. Never grows the default install footprint.
712
- embed_enabled: z5.boolean().optional().default(false),
737
+ // as a recall supplement after BM25. P1 recall-engine-refactor (TASK-004):
738
+ // Default ON `fastembed` is now an optionalDependency (auto-installed; absent →
739
+ // degrade-safe text-only fallback), so CJK semantic recall is on out of the box.
740
+ // OFF only when set explicitly to false. This default mirrors the runtime read in
741
+ // config-loader.ts (`embed_enabled !== false`); keep the two in sync so config
742
+ // introspection never reports a default that contradicts runtime behavior.
743
+ embed_enabled: z5.boolean().optional().default(true),
713
744
  // Weight applied to the 0..1 cosine similarity before it joins the additive
714
745
  // score. Capped at 49 — strictly BELOW BM25_WEIGHT (50) — so a perfect vector
715
746
  // match (weight × 1) can never outscore a single strong BM25 term match. This
@@ -734,8 +765,25 @@ var fabricConfigSchema = z5.object({
734
765
  "fast-bge-base-en-v1.5",
735
766
  "fast-bge-base-en",
736
767
  "fast-all-MiniLM-L6-v2"
737
- ]).optional().default("fast-bge-small-zh-v1.5")
738
- });
768
+ ]).optional().default("fast-bge-small-zh-v1.5"),
769
+ // P1 recall-engine-refactor (TASK-003 + follow-up): content-channel fusion
770
+ // strategy. 'additive' = the weighted-sum path (BM25_WEIGHT·bm25 + vectorWeight·
771
+ // vector + structural); the vector term is structurally minor (cosine·30 vs an
772
+ // unbounded BM25), so additive is effectively BM25-led. 'rrf' = Reciprocal Rank
773
+ // Fusion over the two CONTENT channels (bm25_rank, vector_rank, equal footing)
774
+ // + a re-scaled structural tiebreaker — lets semantic recall actually matter.
775
+ // 'auto' (DEFAULT) = adaptive: use 'rrf' WHEN the vector channel is actually
776
+ // producing scores (embeddings installed + model warm), else fall back to
777
+ // 'additive'. This is the safe default — real-store shadow showed single-channel
778
+ // rrf (no vectors) is strictly worse than additive, so auto never lets that
779
+ // happen. no-query ranking is byte-identical under every value.
780
+ fusion: z5.enum(["additive", "rrf", "auto"]).optional().default("auto")
781
+ });
782
+ var fabricConfigLoadSchema = fabricConfigSchema.merge(
783
+ z5.object({
784
+ required_stores: z5.array(requiredStoreEntrySchema).optional()
785
+ })
786
+ );
739
787
 
740
788
  // src/schemas/fabric-config-introspect.ts
741
789
  import { z as z6 } from "zod";
@@ -900,9 +948,15 @@ var PANEL_FIELDS = [
900
948
  // nudge_mode — the master switch for the human-visible nudge experience
901
949
  // (the most user-facing runtime knob, previously JSON-only). embed_enabled —
902
950
  // vector semantic recall, panel-editable now that config lives in `.fabric`
903
- // (A1); enabling also needs the host-side `fabric install --enable-embed`.
951
+ // (A1). TASK-004: default ON (fastembed is an optionalDependency, degrade-safe
952
+ // when absent) — this introspection default mirrors the runtime read in
953
+ // config-loader.ts so the panel never shows a default that contradicts behavior.
904
954
  makeEnumField("nudge_mode", "D_behavior", nudgeModeSchema.options, "normal"),
905
- makeBooleanField("embed_enabled", false)
955
+ makeBooleanField("embed_enabled", true),
956
+ // P1 recall-engine-refactor (follow-up): the content-channel fusion strategy,
957
+ // panel-editable so it sits next to embed_enabled (the two go together — rrf
958
+ // only pays off when embeddings are on). 'auto' is the safe adaptive default.
959
+ makeEnumField("fusion", "D_behavior", ["additive", "rrf", "auto"], "auto")
906
960
  ];
907
961
 
908
962
  // src/schemas/store-stable-id.ts
@@ -1069,6 +1123,13 @@ var storeResolveInputSchema = z9.object({
1069
1123
  ),
1070
1124
  // Alias selected as the active write store for non-personal scopes, if any.
1071
1125
  activeWriteAlias: z9.string().min(1).optional(),
1126
+ // Alias/UUID of the ACTIVE personal store among possibly-many mounted
1127
+ // `personal:true` stores (语义 A: singleton-at-a-time). Drives the SINGLE
1128
+ // personal choke point (findPersonal) → both read-set inclusion and the
1129
+ // personal-scope write-target. Absent or dangling ⇒ the resolver falls back
1130
+ // to the first mounted personal, so legacy single-personal configs are
1131
+ // unchanged. Sourced from `~/.fabric/fabric-global.json` → active_personal_store.
1132
+ activePersonalAlias: z9.string().min(1).optional(),
1072
1133
  // Scope-aware write routes. Exact scope wins first, then longest prefix route.
1073
1134
  writeRoutes: z9.array(
1074
1135
  z9.object({
@@ -1131,7 +1192,16 @@ function createProjectRootResolver() {
1131
1192
 
1132
1193
  // src/resolver/store-resolver.ts
1133
1194
  function findPersonal(input) {
1134
- return input.mountedStores.find((s) => s.personal);
1195
+ const actives = input.mountedStores.filter((s) => s.personal);
1196
+ if (input.activePersonalAlias !== void 0) {
1197
+ const picked = actives.find(
1198
+ (s) => s.alias === input.activePersonalAlias || s.store_uuid === input.activePersonalAlias
1199
+ );
1200
+ if (picked !== void 0) {
1201
+ return picked;
1202
+ }
1203
+ }
1204
+ return actives[0];
1135
1205
  }
1136
1206
  function personalEntry(input) {
1137
1207
  const p = findPersonal(input);
@@ -1720,7 +1790,12 @@ function loadProjectConfig(projectRoot) {
1720
1790
  if (!existsSync3(path)) {
1721
1791
  return null;
1722
1792
  }
1723
- return fabricConfigSchema.parse(JSON.parse(readFileSync3(path, "utf8")));
1793
+ const raw = JSON.parse(readFileSync3(path, "utf8"));
1794
+ const parsed = fabricConfigSchema.safeParse(raw);
1795
+ if (parsed.success) {
1796
+ return parsed.data;
1797
+ }
1798
+ return fabricConfigLoadSchema.parse(raw);
1724
1799
  }
1725
1800
  function saveProjectConfig(config, projectRoot) {
1726
1801
  const validated = fabricConfigSchema.parse(config);
@@ -1753,6 +1828,7 @@ function buildStoreResolveInput(projectRoot, globalRoot = resolveGlobalRoot()) {
1753
1828
  })
1754
1829
  ),
1755
1830
  ...project?.active_write_store === void 0 ? {} : { activeWriteAlias: project.active_write_store },
1831
+ ...global.active_personal_store === void 0 ? {} : { activePersonalAlias: global.active_personal_store },
1756
1832
  writeRoutes: project?.write_routes ?? [],
1757
1833
  ...project?.default_write_store === void 0 ? {} : { defaultWriteAlias: project.default_write_store }
1758
1834
  };
@@ -3339,6 +3415,7 @@ export {
3339
3415
  fabExtractKnowledgeAnnotations,
3340
3416
  fabPendingAnnotations,
3341
3417
  fabReviewAnnotations,
3418
+ fabricConfigLoadSchema,
3342
3419
  fabricConfigSchema,
3343
3420
  fabricEventSchema,
3344
3421
  fabricLanguageSchema,
@@ -3383,6 +3460,7 @@ export {
3383
3460
  initStore,
3384
3461
  installDiffAppliedEventSchema,
3385
3462
  isKnowledgeStableId,
3463
+ isNonPersonalRequiredStore,
3386
3464
  isPersonalLeakIntoSharedStore,
3387
3465
  isPersonalScope,
3388
3466
  knowledgeArchiveAttemptedEventSchema,
@@ -3435,6 +3513,7 @@ export {
3435
3513
  metaReconciledEventSchema,
3436
3514
  metaReconciledOnStartupEventSchema,
3437
3515
  metaUpdatedEventSchema,
3516
+ migrateRequiredStores,
3438
3517
  mountedStoreSchema,
3439
3518
  normalizeCiteTag,
3440
3519
  normalizeLocale,
@@ -666,6 +666,35 @@ declare const recallOutputSchema: z.ZodObject<{
666
666
  alias: string;
667
667
  }>>;
668
668
  body_in_context: z.ZodOptional<z.ZodBoolean>;
669
+ score: z.ZodOptional<z.ZodNumber>;
670
+ score_breakdown: z.ZodOptional<z.ZodObject<{
671
+ final: z.ZodNumber;
672
+ bm25: z.ZodOptional<z.ZodNumber>;
673
+ bm25_rank: z.ZodOptional<z.ZodNumber>;
674
+ vector: z.ZodOptional<z.ZodNumber>;
675
+ vector_rank: z.ZodOptional<z.ZodNumber>;
676
+ salience: z.ZodNumber;
677
+ recency: z.ZodNumber;
678
+ locality: z.ZodNumber;
679
+ }, "strip", z.ZodTypeAny, {
680
+ final: number;
681
+ salience: number;
682
+ recency: number;
683
+ locality: number;
684
+ bm25?: number | undefined;
685
+ bm25_rank?: number | undefined;
686
+ vector?: number | undefined;
687
+ vector_rank?: number | undefined;
688
+ }, {
689
+ final: number;
690
+ salience: number;
691
+ recency: number;
692
+ locality: number;
693
+ bm25?: number | undefined;
694
+ bm25_rank?: number | undefined;
695
+ vector?: number | undefined;
696
+ vector_rank?: number | undefined;
697
+ }>>;
669
698
  }, "strip", z.ZodTypeAny, {
670
699
  description: {
671
700
  summary: string;
@@ -692,6 +721,17 @@ declare const recallOutputSchema: z.ZodObject<{
692
721
  } | undefined;
693
722
  read_path?: string | undefined;
694
723
  body_in_context?: boolean | undefined;
724
+ score?: number | undefined;
725
+ score_breakdown?: {
726
+ final: number;
727
+ salience: number;
728
+ recency: number;
729
+ locality: number;
730
+ bm25?: number | undefined;
731
+ bm25_rank?: number | undefined;
732
+ vector?: number | undefined;
733
+ vector_rank?: number | undefined;
734
+ } | undefined;
695
735
  }, {
696
736
  description: {
697
737
  summary: string;
@@ -718,6 +758,17 @@ declare const recallOutputSchema: z.ZodObject<{
718
758
  } | undefined;
719
759
  read_path?: string | undefined;
720
760
  body_in_context?: boolean | undefined;
761
+ score?: number | undefined;
762
+ score_breakdown?: {
763
+ final: number;
764
+ salience: number;
765
+ recency: number;
766
+ locality: number;
767
+ bm25?: number | undefined;
768
+ bm25_rank?: number | undefined;
769
+ vector?: number | undefined;
770
+ vector_rank?: number | undefined;
771
+ } | undefined;
721
772
  }>, "many">;
722
773
  intent: z.ZodOptional<z.ZodString>;
723
774
  dropped: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -801,6 +852,17 @@ declare const recallOutputSchema: z.ZodObject<{
801
852
  } | undefined;
802
853
  read_path?: string | undefined;
803
854
  body_in_context?: boolean | undefined;
855
+ score?: number | undefined;
856
+ score_breakdown?: {
857
+ final: number;
858
+ salience: number;
859
+ recency: number;
860
+ locality: number;
861
+ bm25?: number | undefined;
862
+ bm25_rank?: number | undefined;
863
+ vector?: number | undefined;
864
+ vector_rank?: number | undefined;
865
+ } | undefined;
804
866
  }[];
805
867
  stale: boolean;
806
868
  revision_hash: string;
@@ -856,6 +918,17 @@ declare const recallOutputSchema: z.ZodObject<{
856
918
  } | undefined;
857
919
  read_path?: string | undefined;
858
920
  body_in_context?: boolean | undefined;
921
+ score?: number | undefined;
922
+ score_breakdown?: {
923
+ final: number;
924
+ salience: number;
925
+ recency: number;
926
+ locality: number;
927
+ bm25?: number | undefined;
928
+ bm25_rank?: number | undefined;
929
+ vector?: number | undefined;
930
+ vector_rank?: number | undefined;
931
+ } | undefined;
859
932
  }[];
860
933
  stale: boolean;
861
934
  revision_hash: string;
@@ -47,7 +47,7 @@ import {
47
47
  recallInputSchema,
48
48
  recallOutputSchema,
49
49
  structuredWarningSchema
50
- } from "../chunk-D7HUHWBI.js";
50
+ } from "../chunk-7PS7LB5T.js";
51
51
  export {
52
52
  FabExtractKnowledgeInputSchema,
53
53
  FabExtractKnowledgeInputShape,
@@ -7,8 +7,8 @@ import {
7
7
  BOOTSTRAP_REGEX,
8
8
  matchBootstrapCanonicalLocale,
9
9
  resolveBootstrapCanonical
10
- } from "../chunk-SQKWD7X6.js";
11
- import "../chunk-2GLIAZ5M.js";
10
+ } from "../chunk-KFFBQRL5.js";
11
+ import "../chunk-ASS2KBB7.js";
12
12
  export {
13
13
  BOOTSTRAP_CANONICAL_BY_LOCALE,
14
14
  BOOTSTRAP_CANONICAL_EN,
package/dist/theme.d.ts CHANGED
@@ -23,6 +23,7 @@ declare const SYMBOL_ASCII: {
23
23
  };
24
24
  declare function symbol(kind: keyof typeof SYMBOL_ASCII, colorOn?: boolean): string;
25
25
  declare function sectionBar(title: string, colorOn?: boolean): string;
26
+ declare function headerRule(title: string, colorOn?: boolean): string;
26
27
  declare const SCOPE_BADGE_TOKEN: {
27
28
  readonly team: "drift";
28
29
  readonly project: "ai";
@@ -30,4 +31,4 @@ declare const SCOPE_BADGE_TOKEN: {
30
31
  };
31
32
  declare function scopeBadge(scope: keyof typeof SCOPE_BADGE_TOKEN, colorOn?: boolean): string;
32
33
 
33
- export { ANSI, PALETTE, SYMBOL_ASCII, type ThemeToken, isColorEnabled, paint, scopeBadge, sectionBar, symbol };
34
+ export { ANSI, PALETTE, SYMBOL_ASCII, type ThemeToken, headerRule, isColorEnabled, paint, scopeBadge, sectionBar, symbol };
package/dist/theme.js CHANGED
@@ -40,6 +40,12 @@ function symbol(kind, colorOn = isColorEnabled()) {
40
40
  function sectionBar(title, colorOn = isColorEnabled()) {
41
41
  return colorOn ? `${ANSI.bold}${PALETTE.accent}\u258C ${title}${ANSI.reset}` : `# ${title}`;
42
42
  }
43
+ function headerRule(title, colorOn = isColorEnabled()) {
44
+ const head = colorOn ? `${ANSI.bold}${PALETTE.accent}${title}${ANSI.reset}` : title;
45
+ const rule = paint("muted", (colorOn ? "\u2500" : "-").repeat(40), colorOn);
46
+ return `${head}
47
+ ${rule}`;
48
+ }
43
49
  var SCOPE_BADGE_TOKEN = { team: "drift", project: "ai", personal: "human" };
44
50
  function scopeBadge(scope, colorOn = isColorEnabled()) {
45
51
  const text = `[${scope}]`;
@@ -49,6 +55,7 @@ export {
49
55
  ANSI,
50
56
  PALETTE,
51
57
  SYMBOL_ASCII,
58
+ headerRule,
52
59
  isColorEnabled,
53
60
  paint,
54
61
  scopeBadge,
@@ -1,2 +1,2 @@
1
- export { a as AgentsIdentitySource, c as AgentsMeta, d as AgentsMetaCountersEnvelope, e as AgentsMetaKnowledgeTypeCounters, A as AgentsMetaNode, b as AgentsTopologyType, g as AiLedgerEntry, h as AuditMode, C as ClientPaths, D as DefaultLayerFilter, F as FabricConfig, i as FabricLanguage, j as HumanLedgerEntry, H as HumanLockEntry, L as LedgerEntry, M as McpPayloadLimits, R as RuleDescription, k as RuleDescriptionIndexItem } from '../index-BqsM1bzx.js';
1
+ export { a as AgentsIdentitySource, d as AgentsMeta, e as AgentsMetaCountersEnvelope, g as AgentsMetaKnowledgeTypeCounters, A as AgentsMetaNode, b as AgentsTopologyType, h as AiLedgerEntry, i as AuditMode, C as ClientPaths, D as DefaultLayerFilter, F as FabricConfig, j as FabricLanguage, m as HumanLedgerEntry, H as HumanLockEntry, L as LedgerEntry, n as McpPayloadLimits, o as RecallScore, p as RecallScoreBreakdown, q as RuleDescription, r as RuleDescriptionIndexItem } from '../index-C0cijMSw.js';
2
2
  import 'zod';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fenglimg/fabric-shared",
3
- "version": "2.3.0-rc.1",
3
+ "version": "2.3.0-rc.3",
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>",