@fenglimg/fabric-server 2.0.0-rc.35 → 2.0.0-rc.36
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.
|
@@ -1741,6 +1741,7 @@ var HINT_SILENCE_COUNTER_FILE_REL = posix.join(
|
|
|
1741
1741
|
var MS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
1742
1742
|
var MATURITY_LINE_PATTERN = /^maturity:\s*("?)(stable|endorsed|draft)\1\s*$/mu;
|
|
1743
1743
|
var CREATED_AT_LINE_PATTERN = /^created_at:\s*("?)([^"\n]+)\1\s*$/mu;
|
|
1744
|
+
var TAGS_LINE_PATTERN = /^tags:\s*\[(.*)\]\s*$/mu;
|
|
1744
1745
|
var RELEVANCE_SCOPE_LINE_PATTERN = /^relevance_scope:\s*("?)(narrow|broad)\1\s*$/mu;
|
|
1745
1746
|
var RELEVANCE_PATHS_LINE_PATTERN = /^relevance_paths:\s*\[([^\]]*)\]\s*$/mu;
|
|
1746
1747
|
var RELEVANCE_PATHS_DRIFT_WINDOW_DAYS = 90;
|
|
@@ -1830,6 +1831,8 @@ async function runDoctorReport(target) {
|
|
|
1830
1831
|
const skillDescription = inspectSkillDescription(projectRoot);
|
|
1831
1832
|
const citeGoodhart = await inspectCiteGoodhart(projectRoot);
|
|
1832
1833
|
const draftBacklog = inspectDraftBacklog(projectRoot);
|
|
1834
|
+
const knowledgeTagsEmpty = inspectKnowledgeTagsEmpty(projectRoot);
|
|
1835
|
+
const driftUnconsumed = await inspectDriftUnconsumed(projectRoot);
|
|
1833
1836
|
const metaManuallyDiverged = await inspectMetaManuallyDiverged(projectRoot);
|
|
1834
1837
|
const knowledgeDirUnindexed = inspectKnowledgeDirUnindexed(projectRoot, meta);
|
|
1835
1838
|
const knowledgeDirMissing = inspectKnowledgeDirMissing(projectRoot);
|
|
@@ -1904,6 +1907,8 @@ async function runDoctorReport(target) {
|
|
|
1904
1907
|
createSkillDescriptionCheck(t, skillDescription),
|
|
1905
1908
|
createCiteGoodhartCheck(t, citeGoodhart),
|
|
1906
1909
|
createDraftBacklogCheck(t, draftBacklog),
|
|
1910
|
+
createKnowledgeTagsEmptyCheck(t, knowledgeTagsEmpty),
|
|
1911
|
+
createDriftUnconsumedCheck(t, driftUnconsumed),
|
|
1907
1912
|
createMcpConfigInWrongFileCheck(t, mcpConfigInWrongFile),
|
|
1908
1913
|
createMetaManuallyDivergedCheck(t, metaManuallyDiverged),
|
|
1909
1914
|
createKnowledgeDirUnindexedCheck(t, knowledgeDirUnindexed),
|
|
@@ -2980,6 +2985,35 @@ function inspectDraftBacklog(projectRoot) {
|
|
|
2980
2985
|
ratio
|
|
2981
2986
|
};
|
|
2982
2987
|
}
|
|
2988
|
+
function inspectKnowledgeTagsEmpty(projectRoot) {
|
|
2989
|
+
const EMPTY_TAGS_RATIO_THRESHOLD = 0.5;
|
|
2990
|
+
const MIN_TOTAL_FOR_RATIO = 10;
|
|
2991
|
+
let emptyCount = 0;
|
|
2992
|
+
let totalCount = 0;
|
|
2993
|
+
for (const entry of iterateCanonicalEntries(projectRoot, /* @__PURE__ */ new Map())) {
|
|
2994
|
+
let source;
|
|
2995
|
+
try {
|
|
2996
|
+
source = readFileSync3(entry.absPath, "utf8");
|
|
2997
|
+
} catch {
|
|
2998
|
+
continue;
|
|
2999
|
+
}
|
|
3000
|
+
const isEmpty = isKnowledgeFrontmatterTagsEmpty(source);
|
|
3001
|
+
if (isEmpty === null || isEmpty === true) {
|
|
3002
|
+
emptyCount += 1;
|
|
3003
|
+
}
|
|
3004
|
+
totalCount += 1;
|
|
3005
|
+
}
|
|
3006
|
+
if (totalCount < MIN_TOTAL_FOR_RATIO) {
|
|
3007
|
+
return { status: "ok", emptyCount, totalCount, ratio: 0 };
|
|
3008
|
+
}
|
|
3009
|
+
const ratio = emptyCount / totalCount;
|
|
3010
|
+
return {
|
|
3011
|
+
status: ratio > EMPTY_TAGS_RATIO_THRESHOLD ? "warn" : "ok",
|
|
3012
|
+
emptyCount,
|
|
3013
|
+
totalCount,
|
|
3014
|
+
ratio
|
|
3015
|
+
};
|
|
3016
|
+
}
|
|
2983
3017
|
async function inspectKnowledgeTestIndex(projectRoot) {
|
|
2984
3018
|
const path2 = join7(projectRoot, ".fabric", ".cache", "knowledge-test.index.json");
|
|
2985
3019
|
const built = await tryBuildRuleMeta(projectRoot);
|
|
@@ -3395,15 +3429,15 @@ function createMetaCheck(t, meta, globalCli) {
|
|
|
3395
3429
|
);
|
|
3396
3430
|
}
|
|
3397
3431
|
if (meta.stale) {
|
|
3432
|
+
const revision = meta.revision;
|
|
3433
|
+
const computedRevision = meta.computedRevision ?? "<unknown>";
|
|
3434
|
+
const messageKey = revision !== null && revision === meta.computedRevision ? "doctor.check.agents_meta.message.stale_hash_equal" : "doctor.check.agents_meta.message.stale";
|
|
3398
3435
|
return issueCheck(
|
|
3399
3436
|
t("doctor.check.agents_meta.name"),
|
|
3400
3437
|
"warn",
|
|
3401
3438
|
"warning",
|
|
3402
3439
|
"agents_meta_stale",
|
|
3403
|
-
t(
|
|
3404
|
-
revision: meta.revision,
|
|
3405
|
-
computedRevision: meta.computedRevision ?? "<unknown>"
|
|
3406
|
-
}),
|
|
3440
|
+
t(messageKey, { revision, computedRevision }),
|
|
3407
3441
|
t("doctor.check.agents_meta.remediation.stale")
|
|
3408
3442
|
);
|
|
3409
3443
|
}
|
|
@@ -3645,6 +3679,71 @@ function createDraftBacklogCheck(t, inspection) {
|
|
|
3645
3679
|
t("doctor.check.draft_backlog.remediation")
|
|
3646
3680
|
);
|
|
3647
3681
|
}
|
|
3682
|
+
async function inspectDriftUnconsumed(projectRoot) {
|
|
3683
|
+
const WINDOW_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
3684
|
+
const MIN_DRIFT_FOR_WARN = 5;
|
|
3685
|
+
const cutoffMs = Date.now() - WINDOW_MS;
|
|
3686
|
+
let events = [];
|
|
3687
|
+
try {
|
|
3688
|
+
const result = await readEventLedger(projectRoot);
|
|
3689
|
+
events = result.events;
|
|
3690
|
+
} catch {
|
|
3691
|
+
return { status: "ok", driftCount: 0, demoteCount: 0 };
|
|
3692
|
+
}
|
|
3693
|
+
let driftCount = 0;
|
|
3694
|
+
let demoteCount = 0;
|
|
3695
|
+
for (const e of events) {
|
|
3696
|
+
if (e.ts < cutoffMs) continue;
|
|
3697
|
+
if (e.event_type === "knowledge_drift_detected") driftCount += 1;
|
|
3698
|
+
else if (e.event_type === "knowledge_demoted") demoteCount += 1;
|
|
3699
|
+
}
|
|
3700
|
+
const unconsumed = driftCount - demoteCount;
|
|
3701
|
+
return {
|
|
3702
|
+
status: unconsumed >= MIN_DRIFT_FOR_WARN ? "warn" : "ok",
|
|
3703
|
+
driftCount,
|
|
3704
|
+
demoteCount
|
|
3705
|
+
};
|
|
3706
|
+
}
|
|
3707
|
+
function createDriftUnconsumedCheck(t, inspection) {
|
|
3708
|
+
if (inspection.status === "ok") {
|
|
3709
|
+
return okCheck(
|
|
3710
|
+
t("doctor.check.drift_unconsumed.name"),
|
|
3711
|
+
t("doctor.check.drift_unconsumed.ok")
|
|
3712
|
+
);
|
|
3713
|
+
}
|
|
3714
|
+
return issueCheck(
|
|
3715
|
+
t("doctor.check.drift_unconsumed.name"),
|
|
3716
|
+
"warn",
|
|
3717
|
+
"warning",
|
|
3718
|
+
"knowledge_drift_unconsumed",
|
|
3719
|
+
t("doctor.check.drift_unconsumed.message", {
|
|
3720
|
+
driftCount: String(inspection.driftCount),
|
|
3721
|
+
demoteCount: String(inspection.demoteCount)
|
|
3722
|
+
}),
|
|
3723
|
+
t("doctor.check.drift_unconsumed.remediation")
|
|
3724
|
+
);
|
|
3725
|
+
}
|
|
3726
|
+
function createKnowledgeTagsEmptyCheck(t, inspection) {
|
|
3727
|
+
if (inspection.status === "ok") {
|
|
3728
|
+
return okCheck(
|
|
3729
|
+
t("doctor.check.knowledge_tags_empty.name"),
|
|
3730
|
+
t("doctor.check.knowledge_tags_empty.ok")
|
|
3731
|
+
);
|
|
3732
|
+
}
|
|
3733
|
+
const pct = Math.round(inspection.ratio * 100);
|
|
3734
|
+
return issueCheck(
|
|
3735
|
+
t("doctor.check.knowledge_tags_empty.name"),
|
|
3736
|
+
"warn",
|
|
3737
|
+
"warning",
|
|
3738
|
+
"knowledge_tags_empty_ratio",
|
|
3739
|
+
t("doctor.check.knowledge_tags_empty.message", {
|
|
3740
|
+
emptyCount: String(inspection.emptyCount),
|
|
3741
|
+
totalCount: String(inspection.totalCount),
|
|
3742
|
+
pct: String(pct)
|
|
3743
|
+
}),
|
|
3744
|
+
t("doctor.check.knowledge_tags_empty.remediation")
|
|
3745
|
+
);
|
|
3746
|
+
}
|
|
3648
3747
|
function createCiteGoodhartCheck(t, inspection) {
|
|
3649
3748
|
if (inspection.status === "ok") {
|
|
3650
3749
|
return okCheck(
|
|
@@ -4565,6 +4664,19 @@ function extractKnowledgeFrontmatterMaturity(source) {
|
|
|
4565
4664
|
const match = MATURITY_LINE_PATTERN.exec(fm[1]);
|
|
4566
4665
|
return match === null ? null : match[2];
|
|
4567
4666
|
}
|
|
4667
|
+
function isKnowledgeFrontmatterTagsEmpty(source) {
|
|
4668
|
+
const FM_PATTERN = /^(?:)?---\r?\n([\s\S]*?)\r?\n---/u;
|
|
4669
|
+
const fm = FM_PATTERN.exec(source);
|
|
4670
|
+
if (fm === null) {
|
|
4671
|
+
return null;
|
|
4672
|
+
}
|
|
4673
|
+
const match = TAGS_LINE_PATTERN.exec(fm[1]);
|
|
4674
|
+
if (match === null) {
|
|
4675
|
+
return null;
|
|
4676
|
+
}
|
|
4677
|
+
const inner = match[1].replace(/[\s,]/g, "");
|
|
4678
|
+
return inner === "";
|
|
4679
|
+
}
|
|
4568
4680
|
function extractKnowledgeFrontmatterCreatedAt(source) {
|
|
4569
4681
|
const FM_PATTERN = /^(?:\uFEFF)?---\r?\n([\s\S]*?)\r?\n---/u;
|
|
4570
4682
|
const fm = FM_PATTERN.exec(source);
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
sha256,
|
|
40
40
|
stableStringify,
|
|
41
41
|
writeKnowledgeMeta
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-5XXH2VZZ.js";
|
|
43
43
|
|
|
44
44
|
// src/index.ts
|
|
45
45
|
import { existsSync as existsSync3 } from "fs";
|
|
@@ -2091,7 +2091,7 @@ function formatPreexistingRootMessage(projectRoot) {
|
|
|
2091
2091
|
function createFabricServer(tracker) {
|
|
2092
2092
|
const server = new McpServer({
|
|
2093
2093
|
name: "fabric-knowledge-server",
|
|
2094
|
-
version: "2.0.0-rc.
|
|
2094
|
+
version: "2.0.0-rc.36"
|
|
2095
2095
|
});
|
|
2096
2096
|
registerPlanContext(server, tracker);
|
|
2097
2097
|
registerKnowledgeSections(server, tracker);
|
|
@@ -2199,7 +2199,7 @@ function createShutdownHandler(deps) {
|
|
|
2199
2199
|
};
|
|
2200
2200
|
}
|
|
2201
2201
|
async function startHttpServer(options) {
|
|
2202
|
-
const { createFabricHttpApp } = await import("./http-
|
|
2202
|
+
const { createFabricHttpApp } = await import("./http-ZRVOXE6C.js");
|
|
2203
2203
|
const { port, projectRoot, host = "127.0.0.1", authToken, allowLoopbackNoAuth } = options;
|
|
2204
2204
|
const app = createFabricHttpApp({ projectRoot, host, authToken, allowLoopbackNoAuth });
|
|
2205
2205
|
return await new Promise((resolveServer, rejectServer) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fenglimg/fabric-server",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.36",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"express": "^5.2.1",
|
|
14
14
|
"minimatch": "^10.0.1",
|
|
15
15
|
"zod": "^3.25.0",
|
|
16
|
-
"@fenglimg/fabric-shared": "2.0.0-rc.
|
|
16
|
+
"@fenglimg/fabric-shared": "2.0.0-rc.36"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/express": "^5.0.6",
|