@fenglimg/fabric-server 2.2.0-rc.8 → 2.2.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 +32 -1
- package/dist/index.js +132 -39
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -538,6 +538,37 @@ declare function extractKnowledge(projectRoot: string, input: FabExtractKnowledg
|
|
|
538
538
|
*/
|
|
539
539
|
declare function reviewKnowledge(projectRoot: string, input: FabReviewInput): Promise<FabReviewOutput>;
|
|
540
540
|
|
|
541
|
+
/** A summary to be cold-judged, keyed by its stable_id. */
|
|
542
|
+
interface ColdEvalCandidate {
|
|
543
|
+
stable_id: string;
|
|
544
|
+
summary: string;
|
|
545
|
+
}
|
|
546
|
+
/** The verdict the external cold-eval judge returns per candidate. */
|
|
547
|
+
interface ColdEvalVerdict {
|
|
548
|
+
stable_id: string;
|
|
549
|
+
/** true when the summary alone is act-on sufficient without the body. */
|
|
550
|
+
self_sufficient: boolean;
|
|
551
|
+
/** When not self-sufficient, the judge's suggested act-on rewrite. */
|
|
552
|
+
suggested_summary?: string;
|
|
553
|
+
/** Short rationale (pointer-vs-thesis) for the verdict. */
|
|
554
|
+
reason?: string;
|
|
555
|
+
}
|
|
556
|
+
/** The batch request handed to the external (maestro delegate) cold-eval judge. */
|
|
557
|
+
interface ColdEvalBatch {
|
|
558
|
+
rubric: string;
|
|
559
|
+
candidates: ColdEvalCandidate[];
|
|
560
|
+
}
|
|
561
|
+
declare const COLD_EVAL_RUBRIC: string;
|
|
562
|
+
/**
|
|
563
|
+
* Build the cold-eval batch request for the external judge. Pure + deterministic:
|
|
564
|
+
* drops blank summaries (nothing to judge) and pairs the candidates with the
|
|
565
|
+
* zero-context rubric. The fabric-review skill hands the result to
|
|
566
|
+
* `maestro delegate` and applies the returned {@link ColdEvalVerdict}[] via
|
|
567
|
+
* fab_review modify. Returns a batch with an empty candidate list when nothing is
|
|
568
|
+
* judgeable, so callers can short-circuit without a delegate round-trip.
|
|
569
|
+
*/
|
|
570
|
+
declare function buildColdEvalBatch(candidates: ColdEvalCandidate[]): ColdEvalBatch;
|
|
571
|
+
|
|
541
572
|
type StoredEventLedgerEvent = EventLedgerEvent;
|
|
542
573
|
type ReadEventLedgerOptions = {
|
|
543
574
|
event_type?: EventLedgerEvent["event_type"];
|
|
@@ -823,4 +854,4 @@ interface ShutdownHandlerDeps {
|
|
|
823
854
|
*/
|
|
824
855
|
declare function createShutdownHandler(deps: ShutdownHandlerDeps): () => void;
|
|
825
856
|
|
|
826
|
-
export { AGENTS_MD_RESOURCE_URI, type AlwaysActiveBody, type ArchiveHistoryEntry, type ArchiveHistoryReport, type CiteCoverageReport, 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, type PlanContextInput, type PlanContextResult, type RecallInput, type RecallResult, type RequirementProfile, type SelectionTokenState, type ShutdownHandlerDeps, type UnboundProjectViolation, appendEventLedgerEvent, buildAlwaysActiveBodies, buildKnowledgeCensus, bumpCounter, contextCache, createFabricServer, createInFlightTracker, createShutdownHandler, detectUnboundProject, drainCounters, enrichDescriptions, extractKnowledge, findConflictCandidates, flushAndSyncEventLedger, flushMetrics, formatPreexistingRootMessage, getEventLedgerPath, getLedgerPath, getLegacyLedgerPath, getMetricsLedgerPath, lintConflicts, loadConflictEntries, pairSimilarity, planContext, readEventLedger, readLedger, readMetrics, readSelectionToken, recall, rehydrateAgentsMetaAt, resolveLedgerPaths, reviewKnowledge, runDoctorApplyLint, runDoctorArchiveHistory, runDoctorCiteCoverage, runDoctorConflictLint, runDoctorFix, runDoctorHistoryAll, runDoctorReport, startMetricsFlush, startRotationTick, startStdioServer, stopMetricsFlush, stopRotationTick };
|
|
857
|
+
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, type PlanContextInput, type PlanContextResult, type RecallInput, type RecallResult, type RequirementProfile, type SelectionTokenState, type ShutdownHandlerDeps, type UnboundProjectViolation, appendEventLedgerEvent, buildAlwaysActiveBodies, buildColdEvalBatch, buildKnowledgeCensus, bumpCounter, contextCache, createFabricServer, createInFlightTracker, createShutdownHandler, detectUnboundProject, drainCounters, enrichDescriptions, extractKnowledge, findConflictCandidates, flushAndSyncEventLedger, flushMetrics, formatPreexistingRootMessage, getEventLedgerPath, getLedgerPath, getLegacyLedgerPath, getMetricsLedgerPath, lintConflicts, loadConflictEntries, pairSimilarity, planContext, readEventLedger, readLedger, readMetrics, readSelectionToken, recall, rehydrateAgentsMetaAt, resolveLedgerPaths, reviewKnowledge, runDoctorApplyLint, runDoctorArchiveHistory, runDoctorCiteCoverage, runDoctorConflictLint, runDoctorFix, runDoctorHistoryAll, runDoctorReport, startMetricsFlush, startRotationTick, startStdioServer, stopMetricsFlush, stopRotationTick };
|
package/dist/index.js
CHANGED
|
@@ -700,13 +700,9 @@ function appendPayloadWarning(warnings, guardResult, actionHint) {
|
|
|
700
700
|
// src/config-loader.ts
|
|
701
701
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
702
702
|
import { join as join4 } from "path";
|
|
703
|
-
import { selectionTokenTtlMsSchema, planContextTopKSchema
|
|
704
|
-
var RETRIEVAL_BUDGET_PROFILES = ["conservative", "balanced", "generous"];
|
|
705
|
-
function readRetrievalBudgetProfile(config) {
|
|
706
|
-
const raw = config.retrieval_budget_profile;
|
|
707
|
-
return typeof raw === "string" && RETRIEVAL_BUDGET_PROFILES.includes(raw) ? raw : void 0;
|
|
708
|
-
}
|
|
703
|
+
import { selectionTokenTtlMsSchema, planContextTopKSchema } from "@fenglimg/fabric-shared";
|
|
709
704
|
var PLAN_CONTEXT_TOP_K_DEFAULT = 24;
|
|
705
|
+
var RECALL_RELEVANCE_RATIO_DEFAULT = 0.25;
|
|
710
706
|
function readFabricConfig(projectRoot) {
|
|
711
707
|
const configPath = join4(projectRoot, ".fabric", "fabric-config.json");
|
|
712
708
|
if (!existsSync2(configPath)) {
|
|
@@ -719,18 +715,7 @@ function readFabricConfig(projectRoot) {
|
|
|
719
715
|
return parsed;
|
|
720
716
|
}
|
|
721
717
|
function readPayloadLimits(projectRoot) {
|
|
722
|
-
|
|
723
|
-
const explicit = config.mcpPayloadLimits;
|
|
724
|
-
const profile = readRetrievalBudgetProfile(config);
|
|
725
|
-
if (profile === void 0 && explicit === void 0) {
|
|
726
|
-
return void 0;
|
|
727
|
-
}
|
|
728
|
-
const resolved = resolveRetrievalBudget({
|
|
729
|
-
profile,
|
|
730
|
-
payloadWarnBytes: explicit?.warnBytes,
|
|
731
|
-
payloadHardBytes: explicit?.hardBytes
|
|
732
|
-
});
|
|
733
|
-
return { warnBytes: resolved.payloadWarnBytes, hardBytes: resolved.payloadHardBytes };
|
|
718
|
+
return readFabricConfig(projectRoot).mcpPayloadLimits;
|
|
734
719
|
}
|
|
735
720
|
function readSelectionTokenTtlMs(projectRoot) {
|
|
736
721
|
try {
|
|
@@ -776,17 +761,27 @@ function readDefaultLayerFilter(projectRoot) {
|
|
|
776
761
|
}
|
|
777
762
|
function readPlanContextTopK(projectRoot) {
|
|
778
763
|
try {
|
|
779
|
-
const
|
|
780
|
-
const raw = config.plan_context_top_k;
|
|
764
|
+
const raw = readFabricConfig(projectRoot).plan_context_top_k;
|
|
781
765
|
if (raw !== void 0) {
|
|
782
766
|
const parsed = planContextTopKSchema.safeParse(raw);
|
|
783
767
|
if (parsed.success) return parsed.data;
|
|
784
768
|
}
|
|
785
|
-
return
|
|
769
|
+
return PLAN_CONTEXT_TOP_K_DEFAULT;
|
|
786
770
|
} catch {
|
|
787
771
|
return PLAN_CONTEXT_TOP_K_DEFAULT;
|
|
788
772
|
}
|
|
789
773
|
}
|
|
774
|
+
function readRecallRelevanceRatio(projectRoot) {
|
|
775
|
+
try {
|
|
776
|
+
const raw = readFabricConfig(projectRoot).recall_relevance_ratio;
|
|
777
|
+
if (typeof raw === "number" && Number.isFinite(raw) && raw >= 0 && raw <= 1) {
|
|
778
|
+
return raw;
|
|
779
|
+
}
|
|
780
|
+
return RECALL_RELEVANCE_RATIO_DEFAULT;
|
|
781
|
+
} catch {
|
|
782
|
+
return RECALL_RELEVANCE_RATIO_DEFAULT;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
790
785
|
function readOrphanDemoteThresholdDays(projectRoot) {
|
|
791
786
|
try {
|
|
792
787
|
const cfg = readFabricConfig(projectRoot);
|
|
@@ -2643,11 +2638,23 @@ async function planContext(projectRoot, input) {
|
|
|
2643
2638
|
scoringContext.vectorWeight = embedConfig.weight;
|
|
2644
2639
|
}
|
|
2645
2640
|
}
|
|
2646
|
-
const
|
|
2647
|
-
const
|
|
2641
|
+
const scoredSorted = sortDescriptionItems(rawItems, scoringContext);
|
|
2642
|
+
const seenStableIds = /* @__PURE__ */ new Set();
|
|
2643
|
+
const rankedScored = scoredSorted.filter(({ item }) => {
|
|
2644
|
+
if (seenStableIds.has(item.stable_id)) return false;
|
|
2645
|
+
seenStableIds.add(item.stable_id);
|
|
2646
|
+
return true;
|
|
2647
|
+
});
|
|
2648
|
+
const rankedCandidates = rankedScored.map((entry) => entry.item);
|
|
2648
2649
|
const topK = readPlanContextTopK(projectRoot);
|
|
2649
|
-
const
|
|
2650
|
-
const
|
|
2650
|
+
const cappedScored = rankedScored.slice(0, topK);
|
|
2651
|
+
const relevanceRatio = readRecallRelevanceRatio(projectRoot);
|
|
2652
|
+
const hasQuery = scoringContext.queryTerms.length > 0;
|
|
2653
|
+
const maxScore = rankedScored.length > 0 ? rankedScored[0].score : 0;
|
|
2654
|
+
const relevanceFloor = maxScore * relevanceRatio;
|
|
2655
|
+
const survivingScored = hasQuery && maxScore > 0 && relevanceRatio > 0 ? cappedScored.filter((entry) => entry.score >= relevanceFloor) : cappedScored;
|
|
2656
|
+
const topKCandidates = survivingScored.map((entry) => entry.item);
|
|
2657
|
+
const omittedCandidateCount = Math.max(0, rankedCandidates.length - topKCandidates.length);
|
|
2651
2658
|
let candidates = topKCandidates;
|
|
2652
2659
|
const relatedAppended = {};
|
|
2653
2660
|
if (input.include_related === true) {
|
|
@@ -2889,7 +2896,7 @@ function compareScopeThenId(left, right, scopeRank) {
|
|
|
2889
2896
|
}
|
|
2890
2897
|
function sortDescriptionItems(rawItems, scoringContext) {
|
|
2891
2898
|
if (scoringContext === void 0) {
|
|
2892
|
-
return [...rawItems].sort((left, right) => compareStableIds(left.stable_id, right.stable_id));
|
|
2899
|
+
return [...rawItems].sort((left, right) => compareStableIds(left.stable_id, right.stable_id)).map((item) => ({ item, score: 0 }));
|
|
2893
2900
|
}
|
|
2894
2901
|
const scored = rawItems.map((item) => ({
|
|
2895
2902
|
item,
|
|
@@ -2899,7 +2906,7 @@ function sortDescriptionItems(rawItems, scoringContext) {
|
|
|
2899
2906
|
(left, right) => left.score !== right.score ? right.score - left.score : compareScopeThenId(left.item, right.item, scoringContext.scopeRank)
|
|
2900
2907
|
// W2/A4 scope tie-break
|
|
2901
2908
|
);
|
|
2902
|
-
return scored
|
|
2909
|
+
return scored;
|
|
2903
2910
|
}
|
|
2904
2911
|
function documentTextForItem(description) {
|
|
2905
2912
|
return [
|
|
@@ -2930,16 +2937,6 @@ function buildPreflightDiagnostics(suppressedStableIds) {
|
|
|
2930
2937
|
function dedupeStableIds(stableIds) {
|
|
2931
2938
|
return Array.from(new Set(stableIds));
|
|
2932
2939
|
}
|
|
2933
|
-
function dedupeDescriptionIndex(items) {
|
|
2934
|
-
const seenStableIds = /* @__PURE__ */ new Set();
|
|
2935
|
-
return items.filter((item) => {
|
|
2936
|
-
if (seenStableIds.has(item.stable_id)) {
|
|
2937
|
-
return false;
|
|
2938
|
-
}
|
|
2939
|
-
seenStableIds.add(item.stable_id);
|
|
2940
|
-
return true;
|
|
2941
|
-
});
|
|
2942
|
-
}
|
|
2943
2940
|
var RECENCY_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
2944
2941
|
var RECENCY_BOOST = 25;
|
|
2945
2942
|
var LOCALITY_SAME_FILE = 100;
|
|
@@ -3091,7 +3088,7 @@ function buildNextSteps(planResult, paths, candidateById, candidateLookup) {
|
|
|
3091
3088
|
const omitted = planResult.omitted_candidate_count ?? 0;
|
|
3092
3089
|
if (omitted > 0) {
|
|
3093
3090
|
nextSteps.push(
|
|
3094
|
-
`${omitted} lower-ranked candidate(s) were omitted by the retrieval budget \u2014 pass a narrower intent (or raise plan_context_top_k
|
|
3091
|
+
`${omitted} lower-ranked candidate(s) were omitted by the retrieval budget \u2014 pass a narrower intent (or raise plan_context_top_k) to surface them.`
|
|
3095
3092
|
);
|
|
3096
3093
|
}
|
|
3097
3094
|
const surfacedPaths = new Set(paths.map((p) => p.stable_id));
|
|
@@ -5660,6 +5657,15 @@ async function inspectEventsJsonlGates(projectRoot, options = {}) {
|
|
|
5660
5657
|
import { readdir as readdir2, readFile as readFile9 } from "fs/promises";
|
|
5661
5658
|
import { join as join16, posix as posix2 } from "path";
|
|
5662
5659
|
var FABRIC_SKILL_SLUGS = ["fabric-archive", "fabric-review", "fabric-import"];
|
|
5660
|
+
var ROUTER_VALID_LEAF_SLUGS = /* @__PURE__ */ new Set([
|
|
5661
|
+
"fabric-archive",
|
|
5662
|
+
"fabric-review",
|
|
5663
|
+
"fabric-import",
|
|
5664
|
+
"fabric-sync",
|
|
5665
|
+
"fabric-store",
|
|
5666
|
+
"fabric-audit",
|
|
5667
|
+
"fabric-connect"
|
|
5668
|
+
]);
|
|
5663
5669
|
var SKILL_MD_FRONTMATTER_ROOTS = [".claude/skills", ".codex/skills"];
|
|
5664
5670
|
var SKILL_FRONTMATTER_KEY_PATTERN = /^([A-Za-z_][A-Za-z0-9_-]*):[ \t]+(.+?)[ \t]*$/u;
|
|
5665
5671
|
var SKILL_QUOTED_VALUE_LEADS = /* @__PURE__ */ new Set(['"', "'", "[", "{", ">", "|"]);
|
|
@@ -5844,6 +5850,68 @@ function extractSkillFrontmatterLines(raw) {
|
|
|
5844
5850
|
}
|
|
5845
5851
|
return null;
|
|
5846
5852
|
}
|
|
5853
|
+
function extractMarkdownSectionBody(markdown, sectionName) {
|
|
5854
|
+
const lines = markdown.split(/\r?\n/u);
|
|
5855
|
+
const headingRe = /^(#{2,3})\s+(.+?)\s*$/u;
|
|
5856
|
+
let start = -1;
|
|
5857
|
+
for (let i = 0; i < lines.length; i++) {
|
|
5858
|
+
const h = headingRe.exec(lines[i]);
|
|
5859
|
+
if (h && h[2] === sectionName) {
|
|
5860
|
+
start = i + 1;
|
|
5861
|
+
break;
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
if (start === -1) return null;
|
|
5865
|
+
const out = [];
|
|
5866
|
+
for (let i = start; i < lines.length; i++) {
|
|
5867
|
+
if (headingRe.test(lines[i])) break;
|
|
5868
|
+
out.push(lines[i]);
|
|
5869
|
+
}
|
|
5870
|
+
return out.join("\n");
|
|
5871
|
+
}
|
|
5872
|
+
async function inspectRouterChainRef(projectRoot) {
|
|
5873
|
+
const candidatePaths = [
|
|
5874
|
+
join16(projectRoot, ".claude", "skills", "fabric", "SKILL.md"),
|
|
5875
|
+
join16(projectRoot, ".codex", "skills", "fabric", "SKILL.md")
|
|
5876
|
+
];
|
|
5877
|
+
let body = null;
|
|
5878
|
+
for (const candidate of candidatePaths) {
|
|
5879
|
+
try {
|
|
5880
|
+
body = await readFile9(candidate, "utf8");
|
|
5881
|
+
break;
|
|
5882
|
+
} catch {
|
|
5883
|
+
}
|
|
5884
|
+
}
|
|
5885
|
+
if (body === null) return { status: "ok", unknownRefs: [] };
|
|
5886
|
+
const chainSection = extractMarkdownSectionBody(body, "S_CHAIN");
|
|
5887
|
+
if (chainSection === null) return { status: "ok", unknownRefs: [] };
|
|
5888
|
+
const refs = /* @__PURE__ */ new Set();
|
|
5889
|
+
const tokenRe = /`(fabric-[a-z]+)`/gu;
|
|
5890
|
+
let match;
|
|
5891
|
+
while ((match = tokenRe.exec(chainSection)) !== null) {
|
|
5892
|
+
refs.add(match[1]);
|
|
5893
|
+
}
|
|
5894
|
+
const unknownRefs = [...refs].filter((slug) => !ROUTER_VALID_LEAF_SLUGS.has(slug)).sort();
|
|
5895
|
+
return unknownRefs.length === 0 ? { status: "ok", unknownRefs: [] } : { status: "drift", unknownRefs };
|
|
5896
|
+
}
|
|
5897
|
+
function createRouterChainRefCheck(t, inspection) {
|
|
5898
|
+
if (inspection.status === "ok") {
|
|
5899
|
+
return okCheck(t("doctor.check.router_chain_ref.name"), t("doctor.check.router_chain_ref.ok"));
|
|
5900
|
+
}
|
|
5901
|
+
const count = inspection.unknownRefs.length;
|
|
5902
|
+
return issueCheck(
|
|
5903
|
+
t("doctor.check.router_chain_ref.name"),
|
|
5904
|
+
"warn",
|
|
5905
|
+
"warning",
|
|
5906
|
+
"router_chain_ref_drift",
|
|
5907
|
+
t(`doctor.check.router_chain_ref.message.${count === 1 ? "singular" : "plural"}`, {
|
|
5908
|
+
count: String(count),
|
|
5909
|
+
list: inspection.unknownRefs.join(", ")
|
|
5910
|
+
}),
|
|
5911
|
+
t("doctor.check.router_chain_ref.remediation"),
|
|
5912
|
+
"maintainer"
|
|
5913
|
+
);
|
|
5914
|
+
}
|
|
5847
5915
|
function createSkillRefMirrorCheck(t, inspection) {
|
|
5848
5916
|
if (inspection.status === "ok") {
|
|
5849
5917
|
return okCheck(t("doctor.check.skill_ref_mirror.name"), t("doctor.check.skill_ref_mirror.ok"));
|
|
@@ -7565,6 +7633,7 @@ async function runDoctorReport(target) {
|
|
|
7565
7633
|
const hookCacheWritability = await inspectHookCacheWritability(projectRoot);
|
|
7566
7634
|
const staleServeLock = inspectStaleServeLock(projectRoot, lintNow);
|
|
7567
7635
|
const skillMdYamlInvalid = await inspectSkillMdYamlInvalid(projectRoot);
|
|
7636
|
+
const routerChainRef = await inspectRouterChainRef(projectRoot);
|
|
7568
7637
|
const onboardCoverage = await inspectOnboardCoverage(projectRoot);
|
|
7569
7638
|
const [hooksWired, hooksRuntime, hooksContentDrift] = await Promise.all([
|
|
7570
7639
|
inspectHooksWired(projectRoot),
|
|
@@ -7641,6 +7710,9 @@ async function runDoctorReport(target) {
|
|
|
7641
7710
|
// rc.12 lint #29: skill_md_yaml_invalid. Warning kind — surfaces
|
|
7642
7711
|
// SKILL.md frontmatter that Codex CLI silently drops at load.
|
|
7643
7712
|
createSkillMdYamlInvalidCheck(t, skillMdYamlInvalid),
|
|
7713
|
+
// B2 skill-router (A4): S_CHAIN reference backstop. Warning kind — flags an
|
|
7714
|
+
// S_CHAIN `fabric-*` reference to a leaf no longer in the install set.
|
|
7715
|
+
createRouterChainRefCheck(t, routerChainRef),
|
|
7644
7716
|
// v2.0.0-rc.23 TASK-014 (F8c): Onboard coverage advisory. Info kind.
|
|
7645
7717
|
// Surfaces uncovered S5 onboard slots and recommends /fabric-archive
|
|
7646
7718
|
// first-run phase. Sits adjacent to Skill markdown YAML — both are
|
|
@@ -9340,6 +9412,25 @@ async function runDoctorConflictLint(projectRoot, opts = {}) {
|
|
|
9340
9412
|
};
|
|
9341
9413
|
}
|
|
9342
9414
|
|
|
9415
|
+
// src/services/summary-cold-eval.ts
|
|
9416
|
+
var COLD_EVAL_RUBRIC = [
|
|
9417
|
+
"You are a ZERO-CONTEXT judge. You are shown ONLY a one-line knowledge summary \u2014",
|
|
9418
|
+
"never the full entry body. For each summary decide: could a reader who has NOT",
|
|
9419
|
+
"seen the body ACT on this line alone (apply the decision / avoid the pitfall /",
|
|
9420
|
+
"follow the rule)?",
|
|
9421
|
+
"",
|
|
9422
|
+
"PASS (self_sufficient=true): the line states the thesis \u2014 the what + the",
|
|
9423
|
+
"operative so-what. FAIL (self_sufficient=false): the line only POINTS at the",
|
|
9424
|
+
"body ('explains the approach', 'covers the edge cases') without stating it.",
|
|
9425
|
+
"When you FAIL one, return a suggested_summary that states the thesis in one line."
|
|
9426
|
+
].join("\n");
|
|
9427
|
+
function buildColdEvalBatch(candidates) {
|
|
9428
|
+
const judgeable = candidates.filter(
|
|
9429
|
+
(c) => typeof c.summary === "string" && c.summary.trim().length > 0
|
|
9430
|
+
);
|
|
9431
|
+
return { rubric: COLD_EVAL_RUBRIC, candidates: judgeable };
|
|
9432
|
+
}
|
|
9433
|
+
|
|
9343
9434
|
// src/services/rotation-tick.ts
|
|
9344
9435
|
var DEFAULT_TICK_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
9345
9436
|
var tickTimers = /* @__PURE__ */ new Map();
|
|
@@ -9685,7 +9776,7 @@ function createFabricServer(tracker) {
|
|
|
9685
9776
|
const server = new McpServer(
|
|
9686
9777
|
{
|
|
9687
9778
|
name: "fabric-knowledge-server",
|
|
9688
|
-
version: "2.2.0-rc.
|
|
9779
|
+
version: "2.2.0-rc.9"
|
|
9689
9780
|
},
|
|
9690
9781
|
{
|
|
9691
9782
|
instructions: FABRIC_SERVER_INSTRUCTIONS
|
|
@@ -9797,6 +9888,7 @@ if (isMainModule) {
|
|
|
9797
9888
|
}
|
|
9798
9889
|
export {
|
|
9799
9890
|
AGENTS_MD_RESOURCE_URI,
|
|
9891
|
+
COLD_EVAL_RUBRIC,
|
|
9800
9892
|
DEFAULT_CONFLICT_SIMILARITY_THRESHOLD,
|
|
9801
9893
|
EVENT_LEDGER_PATH,
|
|
9802
9894
|
FABRIC_SERVER_INSTRUCTIONS,
|
|
@@ -9806,6 +9898,7 @@ export {
|
|
|
9806
9898
|
METRIC_COUNTER_NAMES,
|
|
9807
9899
|
appendEventLedgerEvent,
|
|
9808
9900
|
buildAlwaysActiveBodies,
|
|
9901
|
+
buildColdEvalBatch,
|
|
9809
9902
|
buildKnowledgeCensus,
|
|
9810
9903
|
bumpCounter,
|
|
9811
9904
|
contextCache,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fenglimg/fabric-server",
|
|
3
|
-
"version": "2.2.0-rc.
|
|
3
|
+
"version": "2.2.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.2.0-rc.
|
|
40
|
+
"@fenglimg/fabric-shared": "2.2.0-rc.9"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^22.15.0",
|