@fenglimg/fabric-server 2.0.0-rc.27 → 2.0.0-rc.28

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.
@@ -1753,6 +1753,7 @@ async function runDoctorReport(target) {
1753
1753
  inspectL2ManagedBlockDrift(projectRoot)
1754
1754
  ]);
1755
1755
  const mcpConfigInWrongFile = inspectMcpConfigInWrongFile(projectRoot);
1756
+ const skillRefMirror = inspectSkillRefMirror(projectRoot);
1756
1757
  const metaManuallyDiverged = await inspectMetaManuallyDiverged(projectRoot);
1757
1758
  const knowledgeDirUnindexed = inspectKnowledgeDirUnindexed(projectRoot, meta);
1758
1759
  const knowledgeDirMissing = inspectKnowledgeDirMissing(projectRoot);
@@ -1815,6 +1816,11 @@ async function runDoctorReport(target) {
1815
1816
  // events.jsonl rows that fail Zod validation because of unknown
1816
1817
  // schema_version or event_type tokens. Previously silently dropped.
1817
1818
  createEventLedgerSchemaCompatCheck(t, eventLedger),
1819
+ // v2.0.0-rc.28 TASK-04 (audit §3.1 follow-up): SKILL ref/ mirror parity.
1820
+ // Detects hand-edits or partial install that breaks the byte-identical
1821
+ // contract between .claude/skills/<slug>/ref/ and .codex/skills/<slug>/
1822
+ // ref/. warning severity — fab install restores parity.
1823
+ createSkillRefMirrorCheck(t, skillRefMirror),
1818
1824
  createMcpConfigInWrongFileCheck(t, mcpConfigInWrongFile),
1819
1825
  createMetaManuallyDivergedCheck(t, metaManuallyDiverged),
1820
1826
  createKnowledgeDirUnindexedCheck(t, knowledgeDirUnindexed),
@@ -2616,6 +2622,53 @@ async function inspectEventLedger(projectRoot) {
2616
2622
  };
2617
2623
  }
2618
2624
  }
2625
+ function inspectSkillRefMirror(projectRoot) {
2626
+ const skillSlugs = ["fabric-archive", "fabric-review", "fabric-import"];
2627
+ const driftedPaths = [];
2628
+ for (const slug of skillSlugs) {
2629
+ const claudeRef = join6(projectRoot, ".claude", "skills", slug, "ref");
2630
+ const codexRef = join6(projectRoot, ".codex", "skills", slug, "ref");
2631
+ let claudeFiles = null;
2632
+ let codexFiles = null;
2633
+ try {
2634
+ claudeFiles = readdirSync(claudeRef).filter((n) => n.endsWith(".md"));
2635
+ } catch {
2636
+ }
2637
+ try {
2638
+ codexFiles = readdirSync(codexRef).filter((n) => n.endsWith(".md"));
2639
+ } catch {
2640
+ }
2641
+ if (claudeFiles === null || codexFiles === null) continue;
2642
+ const claudeSet = new Set(claudeFiles);
2643
+ const codexSet = new Set(codexFiles);
2644
+ const union = /* @__PURE__ */ new Set([...claudeFiles, ...codexFiles]);
2645
+ for (const fname of union) {
2646
+ const inClaude = claudeSet.has(fname);
2647
+ const inCodex = codexSet.has(fname);
2648
+ if (!inClaude || !inCodex) {
2649
+ driftedPaths.push(`skills/${slug}/ref/${fname}`);
2650
+ continue;
2651
+ }
2652
+ let claudeBody;
2653
+ let codexBody;
2654
+ try {
2655
+ claudeBody = readFileSync2(join6(claudeRef, fname), "utf8");
2656
+ } catch {
2657
+ continue;
2658
+ }
2659
+ try {
2660
+ codexBody = readFileSync2(join6(codexRef, fname), "utf8");
2661
+ } catch {
2662
+ continue;
2663
+ }
2664
+ if (claudeBody !== codexBody) {
2665
+ driftedPaths.push(`skills/${slug}/ref/${fname}`);
2666
+ }
2667
+ }
2668
+ }
2669
+ if (driftedPaths.length === 0) return { status: "ok" };
2670
+ return { status: "drift", driftedPaths };
2671
+ }
2619
2672
  async function inspectKnowledgeTestIndex(projectRoot) {
2620
2673
  const path2 = join6(projectRoot, ".fabric", ".cache", "knowledge-test.index.json");
2621
2674
  const built = await tryBuildRuleMeta(projectRoot);
@@ -3192,6 +3245,25 @@ function createEventLedgerSchemaCompatCheck(t, ledger) {
3192
3245
  t("doctor.check.event_ledger_schema_compat.remediation")
3193
3246
  );
3194
3247
  }
3248
+ function createSkillRefMirrorCheck(t, inspection) {
3249
+ if (inspection.status === "ok") {
3250
+ return okCheck(
3251
+ t("doctor.check.skill_ref_mirror.name"),
3252
+ t("doctor.check.skill_ref_mirror.ok")
3253
+ );
3254
+ }
3255
+ return issueCheck(
3256
+ t("doctor.check.skill_ref_mirror.name"),
3257
+ "warn",
3258
+ "warning",
3259
+ "skill_ref_mirror_drift",
3260
+ t("doctor.check.skill_ref_mirror.message", {
3261
+ count: String(inspection.driftedPaths.length),
3262
+ list: inspection.driftedPaths.join(", ")
3263
+ }),
3264
+ t("doctor.check.skill_ref_mirror.remediation")
3265
+ );
3266
+ }
3195
3267
  function createEventLedgerPartialWriteCheck(t, ledger) {
3196
3268
  if (!ledger.exists || !ledger.writable) {
3197
3269
  return okCheck(
@@ -14,7 +14,7 @@ import {
14
14
  readEventLedger,
15
15
  runDoctorReport,
16
16
  sha256
17
- } from "./chunk-NZSGNQKE.js";
17
+ } from "./chunk-EEVSGTHG.js";
18
18
 
19
19
  // src/http.ts
20
20
  import { randomUUID as randomUUID2 } from "crypto";
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  sha256,
38
38
  stableStringify,
39
39
  writeKnowledgeMeta
40
- } from "./chunk-NZSGNQKE.js";
40
+ } from "./chunk-EEVSGTHG.js";
41
41
 
42
42
  // src/index.ts
43
43
  import { existsSync as existsSync4 } from "fs";
@@ -2036,7 +2036,7 @@ function formatPreexistingRootMessage(projectRoot) {
2036
2036
  function createFabricServer(tracker) {
2037
2037
  const server = new McpServer({
2038
2038
  name: "fabric-knowledge-server",
2039
- version: "2.0.0-rc.27"
2039
+ version: "2.0.0-rc.28"
2040
2040
  });
2041
2041
  registerPlanContext(server, tracker);
2042
2042
  registerKnowledgeSections(server, tracker);
@@ -2144,7 +2144,7 @@ function createShutdownHandler(deps) {
2144
2144
  };
2145
2145
  }
2146
2146
  async function startHttpServer(options) {
2147
- const { createFabricHttpApp } = await import("./http-3WADEK3O.js");
2147
+ const { createFabricHttpApp } = await import("./http-3IIPL3HQ.js");
2148
2148
  const { port, projectRoot, host = "127.0.0.1", authToken } = options;
2149
2149
  const app = createFabricHttpApp({ projectRoot, host, authToken });
2150
2150
  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.27",
3
+ "version": "2.0.0-rc.28",
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.27"
16
+ "@fenglimg/fabric-shared": "2.0.0-rc.28"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/express": "^5.0.6",