@fenglimg/fabric-server 2.3.0-rc.3 → 2.3.0-rc.5

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +175 -2
  2. package/dist/index.js +903 -191
  3. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { FabExtractKnowledgeInput, FabExtractKnowledgeOutput, FabReviewInput, FabReviewOutput, FabPendingInput, FabPendingOutput } from '@fenglimg/fabric-shared/schemas/api-contracts';
3
- import { EventLedgerEventInput, EventLedgerEvent, RuleDescriptionIndexItem, RecallScore, RecallScoreBreakdown, LedgerEntry, AgentsMeta } from '@fenglimg/fabric-shared';
3
+ import { RuleDescription, EventLedgerEventInput, EventLedgerEvent, RuleDescriptionIndexItem, RecallScore, RecallScoreBreakdown, LedgerEntry, AgentsMeta } from '@fenglimg/fabric-shared';
4
4
  import { PayloadGuardOptions } from '@fenglimg/fabric-shared/node/mcp-payload-guard';
5
5
 
6
6
  interface InFlightTracker {
@@ -33,6 +33,8 @@ type DoctorHealth = {
33
33
  };
34
34
  };
35
35
 
36
+ declare function extractRuleDescription(source: string): RuleDescription | undefined;
37
+
36
38
  interface AlwaysActiveBody {
37
39
  /** store-qualified id (`<alias>:<stableId>`). */
38
40
  stable_id: string;
@@ -78,6 +80,16 @@ interface KnowledgeCensus {
78
80
  */
79
81
  declare function buildKnowledgeCensus(projectRoot: string): Promise<KnowledgeCensus>;
80
82
  declare function buildAlwaysActiveBodies(projectRoot: string): Promise<AlwaysActiveBody[]>;
83
+ interface StoreCanonicalEntry {
84
+ stableId: string;
85
+ qualifiedId: string;
86
+ file: string;
87
+ type: string;
88
+ layer: "team" | "personal";
89
+ body: string;
90
+ description: NonNullable<ReturnType<typeof extractRuleDescription>>;
91
+ }
92
+ declare function collectStoreCanonicalEntries(projectRoot: string): Promise<StoreCanonicalEntry[]>;
81
93
 
82
94
  interface UnboundProjectViolation {
83
95
  /** The store already bound as the active write target. */
@@ -196,6 +208,11 @@ type CiteCoverageReport = {
196
208
  uncorrelatable_edits?: number;
197
209
  recall_backed_edits?: number;
198
210
  recall_coverage_rate?: number | null;
211
+ recall_diagnostics?: {
212
+ recalls_in_window: number;
213
+ recall_sessions: number;
214
+ recall_sessions_correlated: number;
215
+ };
199
216
  exposed_and_mutated?: {
200
217
  count: number;
201
218
  ids?: string[];
@@ -541,6 +558,20 @@ interface Embedder {
541
558
  embed(texts: string[]): Promise<number[][]>;
542
559
  }
543
560
  declare const OPTIONAL_EMBED_PACKAGE = "fastembed";
561
+ /**
562
+ * Is the optional embedder package resolvable FROM THE SERVER'S module location —
563
+ * i.e. from exactly where `loadEmbedder`'s dynamic `import()` will look for it?
564
+ *
565
+ * This is the honest "is fastembed installed?" probe. The naive alternative — a
566
+ * `createRequire(import.meta.url)` check run inside the CLI package — answers from
567
+ * the WRONG base: in a pnpm / non-hoisted layout (or a dev-linked global install)
568
+ * fastembed lives under the SERVER's `node_modules` (it is the server's
569
+ * optionalDependency), so the CLI cannot resolve it even though the server — the
570
+ * only code that actually imports it — can. That mismatch made `fabric info
571
+ * --recall` report "not installed" on a perfectly working setup. Callers that
572
+ * surface embedder availability MUST use this server-anchored probe.
573
+ */
574
+ declare function isEmbedderResolvable(): boolean;
544
575
  declare function defaultEmbedCacheDir(): string;
545
576
  /**
546
577
  * Lazy-load the optional fastembed embedder, pinned to CPU + cache-only. Returns
@@ -680,6 +711,148 @@ declare const COLD_EVAL_RUBRIC: string;
680
711
  */
681
712
  declare function buildColdEvalBatch(candidates: ColdEvalCandidate[]): ColdEvalBatch;
682
713
 
714
+ interface RelatedBrokenLink {
715
+ /** The entry (store-qualified id) that declared the `related` edge. */
716
+ source: string;
717
+ /** The unresolvable related value. */
718
+ target: string;
719
+ }
720
+ interface RelatedHubEntry {
721
+ stableId: string;
722
+ inDegree: number;
723
+ }
724
+ interface RelatedGraphInspection {
725
+ brokenLinks: RelatedBrokenLink[];
726
+ hubEntries: RelatedHubEntry[];
727
+ /** Total canonical entries scanned. */
728
+ totalEntries: number;
729
+ }
730
+ /** A single node fed into the pure graph builder. */
731
+ interface RelatedGraphNode {
732
+ /** Store-qualified id (`<alias>:<stableId>`). */
733
+ qualifiedId: string;
734
+ /** The entry's declared `related` edges (frontmatter), if any. */
735
+ related?: string[];
736
+ }
737
+ /**
738
+ * Build the related-edge graph from a list of nodes and report broken links +
739
+ * hub ranking. Pure — no I/O — so the broken-link / in-degree logic can be
740
+ * tested with hand-built fixtures.
741
+ *
742
+ * A "broken link" is a `related` value that does not appear as any node's
743
+ * store-qualified id NOR bare stable_id in the corpus. Store-qualified
744
+ * references (`alias:id`) and bare references (`id`) both resolve, because the
745
+ * id index carries both forms for every node.
746
+ */
747
+ declare function buildRelatedGraph(nodes: RelatedGraphNode[]): RelatedGraphInspection;
748
+ /**
749
+ * Walk the store canonical corpus and build the related graph. Never throws —
750
+ * collectStoreCanonicalEntries degrades to [] when no store is in the read-set.
751
+ *
752
+ * Note: the previous (dead, never-wired) draft of this module re-parsed each
753
+ * entry's frontmatter via extractRuleDescription(entry.file) — passing a FILE
754
+ * PATH where a raw-markdown SOURCE was expected, which silently produced no
755
+ * edges. StoreCanonicalEntry already carries the parsed `description`, so we
756
+ * read `description.related` directly (the single source the recall path uses).
757
+ */
758
+ declare function inspectRelatedGraph(projectRoot: string): Promise<RelatedGraphInspection>;
759
+
760
+ interface StoreReachability {
761
+ uuid: string;
762
+ alias: string;
763
+ reachable: boolean;
764
+ reason?: string;
765
+ }
766
+ interface PrecheckResult {
767
+ stores: StoreReachability[];
768
+ allReachable: boolean;
769
+ }
770
+ declare function clearPrecheckCache(): void;
771
+ /**
772
+ * Evaluate a single store directory's reachability. A store is reachable when
773
+ * BOTH hold:
774
+ * 1. The store directory exists on disk.
775
+ * 2. The directory contains either a `store.json` (valid JSON, local-only
776
+ * store) OR a `.git/` subdirectory (git-cloned store).
777
+ *
778
+ * Pure (filesystem-only, no config resolution) so the rule is testable with a
779
+ * temp directory regardless of the machine's ~/.fabric layout.
780
+ */
781
+ declare function evaluateStoreDir(storeDir: string, identity: {
782
+ uuid: string;
783
+ alias: string;
784
+ }): StoreReachability;
785
+ /**
786
+ * Check that every store in the project's read-set is reachable on disk.
787
+ * Results are cached for 60s (CACHE_TTL_MS). Call `clearPrecheckCache()` when a
788
+ * store mount / unmount operation invalidates the cache.
789
+ *
790
+ * `globalRoot` is injectable for hermetic tests; production callers use the
791
+ * resolved ~/.fabric root.
792
+ */
793
+ declare function precheckStoreReachability(projectRoot: string, globalRoot?: string, now?: number): Promise<PrecheckResult>;
794
+
795
+ interface ConsumptionLintConfig {
796
+ /** Rolling window in days (default 30). */
797
+ windowDays: number;
798
+ /** How many top-consumed entries to report (default 10). */
799
+ topN: number;
800
+ /** Minimum CORPUS size before the lint runs at all (fresh-install guard). */
801
+ minTotalEntries: number;
802
+ /**
803
+ * Data-maturity gate axis 1: minimum number of metrics windows (rows) that
804
+ * recorded ≥1 consumption counter before zero-consumed is trustworthy.
805
+ */
806
+ minConsumedWindows: number;
807
+ /**
808
+ * Data-maturity gate axis 2: minimum total consumption events in the window
809
+ * before zero-consumed is trustworthy.
810
+ */
811
+ minConsumedEvents: number;
812
+ }
813
+ interface ConsumptionEntry {
814
+ /** Store-qualified id (`<alias>:<stableId>`). */
815
+ stableId: string;
816
+ count: number;
817
+ }
818
+ interface ConsumptionInspection {
819
+ topConsumed: ConsumptionEntry[];
820
+ /**
821
+ * Corpus entries never consumed in the window. ALWAYS [] when the data is not
822
+ * mature (dataMature === false) — the gate suppresses the noisy signal.
823
+ */
824
+ zeroConsumed: string[];
825
+ /** Total corpus entries considered for the zero-consumed denominator. */
826
+ totalEntries: number;
827
+ /** Distinct entries with ≥1 consumption in the window. */
828
+ consumedEntries: number;
829
+ /** Number of metrics windows (rows) that carried ≥1 consumption counter. */
830
+ consumedWindows: number;
831
+ /** Sum of all consumption counts in the window. */
832
+ totalConsumedEvents: number;
833
+ /** True when both maturity axes clear their thresholds. */
834
+ dataMature: boolean;
835
+ windowDays: number;
836
+ }
837
+ /**
838
+ * Aggregate consumption from metrics rows against the canonical corpus id list.
839
+ * Pure — no I/O — so the windowing, prefix parsing, top-N ranking, zero-consumed
840
+ * computation, and the maturity gate are all testable with fixtures.
841
+ *
842
+ * @param rows metrics.jsonl rows (any window/order)
843
+ * @param allQualifiedIds store-qualified ids of the canonical corpus
844
+ * @param now current epoch ms (injected for deterministic windowing)
845
+ */
846
+ declare function aggregateConsumption(rows: MetricsRow[], allQualifiedIds: string[], now: number, config?: Partial<ConsumptionLintConfig>): ConsumptionInspection;
847
+ /**
848
+ * Read metrics.jsonl + the canonical corpus and aggregate consumption. Never
849
+ * throws — readMetrics returns [] on a missing ledger and collectStoreCanonical
850
+ * Entries returns [] when no store is in the read-set.
851
+ *
852
+ * `now` is injectable for deterministic tests.
853
+ */
854
+ declare function inspectConsumption(projectRoot: string, config?: Partial<ConsumptionLintConfig>, now?: number): Promise<ConsumptionInspection>;
855
+
683
856
  type StoredEventLedgerEvent = EventLedgerEvent;
684
857
  type ReadEventLedgerOptions = {
685
858
  event_type?: EventLedgerEvent["event_type"];
@@ -974,4 +1147,4 @@ interface ShutdownHandlerDeps {
974
1147
  */
975
1148
  declare function createShutdownHandler(deps: ShutdownHandlerDeps): () => void;
976
1149
 
977
- export { AGENTS_MD_RESOURCE_URI, type AlwaysActiveBody, type ArchiveHistoryEntry, type ArchiveHistoryReport, COLD_EVAL_RUBRIC, type CiteCoverageReport, type ColdEvalBatch, type ColdEvalCandidate, type ColdEvalVerdict, type ConflictEntry, type ConflictJudge, type ConflictLintReport, type ConflictPair, type ConflictVerdict, DEFAULT_CONFLICT_SIMILARITY_THRESHOLD, type DoctorApplyLintMutation, type DoctorApplyLintMutationKind, type DoctorApplyLintReport, type DoctorFixReport, type DoctorIssue, type DoctorReport, EVENT_LEDGER_PATH, type EnrichDescriptionsCandidate, type EnrichDescriptionsMode, type EnrichDescriptionsReport, FABRIC_SERVER_INSTRUCTIONS, type HistoryAllReport, type HistoryDayRow, type InFlightTracker, type KnowledgeCensus, LEDGER_PATH, LEGACY_LEDGER_PATH, METRICS_LEDGER_PATH, METRIC_COUNTER_NAMES, type MetricCounterName, type MetricsRow, OPTIONAL_EMBED_PACKAGE, type PlanContextInput, type PlanContextResult, RETIRED_TOKENS, type RecallInput, type RecallResult, type RequirementProfile, type RetiredReferenceHit, type RetiredReferenceInspection, type RetiredToken, type SelectionTokenState, type ShutdownHandlerDeps, type SurfaceVerdict, type UnboundProjectViolation, type WhyNotSurfacedResult, appendEventLedgerEvent, buildAlwaysActiveBodies, buildColdEvalBatch, buildKnowledgeCensus, bumpCounter, contextCache, createFabricServer, createInFlightTracker, createShutdownHandler, defaultEmbedCacheDir, detectUnboundProject, drainCounters, enrichDescriptions, explainWhyNotSurfaced, extractKnowledge, findConflictCandidates, flushAndSyncEventLedger, flushMetrics, formatPreexistingRootMessage, getEventLedgerPath, getLedgerPath, getLegacyLedgerPath, getMetricsLedgerPath, inspectRetiredReferences, lintConflicts, loadConflictEntries, loadEmbedder, pairSimilarity, planContext, readEmbedConfig, readEventLedger, readFusion, readLedger, readMetrics, readSelectionToken, recall, rehydrateAgentsMetaAt, resolveLedgerPaths, reviewKnowledge, reviewPending, runDoctorApplyLint, runDoctorArchiveHistory, runDoctorCiteCoverage, runDoctorConflictLint, runDoctorFix, runDoctorHistoryAll, runDoctorReport, startMetricsFlush, startRotationTick, startStdioServer, stopMetricsFlush, stopRotationTick };
1150
+ export { AGENTS_MD_RESOURCE_URI, type AlwaysActiveBody, type ArchiveHistoryEntry, type ArchiveHistoryReport, COLD_EVAL_RUBRIC, type CiteCoverageReport, type ColdEvalBatch, type ColdEvalCandidate, type ColdEvalVerdict, type ConflictEntry, type ConflictJudge, type ConflictLintReport, type ConflictPair, type ConflictVerdict, type ConsumptionEntry, type ConsumptionInspection, type ConsumptionLintConfig, DEFAULT_CONFLICT_SIMILARITY_THRESHOLD, type DoctorApplyLintMutation, type DoctorApplyLintMutationKind, type DoctorApplyLintReport, type DoctorFixReport, type DoctorIssue, type DoctorReport, EVENT_LEDGER_PATH, type EnrichDescriptionsCandidate, type EnrichDescriptionsMode, type EnrichDescriptionsReport, FABRIC_SERVER_INSTRUCTIONS, type HistoryAllReport, type HistoryDayRow, type InFlightTracker, type KnowledgeCensus, LEDGER_PATH, LEGACY_LEDGER_PATH, METRICS_LEDGER_PATH, METRIC_COUNTER_NAMES, type MetricCounterName, type MetricsRow, OPTIONAL_EMBED_PACKAGE, type PlanContextInput, type PlanContextResult, type PrecheckResult, RETIRED_TOKENS, type RecallInput, type RecallResult, type RelatedBrokenLink, type RelatedGraphInspection, type RelatedGraphNode, type RelatedHubEntry, type RequirementProfile, type RetiredReferenceHit, type RetiredReferenceInspection, type RetiredToken, type SelectionTokenState, type ShutdownHandlerDeps, type StoreCanonicalEntry, type StoreReachability, type SurfaceVerdict, type UnboundProjectViolation, type WhyNotSurfacedResult, aggregateConsumption, appendEventLedgerEvent, buildAlwaysActiveBodies, buildColdEvalBatch, buildKnowledgeCensus, buildRelatedGraph, bumpCounter, clearPrecheckCache, collectStoreCanonicalEntries, contextCache, createFabricServer, createInFlightTracker, createShutdownHandler, defaultEmbedCacheDir, detectUnboundProject, drainCounters, enrichDescriptions, evaluateStoreDir, explainWhyNotSurfaced, extractKnowledge, findConflictCandidates, flushAndSyncEventLedger, flushMetrics, formatPreexistingRootMessage, getEventLedgerPath, getLedgerPath, getLegacyLedgerPath, getMetricsLedgerPath, inspectConsumption, inspectRelatedGraph, inspectRetiredReferences, isEmbedderResolvable, lintConflicts, loadConflictEntries, loadEmbedder, pairSimilarity, planContext, precheckStoreReachability, readEmbedConfig, readEventLedger, readFusion, readLedger, readMetrics, readSelectionToken, recall, rehydrateAgentsMetaAt, resolveLedgerPaths, reviewKnowledge, reviewPending, runDoctorApplyLint, runDoctorArchiveHistory, runDoctorCiteCoverage, runDoctorConflictLint, runDoctorFix, runDoctorHistoryAll, runDoctorReport, startMetricsFlush, startRotationTick, startStdioServer, stopMetricsFlush, stopRotationTick };