@fenglimg/fabric-server 2.3.0-rc.7 → 2.3.0-rc.9
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.d.ts +1 -38
- package/dist/index.js +15 -84
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -745,36 +745,6 @@ interface RelatedGraphNode {
|
|
|
745
745
|
* id index carries both forms for every node.
|
|
746
746
|
*/
|
|
747
747
|
declare function buildRelatedGraph(nodes: RelatedGraphNode[]): RelatedGraphInspection;
|
|
748
|
-
/** A richer node carrying the text/metadata signals the suggestion heuristic reads. */
|
|
749
|
-
interface RelatedGraphNodeRich {
|
|
750
|
-
/** Store-qualified id (`<alias>:<stableId>`). */
|
|
751
|
-
qualifiedId: string;
|
|
752
|
-
summary: string;
|
|
753
|
-
/** RuleDescription.intent_clues (NOT `keywords` — RuleDescription has no such field). */
|
|
754
|
-
intentClues: string[];
|
|
755
|
-
tags: string[];
|
|
756
|
-
relevancePaths: string[];
|
|
757
|
-
/** Existing declared `related` edges — a pair already connected here is never re-proposed. */
|
|
758
|
-
related: string[];
|
|
759
|
-
}
|
|
760
|
-
/** A proposed related edge: an ordered id pair, a confidence, and the signals that fired. */
|
|
761
|
-
interface SuggestedRelatedEdge {
|
|
762
|
-
source: string;
|
|
763
|
-
target: string;
|
|
764
|
-
confidence: number;
|
|
765
|
-
provenance: string[];
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Propose related edges the corpus is missing. For every unordered pair NOT already
|
|
769
|
-
* connected via existing `related`, score:
|
|
770
|
-
* - token Jaccard over tokenize(summary + intent_clues) — the DOMINANT signal
|
|
771
|
-
* - tag-set intersection — an INDEPENDENT boolean bonus (never folded into tokens)
|
|
772
|
-
* - shared relevance_paths — an INDEPENDENT boolean bonus
|
|
773
|
-
* confidence = jaccard + bonuses, clamped [0,1]. Only pairs >= 0.6 are returned, each
|
|
774
|
-
* with a non-empty provenance[] naming the firing signals. Pure + deterministic
|
|
775
|
-
* (same input → same output; sorted confidence desc, then source, then target).
|
|
776
|
-
*/
|
|
777
|
-
declare function suggestRelatedEdges(nodes: RelatedGraphNodeRich[]): SuggestedRelatedEdge[];
|
|
778
748
|
/**
|
|
779
749
|
* Walk the store canonical corpus and build the related graph. Never throws —
|
|
780
750
|
* collectStoreCanonicalEntries degrades to [] when no store is in the read-set.
|
|
@@ -786,13 +756,6 @@ declare function suggestRelatedEdges(nodes: RelatedGraphNodeRich[]): SuggestedRe
|
|
|
786
756
|
* read `description.related` directly (the single source the recall path uses).
|
|
787
757
|
*/
|
|
788
758
|
declare function inspectRelatedGraph(projectRoot: string): Promise<RelatedGraphInspection>;
|
|
789
|
-
/**
|
|
790
|
-
* Walk the store canonical corpus and PROPOSE the top-N missing related edges via the
|
|
791
|
-
* pure suggestRelatedEdges heuristic. Never throws — collectStoreCanonicalEntries
|
|
792
|
-
* degrades to [] when no store is in the read-set. READ-ONLY: it computes suggestions
|
|
793
|
-
* and writes nothing; edge creation stays on the fabric-review modify path.
|
|
794
|
-
*/
|
|
795
|
-
declare function inspectSuggestedRelatedEdges(projectRoot: string): Promise<SuggestedRelatedEdge[]>;
|
|
796
759
|
|
|
797
760
|
interface StoreReachability {
|
|
798
761
|
uuid: string;
|
|
@@ -1186,4 +1149,4 @@ interface ShutdownHandlerDeps {
|
|
|
1186
1149
|
*/
|
|
1187
1150
|
declare function createShutdownHandler(deps: ShutdownHandlerDeps): () => void;
|
|
1188
1151
|
|
|
1189
|
-
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
|
|
1152
|
+
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 };
|
package/dist/index.js
CHANGED
|
@@ -5421,6 +5421,9 @@ ${content}`;
|
|
|
5421
5421
|
if (patch.relevance_paths !== void 0) updates.relevance_paths = `relevance_paths: ${flowArray(patch.relevance_paths)}`;
|
|
5422
5422
|
if (patch.semantic_scope !== void 0) updates.semantic_scope = `semantic_scope: ${patch.semantic_scope}`;
|
|
5423
5423
|
if (patch.related !== void 0) updates.related = `related: ${flowArray(patch.related)}`;
|
|
5424
|
+
if (patch.must_read_if !== void 0) updates.must_read_if = `must_read_if: ${quoteIfNeeded(patch.must_read_if)}`;
|
|
5425
|
+
if (patch.intent_clues !== void 0) updates.intent_clues = `intent_clues: ${flowArray(patch.intent_clues)}`;
|
|
5426
|
+
if (patch.impact !== void 0) updates.impact = `impact: ${flowArray(patch.impact)}`;
|
|
5424
5427
|
if (patch.status !== void 0) updates.status = `status: ${patch.status}`;
|
|
5425
5428
|
if (patch.deferred_until !== void 0) updates.deferred_until = `deferred_until: ${quoteIfNeeded(patch.deferred_until)}`;
|
|
5426
5429
|
if (patch.last_review_confirmed_at !== void 0) updates.last_review_confirmed_at = `last_review_confirmed_at: ${quoteIfNeeded(patch.last_review_confirmed_at)}`;
|
|
@@ -5458,6 +5461,9 @@ function appendPatchLines(lines, patch) {
|
|
|
5458
5461
|
if (patch.relevance_scope !== void 0) lines.push(`relevance_scope: ${patch.relevance_scope}`);
|
|
5459
5462
|
if (patch.relevance_paths !== void 0) lines.push(`relevance_paths: ${flowArray(patch.relevance_paths)}`);
|
|
5460
5463
|
if (patch.related !== void 0) lines.push(`related: ${flowArray(patch.related)}`);
|
|
5464
|
+
if (patch.must_read_if !== void 0) lines.push(`must_read_if: ${quoteIfNeeded(patch.must_read_if)}`);
|
|
5465
|
+
if (patch.intent_clues !== void 0) lines.push(`intent_clues: ${flowArray(patch.intent_clues)}`);
|
|
5466
|
+
if (patch.impact !== void 0) lines.push(`impact: ${flowArray(patch.impact)}`);
|
|
5461
5467
|
if (patch.status !== void 0) lines.push(`status: ${patch.status}`);
|
|
5462
5468
|
if (patch.deferred_until !== void 0) lines.push(`deferred_until: ${quoteIfNeeded(patch.deferred_until)}`);
|
|
5463
5469
|
if (patch.last_review_confirmed_at !== void 0) lines.push(`last_review_confirmed_at: ${quoteIfNeeded(patch.last_review_confirmed_at)}`);
|
|
@@ -7672,7 +7678,13 @@ async function inspectHooksWired(projectRoot) {
|
|
|
7672
7678
|
const required = [
|
|
7673
7679
|
{ event: "Stop", hookFile: "fabric-hint.cjs" },
|
|
7674
7680
|
{ event: "SessionStart", hookFile: "knowledge-hint-broad.cjs" },
|
|
7675
|
-
|
|
7681
|
+
// ux-w2-6 (rc.9): PreToolUse is the SINGLE merged orchestrator
|
|
7682
|
+
// knowledge-pretooluse.cjs which internally requires knowledge-hint-narrow.cjs
|
|
7683
|
+
// (and cite-policy-evict.cjs) so a single edit produces ONE additionalContext
|
|
7684
|
+
// envelope instead of two. The stale reference to narrow.cjs here was the
|
|
7685
|
+
// rc.30 BUG-M3 false-negative source — narrow.cjs still exists on disk as a
|
|
7686
|
+
// lib but is NOT registered as a PreToolUse hook.
|
|
7687
|
+
{ event: "PreToolUse", hookFile: "knowledge-pretooluse.cjs" }
|
|
7676
7688
|
];
|
|
7677
7689
|
const missing = [];
|
|
7678
7690
|
const hooksSection = isRecord(parsed) ? parsed.hooks : void 0;
|
|
@@ -11087,7 +11099,6 @@ function buildColdEvalBatch(candidates) {
|
|
|
11087
11099
|
}
|
|
11088
11100
|
|
|
11089
11101
|
// src/services/doctor-related-graph.ts
|
|
11090
|
-
import { tokenize as tokenize3 } from "@fenglimg/fabric-shared";
|
|
11091
11102
|
function buildRelatedGraph(nodes) {
|
|
11092
11103
|
const brokenLinks = [];
|
|
11093
11104
|
const inDegree = /* @__PURE__ */ new Map();
|
|
@@ -11128,66 +11139,6 @@ function extractBareStableId(qualifiedId) {
|
|
|
11128
11139
|
}
|
|
11129
11140
|
return null;
|
|
11130
11141
|
}
|
|
11131
|
-
var SUGGEST_CONFIDENCE_THRESHOLD = 0.6;
|
|
11132
|
-
var TAG_OVERLAP_BONUS = 0.15;
|
|
11133
|
-
var PATH_OVERLAP_BONUS = 0.15;
|
|
11134
|
-
function suggestRelatedEdges(nodes) {
|
|
11135
|
-
const pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
11136
|
-
const prepared = nodes.map((node) => ({
|
|
11137
|
-
qualifiedId: node.qualifiedId,
|
|
11138
|
-
bareId: extractBareStableId(node.qualifiedId) ?? node.qualifiedId,
|
|
11139
|
-
tokens: new Set(tokenize3(`${node.summary} ${node.intentClues.join(" ")}`)),
|
|
11140
|
-
tags: new Set(node.tags),
|
|
11141
|
-
paths: new Set(node.relevancePaths)
|
|
11142
|
-
}));
|
|
11143
|
-
const existing = /* @__PURE__ */ new Set();
|
|
11144
|
-
for (const node of nodes) {
|
|
11145
|
-
const aBare = extractBareStableId(node.qualifiedId) ?? node.qualifiedId;
|
|
11146
|
-
for (const rel of node.related) {
|
|
11147
|
-
existing.add(pairKey(aBare, extractBareStableId(rel) ?? rel));
|
|
11148
|
-
}
|
|
11149
|
-
}
|
|
11150
|
-
const out = [];
|
|
11151
|
-
for (let i = 0; i < prepared.length; i++) {
|
|
11152
|
-
for (let j = i + 1; j < prepared.length; j++) {
|
|
11153
|
-
const a = prepared[i];
|
|
11154
|
-
const b = prepared[j];
|
|
11155
|
-
if (a.bareId === b.bareId) continue;
|
|
11156
|
-
if (existing.has(pairKey(a.bareId, b.bareId))) continue;
|
|
11157
|
-
let intersection = 0;
|
|
11158
|
-
for (const t of a.tokens) if (b.tokens.has(t)) intersection++;
|
|
11159
|
-
const union = a.tokens.size + b.tokens.size - intersection;
|
|
11160
|
-
const jaccard = union === 0 ? 0 : intersection / union;
|
|
11161
|
-
let tagOverlap = false;
|
|
11162
|
-
for (const t of a.tags)
|
|
11163
|
-
if (b.tags.has(t)) {
|
|
11164
|
-
tagOverlap = true;
|
|
11165
|
-
break;
|
|
11166
|
-
}
|
|
11167
|
-
let pathOverlap = false;
|
|
11168
|
-
for (const p of a.paths)
|
|
11169
|
-
if (b.paths.has(p)) {
|
|
11170
|
-
pathOverlap = true;
|
|
11171
|
-
break;
|
|
11172
|
-
}
|
|
11173
|
-
let confidence = jaccard;
|
|
11174
|
-
if (tagOverlap) confidence += TAG_OVERLAP_BONUS;
|
|
11175
|
-
if (pathOverlap) confidence += PATH_OVERLAP_BONUS;
|
|
11176
|
-
confidence = Math.min(1, confidence);
|
|
11177
|
-
if (confidence < SUGGEST_CONFIDENCE_THRESHOLD) continue;
|
|
11178
|
-
const provenance = [];
|
|
11179
|
-
if (jaccard > 0) provenance.push("token-jaccard");
|
|
11180
|
-
if (tagOverlap) provenance.push("tag-overlap");
|
|
11181
|
-
if (pathOverlap) provenance.push("shared-path");
|
|
11182
|
-
const [source, target] = a.qualifiedId < b.qualifiedId ? [a.qualifiedId, b.qualifiedId] : [b.qualifiedId, a.qualifiedId];
|
|
11183
|
-
out.push({ source, target, confidence, provenance });
|
|
11184
|
-
}
|
|
11185
|
-
}
|
|
11186
|
-
out.sort(
|
|
11187
|
-
(x, y) => y.confidence - x.confidence || x.source.localeCompare(y.source) || x.target.localeCompare(y.target)
|
|
11188
|
-
);
|
|
11189
|
-
return out;
|
|
11190
|
-
}
|
|
11191
11142
|
async function inspectRelatedGraph(projectRoot) {
|
|
11192
11143
|
const entries = await collectStoreCanonicalEntries(projectRoot);
|
|
11193
11144
|
return buildRelatedGraph(
|
|
@@ -11197,24 +11148,6 @@ async function inspectRelatedGraph(projectRoot) {
|
|
|
11197
11148
|
}))
|
|
11198
11149
|
);
|
|
11199
11150
|
}
|
|
11200
|
-
var SUGGESTED_EDGES_TOP_N = 20;
|
|
11201
|
-
async function inspectSuggestedRelatedEdges(projectRoot) {
|
|
11202
|
-
let entries;
|
|
11203
|
-
try {
|
|
11204
|
-
entries = await collectStoreCanonicalEntries(projectRoot);
|
|
11205
|
-
} catch {
|
|
11206
|
-
return [];
|
|
11207
|
-
}
|
|
11208
|
-
const nodes = entries.map((entry) => ({
|
|
11209
|
-
qualifiedId: entry.qualifiedId,
|
|
11210
|
-
summary: entry.description.summary ?? "",
|
|
11211
|
-
intentClues: entry.description.intent_clues ?? [],
|
|
11212
|
-
tags: entry.description.tags ?? [],
|
|
11213
|
-
relevancePaths: entry.description.relevance_paths ?? [],
|
|
11214
|
-
related: entry.description.related ?? []
|
|
11215
|
-
}));
|
|
11216
|
-
return suggestRelatedEdges(nodes).slice(0, SUGGESTED_EDGES_TOP_N);
|
|
11217
|
-
}
|
|
11218
11151
|
|
|
11219
11152
|
// src/services/store-precheck.ts
|
|
11220
11153
|
import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
|
|
@@ -11696,7 +11629,7 @@ function createFabricServer(tracker) {
|
|
|
11696
11629
|
const server = new McpServer(
|
|
11697
11630
|
{
|
|
11698
11631
|
name: "fabric-knowledge-server",
|
|
11699
|
-
version: "2.3.0-rc.
|
|
11632
|
+
version: "2.3.0-rc.9"
|
|
11700
11633
|
},
|
|
11701
11634
|
{
|
|
11702
11635
|
instructions: FABRIC_SERVER_INSTRUCTIONS
|
|
@@ -11850,7 +11783,6 @@ export {
|
|
|
11850
11783
|
inspectConsumption,
|
|
11851
11784
|
inspectRelatedGraph,
|
|
11852
11785
|
inspectRetiredReferences,
|
|
11853
|
-
inspectSuggestedRelatedEdges,
|
|
11854
11786
|
isEmbedderResolvable,
|
|
11855
11787
|
lintConflicts,
|
|
11856
11788
|
loadConflictEntries,
|
|
@@ -11880,6 +11812,5 @@ export {
|
|
|
11880
11812
|
startRotationTick,
|
|
11881
11813
|
startStdioServer,
|
|
11882
11814
|
stopMetricsFlush,
|
|
11883
|
-
stopRotationTick
|
|
11884
|
-
suggestRelatedEdges
|
|
11815
|
+
stopRotationTick
|
|
11885
11816
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fenglimg/fabric-server",
|
|
3
|
-
"version": "2.3.0-rc.
|
|
3
|
+
"version": "2.3.0-rc.9",
|
|
4
4
|
"description": "Fabric MCP knowledge server — stdio transport for Claude Code / Codex CLI, manages .fabric/ knowledge base + agents.meta.json + event ledger.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "wangzhichao <fenglimg90@gmail.com>",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
38
38
|
"minimatch": "^10.0.1",
|
|
39
39
|
"zod": "^3.25.0",
|
|
40
|
-
"@fenglimg/fabric-shared": "2.3.0-rc.
|
|
40
|
+
"@fenglimg/fabric-shared": "2.3.0-rc.9"
|
|
41
41
|
},
|
|
42
42
|
"optionalDependencies": {
|
|
43
43
|
"fastembed": "^2.0.0"
|