@fenglimg/fabric-server 1.5.1 → 1.6.0
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/{chunk-E3RZ276F.js → chunk-TZCE2K4D.js} +284 -67
- package/dist/{http-BVF4GWIM.js → http-DJCTLGF4.js} +43 -14
- package/dist/index.d.ts +17 -2
- package/dist/index.js +477 -71
- package/dist/static/assets/{index-BRegf31x.js → index-LJh6IezM.js} +7 -7
- package/dist/static/index.html +1 -1
- package/package.json +3 -3
|
@@ -2,21 +2,26 @@ import {
|
|
|
2
2
|
AGENTS_MD_RESOURCE_URI,
|
|
3
3
|
AgentsMetaFileMissingError,
|
|
4
4
|
AgentsMetaInvalidError,
|
|
5
|
+
LEDGER_PATH,
|
|
6
|
+
LEGACY_LEDGER_PATH,
|
|
5
7
|
appendLedgerEntry,
|
|
6
8
|
approveHumanLock,
|
|
7
9
|
contextCache,
|
|
10
|
+
ensureParentDirectory,
|
|
11
|
+
getLedgerPath,
|
|
12
|
+
getLegacyLedgerPath,
|
|
8
13
|
getRules,
|
|
9
14
|
readAgentsMeta,
|
|
10
15
|
readHumanLock,
|
|
11
16
|
readHumanLockEntry,
|
|
12
17
|
readLedger,
|
|
18
|
+
resolveLedgerPaths,
|
|
13
19
|
runDoctorReport
|
|
14
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-TZCE2K4D.js";
|
|
15
21
|
|
|
16
22
|
// src/http.ts
|
|
17
23
|
import { randomUUID } from "crypto";
|
|
18
24
|
import { appendFile, readFile as readFile2 } from "fs/promises";
|
|
19
|
-
import { join as join3 } from "path";
|
|
20
25
|
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
|
|
21
26
|
import {
|
|
22
27
|
StreamableHTTPServerTransport
|
|
@@ -126,8 +131,7 @@ import chokidar from "chokidar";
|
|
|
126
131
|
var AGENTS_META_PATH = ".fabric/agents.meta.json";
|
|
127
132
|
var HUMAN_LOCK_PATH = ".fabric/human-lock.json";
|
|
128
133
|
var FORENSIC_PATH = ".fabric/forensic.json";
|
|
129
|
-
var
|
|
130
|
-
var WATCHED_PATHS = [AGENTS_META_PATH, HUMAN_LOCK_PATH, FORENSIC_PATH, LEDGER_PATH];
|
|
134
|
+
var WATCHED_PATHS = [AGENTS_META_PATH, HUMAN_LOCK_PATH, FORENSIC_PATH, LEDGER_PATH, LEGACY_LEDGER_PATH];
|
|
131
135
|
var CONNECTION_LIMIT = 10;
|
|
132
136
|
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
133
137
|
var WATCH_DEBOUNCE_MS = 75;
|
|
@@ -166,6 +170,7 @@ function createEventsHandler(options) {
|
|
|
166
170
|
const state = {
|
|
167
171
|
clients: /* @__PURE__ */ new Set(),
|
|
168
172
|
pendingTimers: /* @__PURE__ */ new Map(),
|
|
173
|
+
activeLedgerPath: getLedgerPath(projectRoot),
|
|
169
174
|
ledgerOffset: 0,
|
|
170
175
|
ledgerRemainder: "",
|
|
171
176
|
humanLockSnapshot: createEmptyHumanLockSnapshot(),
|
|
@@ -243,7 +248,9 @@ async function ensureWatcher(state, projectRoot) {
|
|
|
243
248
|
if (state.watcher !== void 0) {
|
|
244
249
|
return;
|
|
245
250
|
}
|
|
246
|
-
|
|
251
|
+
const ledgerState = await resolveLedgerWatchState(projectRoot);
|
|
252
|
+
state.activeLedgerPath = ledgerState.path;
|
|
253
|
+
state.ledgerOffset = ledgerState.size;
|
|
247
254
|
state.ledgerRemainder = "";
|
|
248
255
|
state.humanLockSnapshot = await readHumanLockSnapshot(projectRoot);
|
|
249
256
|
const watcher = chokidar.watch([...WATCHED_PATHS], {
|
|
@@ -306,7 +313,7 @@ async function readEventsForFile(state, projectRoot, relativePath) {
|
|
|
306
313
|
const event = await readDriftDetectedEvent(projectRoot);
|
|
307
314
|
return event === null ? [] : [event];
|
|
308
315
|
}
|
|
309
|
-
if (relativePath === LEDGER_PATH) {
|
|
316
|
+
if (relativePath === LEDGER_PATH || relativePath === LEGACY_LEDGER_PATH) {
|
|
310
317
|
return await readLedgerAppendedEvents(state, projectRoot);
|
|
311
318
|
}
|
|
312
319
|
return [];
|
|
@@ -370,8 +377,14 @@ async function readHumanLockEvents(state, projectRoot) {
|
|
|
370
377
|
return events;
|
|
371
378
|
}
|
|
372
379
|
async function readLedgerAppendedEvents(state, projectRoot) {
|
|
373
|
-
const
|
|
374
|
-
const
|
|
380
|
+
const ledgerState = await resolveLedgerWatchState(projectRoot);
|
|
381
|
+
const ledgerPath = ledgerState.path;
|
|
382
|
+
const nextSize = ledgerState.size;
|
|
383
|
+
if (ledgerPath !== state.activeLedgerPath) {
|
|
384
|
+
state.activeLedgerPath = ledgerPath;
|
|
385
|
+
state.ledgerOffset = 0;
|
|
386
|
+
state.ledgerRemainder = "";
|
|
387
|
+
}
|
|
375
388
|
if (nextSize < state.ledgerOffset) {
|
|
376
389
|
state.ledgerOffset = 0;
|
|
377
390
|
state.ledgerRemainder = "";
|
|
@@ -394,6 +407,12 @@ async function readLedgerAppendedEvents(state, projectRoot) {
|
|
|
394
407
|
await handle.close();
|
|
395
408
|
}
|
|
396
409
|
}
|
|
410
|
+
async function resolveLedgerWatchState(projectRoot) {
|
|
411
|
+
const paths = await resolveLedgerPaths(projectRoot);
|
|
412
|
+
const path = paths.usingLegacy ? paths.legacyPath : paths.primaryPath;
|
|
413
|
+
const size = await readFileSize(path);
|
|
414
|
+
return { path, size };
|
|
415
|
+
}
|
|
397
416
|
function parseLedgerAppendedEvent(line) {
|
|
398
417
|
try {
|
|
399
418
|
const parsed = JSON.parse(line);
|
|
@@ -1084,12 +1103,13 @@ function hashToken(token) {
|
|
|
1084
1103
|
|
|
1085
1104
|
// src/http.ts
|
|
1086
1105
|
var DEFAULT_HOST = "127.0.0.1";
|
|
1087
|
-
var LEDGER_FILE = ".intent-ledger.jsonl";
|
|
1088
1106
|
var NOTIFY_DEBOUNCE_MS = 200;
|
|
1089
1107
|
var JsonlEventStore = class {
|
|
1090
|
-
constructor(ledgerPath) {
|
|
1108
|
+
constructor(projectRoot, ledgerPath) {
|
|
1109
|
+
this.projectRoot = projectRoot;
|
|
1091
1110
|
this.ledgerPath = ledgerPath;
|
|
1092
1111
|
}
|
|
1112
|
+
projectRoot;
|
|
1093
1113
|
ledgerPath;
|
|
1094
1114
|
async storeEvent(streamId, message) {
|
|
1095
1115
|
const eventId = randomUUID();
|
|
@@ -1099,6 +1119,7 @@ var JsonlEventStore = class {
|
|
|
1099
1119
|
streamId,
|
|
1100
1120
|
message
|
|
1101
1121
|
};
|
|
1122
|
+
await ensureParentDirectory(this.ledgerPath);
|
|
1102
1123
|
await appendFile(this.ledgerPath, `${JSON.stringify(entry)}
|
|
1103
1124
|
`, "utf8");
|
|
1104
1125
|
return eventId;
|
|
@@ -1131,9 +1152,17 @@ var JsonlEventStore = class {
|
|
|
1131
1152
|
raw = await readFile2(this.ledgerPath, "utf8");
|
|
1132
1153
|
} catch (error) {
|
|
1133
1154
|
if (isNodeError2(error) && error.code === "ENOENT") {
|
|
1134
|
-
|
|
1155
|
+
try {
|
|
1156
|
+
raw = await readFile2(getLegacyLedgerPath(this.projectRoot), "utf8");
|
|
1157
|
+
} catch (legacyError) {
|
|
1158
|
+
if (isNodeError2(legacyError) && legacyError.code === "ENOENT") {
|
|
1159
|
+
return [];
|
|
1160
|
+
}
|
|
1161
|
+
throw legacyError;
|
|
1162
|
+
}
|
|
1163
|
+
} else {
|
|
1164
|
+
throw error;
|
|
1135
1165
|
}
|
|
1136
|
-
throw error;
|
|
1137
1166
|
}
|
|
1138
1167
|
return raw.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => parseStoredMcpEvent(line)).filter((event) => event !== null);
|
|
1139
1168
|
}
|
|
@@ -1141,8 +1170,8 @@ var JsonlEventStore = class {
|
|
|
1141
1170
|
function createFabricHttpApp(options) {
|
|
1142
1171
|
const { projectRoot, host = DEFAULT_HOST, authToken, dashboardDistPath, dev } = options;
|
|
1143
1172
|
const app = createMcpExpressApp({ host });
|
|
1144
|
-
const ledgerPath =
|
|
1145
|
-
const eventStore = new JsonlEventStore(ledgerPath);
|
|
1173
|
+
const ledgerPath = getLedgerPath(projectRoot);
|
|
1174
|
+
const eventStore = new JsonlEventStore(projectRoot, ledgerPath);
|
|
1146
1175
|
const sessions = /* @__PURE__ */ new Map();
|
|
1147
1176
|
process.env.FABRIC_PROJECT_ROOT = projectRoot;
|
|
1148
1177
|
const cacheWatcher = chokidar2.watch(
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,11 @@ import { Server } from 'node:http';
|
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import { AuditMode, LedgerEntry, HumanLockEntry } from '@fenglimg/fabric-shared';
|
|
4
4
|
|
|
5
|
+
declare const LEDGER_PATH = ".fabric/.intent-ledger.jsonl";
|
|
6
|
+
declare const LEGACY_LEDGER_PATH = ".intent-ledger.jsonl";
|
|
7
|
+
declare function getLedgerPath(projectRoot: string): string;
|
|
8
|
+
declare function getLegacyLedgerPath(projectRoot: string): string;
|
|
9
|
+
|
|
5
10
|
type DoctorStatus = "ok" | "warn" | "error";
|
|
6
11
|
type DoctorCheck = {
|
|
7
12
|
name: string;
|
|
@@ -25,6 +30,9 @@ type DoctorSummary = {
|
|
|
25
30
|
lastLedgerEntryTs: number | null;
|
|
26
31
|
lastLedgerEntryAgeMs: number | null;
|
|
27
32
|
metaRevision: string | null;
|
|
33
|
+
ledgerPath: string;
|
|
34
|
+
legacyLedgerPath: string;
|
|
35
|
+
legacyLedgerDetected: boolean;
|
|
28
36
|
audit: {
|
|
29
37
|
enabled: boolean;
|
|
30
38
|
mode: AuditMode;
|
|
@@ -39,11 +47,17 @@ type DoctorReport = {
|
|
|
39
47
|
summary: DoctorSummary;
|
|
40
48
|
audit: DoctorAuditReport | null;
|
|
41
49
|
};
|
|
50
|
+
type DoctorFixReport = {
|
|
51
|
+
changed: boolean;
|
|
52
|
+
migratedLedger: boolean;
|
|
53
|
+
message: string;
|
|
54
|
+
report: DoctorReport;
|
|
55
|
+
};
|
|
42
56
|
type DoctorAuditViolation = {
|
|
43
57
|
editTs: number;
|
|
44
58
|
entryId: string;
|
|
45
59
|
intent: string;
|
|
46
|
-
|
|
60
|
+
lastRuleAccessTs: number | null;
|
|
47
61
|
path: string;
|
|
48
62
|
};
|
|
49
63
|
type DoctorAuditReport = {
|
|
@@ -55,6 +69,7 @@ type DoctorAuditReport = {
|
|
|
55
69
|
violations: DoctorAuditViolation[];
|
|
56
70
|
};
|
|
57
71
|
declare function runDoctorReport(target: string): Promise<DoctorReport>;
|
|
72
|
+
declare function runDoctorFix(target: string): Promise<DoctorFixReport>;
|
|
58
73
|
declare function runDoctorAuditReport(target: string, options?: {
|
|
59
74
|
force?: boolean;
|
|
60
75
|
mode?: AuditMode;
|
|
@@ -102,4 +117,4 @@ declare function startHttpServer(options: {
|
|
|
102
117
|
dev?: boolean;
|
|
103
118
|
}): Promise<Server>;
|
|
104
119
|
|
|
105
|
-
export { AGENTS_MD_RESOURCE_URI, type ApproveHumanLockInput, type ApproveHumanLockResult, type DoctorAuditReport, type DoctorReport, type HumanLockStatus, approveHumanLock, createFabricServer, readHumanLock, readHumanLockEntry, runDoctorAuditReport, runDoctorReport, startHttpServer, startStdioServer };
|
|
120
|
+
export { AGENTS_MD_RESOURCE_URI, type ApproveHumanLockInput, type ApproveHumanLockResult, type DoctorAuditReport, type DoctorFixReport, type DoctorReport, type HumanLockStatus, LEDGER_PATH, LEGACY_LEDGER_PATH, approveHumanLock, createFabricServer, getLedgerPath, getLegacyLedgerPath, readHumanLock, readHumanLockEntry, runDoctorAuditReport, runDoctorFix, runDoctorReport, startHttpServer, startStdioServer };
|