@fenglimg/fabric-shared 2.2.0 → 2.3.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-5AKCRBKJ.js → chunk-7PS7LB5T.js} +141 -78
- package/dist/{chunk-2GLIAZ5M.js → chunk-ANUDBQBK.js} +17 -6
- package/dist/chunk-OAYQHN6J.js +152 -0
- package/dist/{chunk-AQMDXC6J.js → chunk-ZYBWITH7.js} +218 -67
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/index-BO7itJ8e.d.ts +892 -0
- package/dist/index.d.ts +31 -243
- package/dist/index.js +172 -117
- package/dist/schemas/api-contracts.d.ts +425 -352
- package/dist/schemas/api-contracts.js +11 -1
- package/dist/templates/bootstrap-canonical.d.ts +2 -2
- package/dist/templates/bootstrap-canonical.js +2 -2
- package/dist/theme.d.ts +33 -0
- package/dist/theme.js +57 -0
- package/dist/types/index.d.ts +1 -1
- package/package.json +17 -3
- package/dist/chunk-BDJQIOQO.js +0 -206
- package/dist/index-D_gT1CEA.d.ts +0 -425
package/dist/index.js
CHANGED
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
BOOTSTRAP_REGEX,
|
|
8
8
|
matchBootstrapCanonicalLocale,
|
|
9
9
|
resolveBootstrapCanonical
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-OAYQHN6J.js";
|
|
11
|
+
import "./chunk-LXNCAKJZ.js";
|
|
11
12
|
import {
|
|
12
13
|
PROTECTED_TOKENS,
|
|
13
14
|
createTranslator,
|
|
@@ -15,7 +16,7 @@ import {
|
|
|
15
16
|
enMessages,
|
|
16
17
|
resolveFabricLocale,
|
|
17
18
|
zhCNMessages
|
|
18
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-ZYBWITH7.js";
|
|
19
20
|
import {
|
|
20
21
|
GLOBAL_BINDINGS_DIR,
|
|
21
22
|
GLOBAL_STATE_DIR,
|
|
@@ -50,7 +51,7 @@ import {
|
|
|
50
51
|
storeRelativePath,
|
|
51
52
|
storeRelativePathForMount,
|
|
52
53
|
storeUuidSchema
|
|
53
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-ANUDBQBK.js";
|
|
54
55
|
import {
|
|
55
56
|
atomicWriteJson,
|
|
56
57
|
withFileLock
|
|
@@ -59,6 +60,10 @@ import {
|
|
|
59
60
|
FabExtractKnowledgeInputSchema,
|
|
60
61
|
FabExtractKnowledgeInputShape,
|
|
61
62
|
FabExtractKnowledgeOutputSchema,
|
|
63
|
+
FabPendingInputSchema,
|
|
64
|
+
FabPendingInputShape,
|
|
65
|
+
FabPendingOutputSchema,
|
|
66
|
+
FabPendingOutputShape,
|
|
62
67
|
FabReviewInputSchema,
|
|
63
68
|
FabReviewInputShape,
|
|
64
69
|
FabReviewOutputSchema,
|
|
@@ -74,6 +79,7 @@ import {
|
|
|
74
79
|
PERSONAL_SCOPE,
|
|
75
80
|
PROPOSED_REASON_DESCRIPTIONS_BY_LOCALE,
|
|
76
81
|
ProposedReasonSchema,
|
|
82
|
+
SCOPE_COORDINATE_HINT,
|
|
77
83
|
SCOPE_COORDINATE_PATTERN,
|
|
78
84
|
StableIdSchema,
|
|
79
85
|
annotateIntentRequestSchema,
|
|
@@ -85,6 +91,7 @@ import {
|
|
|
85
91
|
citeLayerTypeBreakdownSchema,
|
|
86
92
|
entryScopeMetadataSchema,
|
|
87
93
|
fabExtractKnowledgeAnnotations,
|
|
94
|
+
fabPendingAnnotations,
|
|
88
95
|
fabReviewAnnotations,
|
|
89
96
|
formatKnowledgeId,
|
|
90
97
|
historyStateQuerySchema,
|
|
@@ -109,8 +116,7 @@ import {
|
|
|
109
116
|
scopeCoordinateSchema,
|
|
110
117
|
scopeRoot,
|
|
111
118
|
structuredWarningSchema
|
|
112
|
-
} from "./chunk-
|
|
113
|
-
import "./chunk-LXNCAKJZ.js";
|
|
119
|
+
} from "./chunk-7PS7LB5T.js";
|
|
114
120
|
|
|
115
121
|
// src/schemas/agents-meta.ts
|
|
116
122
|
import { z } from "zod";
|
|
@@ -349,6 +355,32 @@ var humanLockFileSchema = z4.object({
|
|
|
349
355
|
|
|
350
356
|
// src/schemas/fabric-config.ts
|
|
351
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
|
+
}
|
|
352
384
|
var auditModeSchema = z5.enum(["strict", "warn", "off"]);
|
|
353
385
|
var clientPathsSchema = z5.object({
|
|
354
386
|
claudeCodeCLI: z5.string().optional(),
|
|
@@ -395,7 +427,9 @@ var fabricConfigSchema = z5.object({
|
|
|
395
427
|
// `$personal` sentinel). Drives the read-set (required_stores ∪ implicit
|
|
396
428
|
// personal, S11/S54) and `clone`'s missing-store onboarding (S51). Optional
|
|
397
429
|
// + absent → read-set is just the implicit personal store.
|
|
398
|
-
|
|
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(),
|
|
399
433
|
// v2.1.0-rc.1 P3 (S60 / `store switch-write`): alias of the store that
|
|
400
434
|
// non-personal-scope writes land in for this project. Set by
|
|
401
435
|
// `fabric store switch-write <alias>`; consumed as the resolver's
|
|
@@ -494,92 +528,28 @@ var fabricConfigSchema = z5.object({
|
|
|
494
528
|
// worst — pairing 14d trigger + 7d cooldown means at most ~2 reminders
|
|
495
529
|
// per month for a workspace that ignores them.
|
|
496
530
|
maintenance_hint_cooldown_days: z5.number().int().positive().optional().default(7),
|
|
497
|
-
//
|
|
498
|
-
//
|
|
499
|
-
//
|
|
500
|
-
//
|
|
501
|
-
//
|
|
502
|
-
|
|
503
|
-
// rc.9+ (skill-contract-fix B1): rerun import window in months. After
|
|
504
|
-
// the first successful import, subsequent runs only scan this many
|
|
505
|
-
// recent months — assumed everything older has already been crystallized
|
|
506
|
-
// into pending or canonical knowledge. Default 2 keeps incremental cost
|
|
507
|
-
// low; raise to 6 if the workspace pauses fabric-import for long stretches.
|
|
508
|
-
import_window_rerun_months: z5.number().int().min(1).optional().default(2),
|
|
509
|
-
// rc.9+ (skill-contract-fix B1): hard cap on pending entries produced
|
|
510
|
-
// per fabric-import invocation. Prevents one run from dumping hundreds
|
|
511
|
-
// of proposals when a backfill window is wide open. Default 10 matches
|
|
512
|
-
// the rule-of-thumb "human can triage ~10 pending entries in one
|
|
513
|
-
// review pass." Range 1-50.
|
|
514
|
-
import_max_pending_per_run: z5.number().int().min(1).max(50).optional().default(10),
|
|
515
|
-
// rc.9+ (skill-contract-fix B1): hard cap on commits scanned per
|
|
516
|
-
// fabric-import invocation. Bounds runtime on monorepos with high
|
|
517
|
-
// commit velocity. Default 500 covers ~2 months of typical churn;
|
|
518
|
-
// range 50-2000. Hitting the cap mid-window is logged but non-fatal.
|
|
519
|
-
import_max_commits_scan: z5.number().int().min(50).max(2e3).optional().default(500),
|
|
520
|
-
// rc.9+ (skill-contract-fix B1): canonical-node count above which
|
|
521
|
-
// fabric-import's pre-flight should warn / suggest review instead of
|
|
522
|
-
// proceeding. A workspace with 50+ canonical entries usually benefits
|
|
523
|
-
// more from `fabric-review` to consolidate than from importing more.
|
|
524
|
-
// Default 50; raise to 100+ for large polyglot repos.
|
|
525
|
-
import_skip_canonical_threshold: z5.number().int().positive().optional().default(50),
|
|
526
|
-
// rc.9+ (skill-contract-fix B1): max candidate entries surfaced per
|
|
527
|
-
// fabric-archive batch (one invocation of the skill). Pagination knob
|
|
528
|
-
// for the archive UI flow. Default 8 keeps each batch reviewable in
|
|
529
|
-
// one sitting; raise for large repos with high archive throughput.
|
|
530
|
-
archive_max_candidates_per_batch: z5.number().int().positive().optional().default(8),
|
|
531
|
-
// rc.9+ (skill-contract-fix B1): max recently-touched paths included
|
|
532
|
-
// in fabric-archive's "relevant context" lookup. Limits the size of
|
|
533
|
-
// the path-relevance digest the skill emits when ranking candidates.
|
|
534
|
-
// Default 20; large repos with deep directory fan-out can raise to
|
|
535
|
-
// 50+ if archive candidates feel under-contextualized.
|
|
536
|
-
archive_max_recent_paths: z5.number().int().positive().optional().default(20),
|
|
537
|
-
// rc.9+ (skill-contract-fix B1): max prior fabric-archive sessions
|
|
538
|
-
// summarised in the digest the skill loads on start. Prevents the
|
|
539
|
-
// digest from ballooning past the model context budget on workspaces
|
|
540
|
-
// that have archived repeatedly. Default 10; lower if context pressure
|
|
541
|
-
// bites, raise if you want longer-range archive trend visibility.
|
|
542
|
-
archive_digest_max_sessions: z5.number().int().positive().optional().default(10),
|
|
543
|
-
// rc.9+ (skill-contract-fix B1): max review results returned per
|
|
544
|
-
// topic when `fabric-review` clusters pending entries. Pagination
|
|
545
|
-
// knob analogous to archive_max_candidates_per_batch but scoped to
|
|
546
|
-
// each topic cluster. Default 8; raise to 15-20 for large repos
|
|
547
|
-
// where each topic legitimately groups many pending entries.
|
|
548
|
-
review_topic_result_cap: z5.number().int().positive().optional().default(8),
|
|
531
|
+
// ux-w2-3: import_*/archive_max_*/review_topic_result_cap skill thresholds
|
|
532
|
+
// were hardcoded (✂ per census Table 1) — never tuned, pure skill-internal
|
|
533
|
+
// pagination/window caps. Removed from the schema; the skills/services read
|
|
534
|
+
// raw config with a built-in default, so an absent key falls to that default
|
|
535
|
+
// (60/2/10/500/50/8/20/10/8 respectively). Lenient parser drops any stale
|
|
536
|
+
// on-disk value.
|
|
549
537
|
// rc.9+ (skill-contract-fix B1): age threshold (in days) above which
|
|
550
538
|
// a pending entry is considered "stale" by fabric-review and surfaced
|
|
551
539
|
// for explicit resolve-or-drop decision. Default 14; tighter than the
|
|
552
540
|
// 7d Signal-B trigger because review specifically targets the long
|
|
553
541
|
// tail. Large repos with slower cadence can raise to 30.
|
|
554
542
|
review_stale_pending_days: z5.number().int().positive().optional().default(14),
|
|
555
|
-
// v2.0.0-rc.34 TASK-05: reverse-unarchive opt-in. When true, callers of the
|
|
556
|
-
// `unarchiveKnowledge` primitive (and any future doctor auto-detect lint built
|
|
557
|
-
// on top) will execute the file move + ledger emit. When false (default),
|
|
558
|
-
// the same callers MUST short-circuit before any mutation — the primitive is
|
|
559
|
-
// shipped but inert until explicitly enabled. Opt-in posture mirrors the
|
|
560
|
-
// archive-flow precedent: destructive-ish file moves stay behind a flag.
|
|
561
|
-
reverse_unarchive_enabled: z5.boolean().optional().default(false),
|
|
562
|
-
// v2.0.0-rc.34 TASK-05: forces `unarchiveKnowledge` into dry-run mode even
|
|
563
|
-
// when called with `options.dryRun=false`. Lets operators preview a
|
|
564
|
-
// restoration pass before flipping `reverse_unarchive_enabled` to true.
|
|
565
|
-
reverse_unarchive_dry_run: z5.boolean().optional().default(false),
|
|
566
|
-
// v2.0.0-rc.34 TASK-06: long-session cite-policy evict window in user-prompt
|
|
567
|
-
// turns. UserPromptSubmit hook (Claude Code only) maintains a per-session
|
|
568
|
-
// counter and re-injects the cite contract reminder via
|
|
569
|
-
// hookSpecificOutput.additionalContext when `turn_count % interval === 0`.
|
|
570
|
-
// Default 0 = OFF (opt-in). Recommend 10-20 for active sessions; 5 for
|
|
571
|
-
// high-contract-criticality projects. Other strategies (time-based,
|
|
572
|
-
// token-budget) deferred to rc.35 per plan locked-decisions 2026-05-26.
|
|
573
|
-
cite_evict_interval: z5.number().int().min(0).optional().default(0),
|
|
574
543
|
// v2.1 ⑤ cite-redesign (P5): recall-based cite-accounting hook config. The
|
|
575
|
-
//
|
|
576
|
-
//
|
|
577
|
-
// key
|
|
578
|
-
//
|
|
579
|
-
//
|
|
580
|
-
//
|
|
581
|
-
//
|
|
582
|
-
//
|
|
544
|
+
// PreToolUse(Edit/Write) recall-aware nudge in cite-policy-evict.cjs replaced
|
|
545
|
+
// the retired rc.34 `cite_evict_interval` turn-counter. ux-w1-5: that inert
|
|
546
|
+
// key — plus the never-wired `reverse_unarchive_enabled`/`reverse_unarchive_dry_run`
|
|
547
|
+
// opt-in flags (the unarchiveKnowledge primitive takes dryRun from its caller,
|
|
548
|
+
// not from config) — were deleted; the lenient root parser drops any stale
|
|
549
|
+
// value left in an on-disk config. `cite_recall_nudge` is the master switch
|
|
550
|
+
// (default true = ON); set false to silence the "改前先 fab_recall" nudge
|
|
551
|
+
// entirely. `cite_recall_window_minutes` bounds how far back an in-session
|
|
552
|
+
// fab_recall counts as "informing" the edit (default 30; 0 = unbounded).
|
|
583
553
|
cite_recall_nudge: z5.boolean().optional().default(true),
|
|
584
554
|
cite_recall_window_minutes: z5.number().int().min(0).optional().default(30),
|
|
585
555
|
// F2: glob exemptions for the cite nudge (cite-policy-evict.cjs). Edit paths
|
|
@@ -625,18 +595,11 @@ var fabricConfigSchema = z5.object({
|
|
|
625
595
|
// Default `[]` keeps the field optional on existing configs — fresh
|
|
626
596
|
// installs land with no opt-outs.
|
|
627
597
|
onboard_slots_opted_out: z5.array(z5.string()).optional().default([]),
|
|
628
|
-
//
|
|
629
|
-
//
|
|
630
|
-
//
|
|
631
|
-
//
|
|
632
|
-
//
|
|
633
|
-
// broad entries which buried the actually-relevant top hits). Default 8 is
|
|
634
|
-
// calibrated against the rc.32 eval baseline (cite-coverage 3.1%): the
|
|
635
|
-
// banner needs to fit in ~1 screenful so the agent actually reads it.
|
|
636
|
-
// Range 1..50; values above 20 effectively disable the cap because the
|
|
637
|
-
// TRUNCATION_THRESHOLD=12 grouped-render kicks in. Mirrors the rc.7 T7 +
|
|
638
|
-
// archive_max_* pattern of externalizing previously-hardcoded thresholds.
|
|
639
|
-
hint_broad_top_k: z5.number().int().min(1).max(50).optional().default(8),
|
|
598
|
+
// ux-w3-j (W3-J): `hint_broad_top_k` was deleted. W2-1 (KT-DEC-0028) retired its
|
|
599
|
+
// hard-cap function — the SessionStart broad banner now shows EVERY broad entry
|
|
600
|
+
// and `broad_index_backstop` (below) is the sole scale guard; the field had been
|
|
601
|
+
// inert ever since (its only remaining refs were retirement comments). The lenient
|
|
602
|
+
// root parser drops any stale on-disk value (zero migration).
|
|
640
603
|
// KT-DEC-0036: the SessionStart broad-menu is now index-only (title + summary
|
|
641
604
|
// per always-active entry, no eager body), so the former `hint_broad_budget_chars`
|
|
642
605
|
// body char-budget knob was retired — there is no rendered body left to bound.
|
|
@@ -714,6 +677,15 @@ var fabricConfigSchema = z5.object({
|
|
|
714
677
|
orphan_demote_proven_days: z5.number().int().min(1).max(3650).optional(),
|
|
715
678
|
orphan_demote_verified_days: z5.number().int().min(1).max(3650).optional(),
|
|
716
679
|
orphan_demote_draft_days: z5.number().int().min(1).max(3650).optional(),
|
|
680
|
+
// v2.2 C1 (processes/maturity-promotion-rubric-v1): days a `broad` entry may
|
|
681
|
+
// go without a fab-review re-confirmation before doctor surfaces a RECHECK
|
|
682
|
+
// nudge. `broad` is EXEMPT from usage-age decay (it is SessionStart-pushed,
|
|
683
|
+
// never pull-recalled → usage-blind, KT-DEC; see doctor-knowledge-age.ts), so
|
|
684
|
+
// its continued validity is instead checked against the review-confirmation
|
|
685
|
+
// clock (`last_review_confirmed_at`, stamped at approve/modify). This is a
|
|
686
|
+
// non-blocking INFO nudge ("re-confirm"), NEVER an auto-demote. Absent → the
|
|
687
|
+
// config-loader default (180d) applies. Range 1..3650 mirrors orphan_demote.
|
|
688
|
+
broad_review_recheck_days: z5.number().int().min(1).max(3650).optional(),
|
|
717
689
|
// v2.0.0-rc.33 W4-A3 (T4 P2): per-entry summary truncation length used by
|
|
718
690
|
// knowledge-hint-{broad,narrow}.cjs. Hard-coded at 80 chars in rc.32 — too
|
|
719
691
|
// short for entries with parameterized summaries (e.g. "Use bcrypt with
|
|
@@ -762,10 +734,13 @@ var fabricConfigSchema = z5.object({
|
|
|
762
734
|
// sole retrieval knob (plan_context_top_k above); payload limits pass through
|
|
763
735
|
// explicit `mcpPayloadLimits`, else the fixed PAYLOAD_LIMIT_DEFAULT_* guardrail.
|
|
764
736
|
// v2.2 C2-vector (W2-T7): OPTIONAL dense-embedding semantic retrieval, layered
|
|
765
|
-
// as a recall supplement after BM25.
|
|
766
|
-
//
|
|
767
|
-
// text-only fallback
|
|
768
|
-
|
|
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),
|
|
769
744
|
// Weight applied to the 0..1 cosine similarity before it joins the additive
|
|
770
745
|
// score. Capped at 49 — strictly BELOW BM25_WEIGHT (50) — so a perfect vector
|
|
771
746
|
// match (weight × 1) can never outscore a single strong BM25 term match. This
|
|
@@ -790,8 +765,22 @@ var fabricConfigSchema = z5.object({
|
|
|
790
765
|
"fast-bge-base-en-v1.5",
|
|
791
766
|
"fast-bge-base-en",
|
|
792
767
|
"fast-all-MiniLM-L6-v2"
|
|
793
|
-
]).optional().default("fast-bge-small-zh-v1.5")
|
|
794
|
-
|
|
768
|
+
]).optional().default("fast-bge-small-zh-v1.5"),
|
|
769
|
+
// P1 recall-engine-refactor (TASK-003): content-channel fusion strategy.
|
|
770
|
+
// 'additive' (DEFAULT) = the historical weighted-sum path (BM25_WEIGHT·bm25 +
|
|
771
|
+
// vectorWeight·vector + structural). 'rrf' = Reciprocal Rank Fusion over the
|
|
772
|
+
// two CONTENT channels (bm25_rank, vector_rank) plus the unchanged structural
|
|
773
|
+
// boost. RRF is gated behind this flag and ships OFF — flipping the default to
|
|
774
|
+
// 'rrf' is a separate human decision gated on a one-off shadow run against the
|
|
775
|
+
// developer's real bound team store. no-query ranking is byte-identical under
|
|
776
|
+
// both values (the content channels contribute nothing without query terms).
|
|
777
|
+
fusion: z5.enum(["additive", "rrf"]).optional().default("additive")
|
|
778
|
+
});
|
|
779
|
+
var fabricConfigLoadSchema = fabricConfigSchema.merge(
|
|
780
|
+
z5.object({
|
|
781
|
+
required_stores: z5.array(requiredStoreEntrySchema).optional()
|
|
782
|
+
})
|
|
783
|
+
);
|
|
795
784
|
|
|
796
785
|
// src/schemas/fabric-config-introspect.ts
|
|
797
786
|
import { z as z6 } from "zod";
|
|
@@ -956,9 +945,11 @@ var PANEL_FIELDS = [
|
|
|
956
945
|
// nudge_mode — the master switch for the human-visible nudge experience
|
|
957
946
|
// (the most user-facing runtime knob, previously JSON-only). embed_enabled —
|
|
958
947
|
// vector semantic recall, panel-editable now that config lives in `.fabric`
|
|
959
|
-
// (A1)
|
|
948
|
+
// (A1). TASK-004: default ON (fastembed is an optionalDependency, degrade-safe
|
|
949
|
+
// when absent) — this introspection default mirrors the runtime read in
|
|
950
|
+
// config-loader.ts so the panel never shows a default that contradicts behavior.
|
|
960
951
|
makeEnumField("nudge_mode", "D_behavior", nudgeModeSchema.options, "normal"),
|
|
961
|
-
makeBooleanField("embed_enabled",
|
|
952
|
+
makeBooleanField("embed_enabled", true)
|
|
962
953
|
];
|
|
963
954
|
|
|
964
955
|
// src/schemas/store-stable-id.ts
|
|
@@ -1125,6 +1116,13 @@ var storeResolveInputSchema = z9.object({
|
|
|
1125
1116
|
),
|
|
1126
1117
|
// Alias selected as the active write store for non-personal scopes, if any.
|
|
1127
1118
|
activeWriteAlias: z9.string().min(1).optional(),
|
|
1119
|
+
// Alias/UUID of the ACTIVE personal store among possibly-many mounted
|
|
1120
|
+
// `personal:true` stores (语义 A: singleton-at-a-time). Drives the SINGLE
|
|
1121
|
+
// personal choke point (findPersonal) → both read-set inclusion and the
|
|
1122
|
+
// personal-scope write-target. Absent or dangling ⇒ the resolver falls back
|
|
1123
|
+
// to the first mounted personal, so legacy single-personal configs are
|
|
1124
|
+
// unchanged. Sourced from `~/.fabric/fabric-global.json` → active_personal_store.
|
|
1125
|
+
activePersonalAlias: z9.string().min(1).optional(),
|
|
1128
1126
|
// Scope-aware write routes. Exact scope wins first, then longest prefix route.
|
|
1129
1127
|
writeRoutes: z9.array(
|
|
1130
1128
|
z9.object({
|
|
@@ -1187,7 +1185,16 @@ function createProjectRootResolver() {
|
|
|
1187
1185
|
|
|
1188
1186
|
// src/resolver/store-resolver.ts
|
|
1189
1187
|
function findPersonal(input) {
|
|
1190
|
-
|
|
1188
|
+
const actives = input.mountedStores.filter((s) => s.personal);
|
|
1189
|
+
if (input.activePersonalAlias !== void 0) {
|
|
1190
|
+
const picked = actives.find(
|
|
1191
|
+
(s) => s.alias === input.activePersonalAlias || s.store_uuid === input.activePersonalAlias
|
|
1192
|
+
);
|
|
1193
|
+
if (picked !== void 0) {
|
|
1194
|
+
return picked;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
return actives[0];
|
|
1191
1198
|
}
|
|
1192
1199
|
function personalEntry(input) {
|
|
1193
1200
|
const p = findPersonal(input);
|
|
@@ -1254,7 +1261,7 @@ function createStoreResolver() {
|
|
|
1254
1261
|
warnings.push({
|
|
1255
1262
|
code: "missing_store",
|
|
1256
1263
|
ref: req.id,
|
|
1257
|
-
message: `required store '${req.id}' is not mounted; run \`fabric store
|
|
1264
|
+
message: `required store '${req.id}' is not mounted; run \`fabric store mount\` (suggested remote: $personal)`
|
|
1258
1265
|
});
|
|
1259
1266
|
}
|
|
1260
1267
|
continue;
|
|
@@ -1267,7 +1274,7 @@ function createStoreResolver() {
|
|
|
1267
1274
|
warnings.push({
|
|
1268
1275
|
code: "missing_store",
|
|
1269
1276
|
ref: req.id,
|
|
1270
|
-
message: `required store '${req.id}' is not mounted; run \`fabric store
|
|
1277
|
+
message: `required store '${req.id}' is not mounted; run \`fabric store mount\`${suffix}`
|
|
1271
1278
|
});
|
|
1272
1279
|
continue;
|
|
1273
1280
|
}
|
|
@@ -1313,7 +1320,7 @@ function createStoreResolver() {
|
|
|
1313
1320
|
{
|
|
1314
1321
|
code: "missing_write_route",
|
|
1315
1322
|
ref: scope,
|
|
1316
|
-
message: `scope '${scope}' has no explicit write route; set \`fabric store
|
|
1323
|
+
message: `scope '${scope}' has no explicit write route; set \`fabric store switch-write <alias> --scope ${scope}\``
|
|
1317
1324
|
}
|
|
1318
1325
|
]
|
|
1319
1326
|
};
|
|
@@ -1776,7 +1783,12 @@ function loadProjectConfig(projectRoot) {
|
|
|
1776
1783
|
if (!existsSync3(path)) {
|
|
1777
1784
|
return null;
|
|
1778
1785
|
}
|
|
1779
|
-
|
|
1786
|
+
const raw = JSON.parse(readFileSync3(path, "utf8"));
|
|
1787
|
+
const parsed = fabricConfigSchema.safeParse(raw);
|
|
1788
|
+
if (parsed.success) {
|
|
1789
|
+
return parsed.data;
|
|
1790
|
+
}
|
|
1791
|
+
return fabricConfigLoadSchema.parse(raw);
|
|
1780
1792
|
}
|
|
1781
1793
|
function saveProjectConfig(config, projectRoot) {
|
|
1782
1794
|
const validated = fabricConfigSchema.parse(config);
|
|
@@ -1809,6 +1821,7 @@ function buildStoreResolveInput(projectRoot, globalRoot = resolveGlobalRoot()) {
|
|
|
1809
1821
|
})
|
|
1810
1822
|
),
|
|
1811
1823
|
...project?.active_write_store === void 0 ? {} : { activeWriteAlias: project.active_write_store },
|
|
1824
|
+
...global.active_personal_store === void 0 ? {} : { activePersonalAlias: global.active_personal_store },
|
|
1812
1825
|
writeRoutes: project?.write_routes ?? [],
|
|
1813
1826
|
...project?.default_write_store === void 0 ? {} : { defaultWriteAlias: project.default_write_store }
|
|
1814
1827
|
};
|
|
@@ -2018,7 +2031,7 @@ var MCP_STORE_AWARE_TOOLS = [
|
|
|
2018
2031
|
"fab_plan_context",
|
|
2019
2032
|
"fab_get_knowledge_sections",
|
|
2020
2033
|
"fab_archive_scan",
|
|
2021
|
-
"
|
|
2034
|
+
"fab_propose",
|
|
2022
2035
|
"fab_review"
|
|
2023
2036
|
];
|
|
2024
2037
|
var storeAwareEntrySchema = z11.object({
|
|
@@ -2043,8 +2056,8 @@ var MCP_STORE_AWARE_CONTRACTS = {
|
|
|
2043
2056
|
surfacesEntries: false,
|
|
2044
2057
|
echoesWrittenStore: false
|
|
2045
2058
|
},
|
|
2046
|
-
|
|
2047
|
-
tool: "
|
|
2059
|
+
fab_propose: {
|
|
2060
|
+
tool: "fab_propose",
|
|
2048
2061
|
surfacesEntries: false,
|
|
2049
2062
|
echoesWrittenStore: true
|
|
2050
2063
|
},
|
|
@@ -3221,6 +3234,34 @@ var eventLedgerEventSchema = z16.discriminatedUnion("event_type", [
|
|
|
3221
3234
|
var CJK_CLASS = "\\u3400-\\u4dbf\\u4e00-\\u9fff\\uf900-\\ufaff\\u3040-\\u30ff\\uac00-\\ud7af";
|
|
3222
3235
|
var RUN_RE = new RegExp(`[a-z0-9]+|[${CJK_CLASS}]+`, "gu");
|
|
3223
3236
|
var CJK_FIRST_RE = new RegExp(`[${CJK_CLASS}]`, "u");
|
|
3237
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
3238
|
+
"the",
|
|
3239
|
+
"a",
|
|
3240
|
+
"an",
|
|
3241
|
+
"and",
|
|
3242
|
+
"or",
|
|
3243
|
+
"of",
|
|
3244
|
+
"to",
|
|
3245
|
+
"in",
|
|
3246
|
+
"on",
|
|
3247
|
+
"for",
|
|
3248
|
+
"is",
|
|
3249
|
+
"it",
|
|
3250
|
+
"with",
|
|
3251
|
+
"as",
|
|
3252
|
+
"at",
|
|
3253
|
+
"by",
|
|
3254
|
+
"be",
|
|
3255
|
+
"are",
|
|
3256
|
+
"was",
|
|
3257
|
+
"were",
|
|
3258
|
+
"this",
|
|
3259
|
+
"that",
|
|
3260
|
+
"from",
|
|
3261
|
+
"but",
|
|
3262
|
+
"not"
|
|
3263
|
+
]);
|
|
3264
|
+
var MAX_CJK_NGRAM = 3;
|
|
3224
3265
|
function tokenize(text) {
|
|
3225
3266
|
if (text.length === 0) {
|
|
3226
3267
|
return [];
|
|
@@ -3234,12 +3275,17 @@ function tokenize(text) {
|
|
|
3234
3275
|
if (CJK_FIRST_RE.test(run[0])) {
|
|
3235
3276
|
if (run.length === 1) {
|
|
3236
3277
|
tokens.push(run);
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3278
|
+
continue;
|
|
3279
|
+
}
|
|
3280
|
+
for (let n = 2; n <= MAX_CJK_NGRAM; n += 1) {
|
|
3281
|
+
if (run.length < n) {
|
|
3282
|
+
break;
|
|
3283
|
+
}
|
|
3284
|
+
for (let i = 0; i + n <= run.length; i += 1) {
|
|
3285
|
+
tokens.push(run.slice(i, i + n));
|
|
3240
3286
|
}
|
|
3241
3287
|
}
|
|
3242
|
-
} else {
|
|
3288
|
+
} else if (run.length >= 2 && !STOP_WORDS.has(run)) {
|
|
3243
3289
|
tokens.push(run);
|
|
3244
3290
|
}
|
|
3245
3291
|
}
|
|
@@ -3258,6 +3304,10 @@ export {
|
|
|
3258
3304
|
FabExtractKnowledgeInputSchema,
|
|
3259
3305
|
FabExtractKnowledgeInputShape,
|
|
3260
3306
|
FabExtractKnowledgeOutputSchema,
|
|
3307
|
+
FabPendingInputSchema,
|
|
3308
|
+
FabPendingInputShape,
|
|
3309
|
+
FabPendingOutputSchema,
|
|
3310
|
+
FabPendingOutputShape,
|
|
3261
3311
|
FabReviewInputSchema,
|
|
3262
3312
|
FabReviewInputShape,
|
|
3263
3313
|
FabReviewOutputSchema,
|
|
@@ -3285,6 +3335,7 @@ export {
|
|
|
3285
3335
|
PROTECTED_TOKENS,
|
|
3286
3336
|
ProposedReasonSchema,
|
|
3287
3337
|
REDACTION_PLACEHOLDER_PREFIX,
|
|
3338
|
+
SCOPE_COORDINATE_HINT,
|
|
3288
3339
|
SCOPE_COORDINATE_PATTERN,
|
|
3289
3340
|
STORES_ROOT_DIR,
|
|
3290
3341
|
STORE_ALIAS_PATTERN,
|
|
@@ -3355,7 +3406,9 @@ export {
|
|
|
3355
3406
|
eventsRotatedEventSchema,
|
|
3356
3407
|
explainStore,
|
|
3357
3408
|
fabExtractKnowledgeAnnotations,
|
|
3409
|
+
fabPendingAnnotations,
|
|
3358
3410
|
fabReviewAnnotations,
|
|
3411
|
+
fabricConfigLoadSchema,
|
|
3359
3412
|
fabricConfigSchema,
|
|
3360
3413
|
fabricEventSchema,
|
|
3361
3414
|
fabricLanguageSchema,
|
|
@@ -3400,6 +3453,7 @@ export {
|
|
|
3400
3453
|
initStore,
|
|
3401
3454
|
installDiffAppliedEventSchema,
|
|
3402
3455
|
isKnowledgeStableId,
|
|
3456
|
+
isNonPersonalRequiredStore,
|
|
3403
3457
|
isPersonalLeakIntoSharedStore,
|
|
3404
3458
|
isPersonalScope,
|
|
3405
3459
|
knowledgeArchiveAttemptedEventSchema,
|
|
@@ -3452,6 +3506,7 @@ export {
|
|
|
3452
3506
|
metaReconciledEventSchema,
|
|
3453
3507
|
metaReconciledOnStartupEventSchema,
|
|
3454
3508
|
metaUpdatedEventSchema,
|
|
3509
|
+
migrateRequiredStores,
|
|
3455
3510
|
mountedStoreSchema,
|
|
3456
3511
|
normalizeCiteTag,
|
|
3457
3512
|
normalizeLocale,
|