@fenglimg/fabric-server 1.6.0 → 1.8.0-rc.1
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-E3BHIUIW.js +2903 -0
- package/dist/{http-DJCTLGF4.js → http-MEFXOG3L.js} +348 -278
- package/dist/index.d.ts +187 -61
- package/dist/index.js +329 -681
- package/dist/static/assets/index-C-ba4ih0.js +10 -0
- package/dist/static/assets/index-FoBU5Kta.css +1 -0
- package/dist/static/index.html +9 -7
- package/package.json +10 -4
- package/dist/chunk-TZCE2K4D.js +0 -1447
- package/dist/static/assets/index-B5hhHHl2.css +0 -1
- package/dist/static/assets/index-LJh6IezM.js +0 -14
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,42 @@
|
|
|
1
1
|
import { Server } from 'node:http';
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import {
|
|
3
|
+
import { AgentsMeta, RuleTestIndex, AgentsLayer, AgentsTopologyType } from '@fenglimg/fabric-shared';
|
|
4
|
+
import { IOFabricError } from '@fenglimg/fabric-shared/errors';
|
|
5
|
+
|
|
6
|
+
interface InFlightTracker {
|
|
7
|
+
enter(requestId: string): void;
|
|
8
|
+
exit(requestId: string): void;
|
|
9
|
+
drain(deadlineMs: number): Promise<{
|
|
10
|
+
drained: number;
|
|
11
|
+
timed_out: number;
|
|
12
|
+
}>;
|
|
13
|
+
size(): number;
|
|
14
|
+
}
|
|
15
|
+
declare function createInFlightTracker(): InFlightTracker;
|
|
4
16
|
|
|
5
17
|
declare const LEDGER_PATH = ".fabric/.intent-ledger.jsonl";
|
|
6
18
|
declare const LEGACY_LEDGER_PATH = ".intent-ledger.jsonl";
|
|
19
|
+
declare const EVENT_LEDGER_PATH = ".fabric/events.jsonl";
|
|
7
20
|
declare function getLedgerPath(projectRoot: string): string;
|
|
8
21
|
declare function getLegacyLedgerPath(projectRoot: string): string;
|
|
22
|
+
declare function getEventLedgerPath(projectRoot: string): string;
|
|
9
23
|
|
|
10
24
|
type DoctorStatus = "ok" | "warn" | "error";
|
|
25
|
+
type DoctorIssueKind = "fixable_error" | "manual_error" | "warning" | "info";
|
|
11
26
|
type DoctorCheck = {
|
|
12
27
|
name: string;
|
|
13
28
|
status: DoctorStatus;
|
|
14
29
|
message: string;
|
|
30
|
+
kind?: DoctorIssueKind;
|
|
31
|
+
code?: string;
|
|
32
|
+
fixable?: boolean;
|
|
33
|
+
actionHint?: string;
|
|
34
|
+
};
|
|
35
|
+
type DoctorIssue = {
|
|
36
|
+
code: string;
|
|
37
|
+
name: string;
|
|
38
|
+
message: string;
|
|
39
|
+
path?: string;
|
|
15
40
|
};
|
|
16
41
|
type DoctorSummary = {
|
|
17
42
|
target: string;
|
|
@@ -24,81 +49,53 @@ type DoctorSummary = {
|
|
|
24
49
|
path: string;
|
|
25
50
|
reason: string;
|
|
26
51
|
}>;
|
|
27
|
-
driftCount: number;
|
|
28
|
-
protectedPathCount: number;
|
|
29
|
-
protectedPathsIntact: boolean;
|
|
30
|
-
lastLedgerEntryTs: number | null;
|
|
31
|
-
lastLedgerEntryAgeMs: number | null;
|
|
32
52
|
metaRevision: string | null;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
windowMs: number;
|
|
42
|
-
} | null;
|
|
53
|
+
computedMetaRevision: string | null;
|
|
54
|
+
ruleCount: number;
|
|
55
|
+
eventLedgerPath: string;
|
|
56
|
+
fixableErrorCount: number;
|
|
57
|
+
manualErrorCount: number;
|
|
58
|
+
warningCount: number;
|
|
59
|
+
infoCount: number;
|
|
60
|
+
targetFiles: Record<string, boolean>;
|
|
43
61
|
};
|
|
44
62
|
type DoctorReport = {
|
|
45
63
|
status: DoctorStatus;
|
|
46
64
|
checks: DoctorCheck[];
|
|
65
|
+
fixable_errors: DoctorIssue[];
|
|
66
|
+
manual_errors: DoctorIssue[];
|
|
67
|
+
warnings: DoctorIssue[];
|
|
68
|
+
infos: DoctorIssue[];
|
|
47
69
|
summary: DoctorSummary;
|
|
48
|
-
audit: DoctorAuditReport | null;
|
|
49
70
|
};
|
|
50
71
|
type DoctorFixReport = {
|
|
51
72
|
changed: boolean;
|
|
52
|
-
|
|
73
|
+
fixed: DoctorIssue[];
|
|
74
|
+
remaining_manual_errors: DoctorIssue[];
|
|
75
|
+
warnings: DoctorIssue[];
|
|
53
76
|
message: string;
|
|
54
77
|
report: DoctorReport;
|
|
55
78
|
};
|
|
56
|
-
type DoctorAuditViolation = {
|
|
57
|
-
editTs: number;
|
|
58
|
-
entryId: string;
|
|
59
|
-
intent: string;
|
|
60
|
-
lastRuleAccessTs: number | null;
|
|
61
|
-
path: string;
|
|
62
|
-
};
|
|
63
|
-
type DoctorAuditReport = {
|
|
64
|
-
mode: AuditMode;
|
|
65
|
-
skipped: boolean;
|
|
66
|
-
windowMs: number;
|
|
67
|
-
checkedPathCount: number;
|
|
68
|
-
violationCount: number;
|
|
69
|
-
violations: DoctorAuditViolation[];
|
|
70
|
-
};
|
|
71
79
|
declare function runDoctorReport(target: string): Promise<DoctorReport>;
|
|
72
80
|
declare function runDoctorFix(target: string): Promise<DoctorFixReport>;
|
|
73
|
-
declare function runDoctorAuditReport(target: string, options?: {
|
|
74
|
-
force?: boolean;
|
|
75
|
-
mode?: AuditMode;
|
|
76
|
-
windowMs?: number;
|
|
77
|
-
}): Promise<DoctorAuditReport>;
|
|
78
|
-
|
|
79
|
-
type StoredLedgerEntry = LedgerEntry & {
|
|
80
|
-
id: string;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
type HumanLockStatus = HumanLockEntry & {
|
|
84
|
-
drift: boolean;
|
|
85
|
-
current_hash: string;
|
|
86
|
-
};
|
|
87
|
-
declare function readHumanLock(projectRoot: string): Promise<HumanLockStatus[]>;
|
|
88
|
-
declare function readHumanLockEntry(projectRoot: string, file: string): Promise<HumanLockStatus | null>;
|
|
89
81
|
|
|
90
|
-
type
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
type RuleMetaBuildSource = "doctor_fix" | "sync_meta";
|
|
83
|
+
type RuleMetaBuildResult = {
|
|
84
|
+
meta: AgentsMeta;
|
|
85
|
+
ruleTestIndex: RuleTestIndex;
|
|
86
|
+
changed: boolean;
|
|
95
87
|
};
|
|
96
|
-
type
|
|
97
|
-
|
|
98
|
-
entry: HumanLockStatus;
|
|
99
|
-
ledger_entry?: StoredLedgerEntry;
|
|
88
|
+
type WriteRuleMetaOptions = {
|
|
89
|
+
source: RuleMetaBuildSource;
|
|
100
90
|
};
|
|
101
|
-
declare function
|
|
91
|
+
declare function buildRuleMeta(projectRootInput: string): Promise<RuleMetaBuildResult>;
|
|
92
|
+
declare function writeRuleMeta(projectRootInput: string, options: WriteRuleMetaOptions): Promise<RuleMetaBuildResult>;
|
|
93
|
+
declare function computeRulesBasedAgentsMeta(projectRootInput: string, existingMeta?: AgentsMeta): Promise<AgentsMeta>;
|
|
94
|
+
declare function computeRuleTestIndex(projectRootInput: string, computedMeta: AgentsMeta, previousIndex?: RuleTestIndex): Promise<RuleTestIndex>;
|
|
95
|
+
declare function deriveRuleMetaLayer(relativePath: string): AgentsLayer;
|
|
96
|
+
declare function deriveRuleMetaTopologyType(relativePath: string): AgentsTopologyType;
|
|
97
|
+
declare function isSameRuleTestIndex(left: RuleTestIndex, right: RuleTestIndex): boolean;
|
|
98
|
+
declare function stableStringify(value: unknown): string;
|
|
102
99
|
|
|
103
100
|
/**
|
|
104
101
|
* Shared constants used across the server package.
|
|
@@ -106,8 +103,137 @@ declare function approveHumanLock(projectRoot: string, input: ApproveHumanLockIn
|
|
|
106
103
|
/** MCP resource URI for the project's bootstrap README (L0 rules) file. */
|
|
107
104
|
declare const AGENTS_MD_RESOURCE_URI = "fabric://bootstrap-readme";
|
|
108
105
|
|
|
109
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Synchronously fsync the event ledger file to ensure OS page-cache buffers are
|
|
108
|
+
* flushed to durable storage. Must be called AFTER in-flight drain but BEFORE
|
|
109
|
+
* server.close() — Gemini G1 ordering requirement.
|
|
110
|
+
*
|
|
111
|
+
* Uses sync APIs intentionally: we are inside a signal handler and need
|
|
112
|
+
* guaranteed completion before process.exit().
|
|
113
|
+
*/
|
|
114
|
+
declare function flushAndSyncEventLedger(projectRoot: string): void;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* rule-sync.ts — Rule-sync orchestrator framework (R28, TASK-011)
|
|
118
|
+
*
|
|
119
|
+
* Public surface: ensureRulesFresh, reconcileRules + exported types.
|
|
120
|
+
* Internal helpers are co-located in this file.
|
|
121
|
+
* Does NOT wire any consumers (MCP tools, doctor, watchers).
|
|
122
|
+
*
|
|
123
|
+
* Distinction between the two public entry points:
|
|
124
|
+
*
|
|
125
|
+
* - `ensureRulesFresh`: detects drift, emits ledger events, invalidates cache.
|
|
126
|
+
* Does NOT rewrite agents.meta.json. Optimised for hot-path consumers (MCP tools).
|
|
127
|
+
*
|
|
128
|
+
* - `reconcileRules`: full scan + rewrites agents.meta.json (via rule-meta-builder)
|
|
129
|
+
* + emits ledger events. Used by startup (TASK-022) and doctor repair (TASK-023).
|
|
130
|
+
*/
|
|
131
|
+
interface RuleSyncOptions {
|
|
132
|
+
mode?: "incremental" | "full";
|
|
133
|
+
/** When true, invalid frontmatter throws RuleValidationError (default: false — collect as warning). */
|
|
134
|
+
throwOnInvalidFrontmatter?: boolean;
|
|
135
|
+
}
|
|
136
|
+
interface StructuredWarning {
|
|
137
|
+
code: string;
|
|
138
|
+
file: string;
|
|
139
|
+
line?: number;
|
|
140
|
+
action_hint: string;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Granular ledger event shape for rule-sync operations.
|
|
144
|
+
* These are returned in RuleSyncReport and also appended to the event ledger
|
|
145
|
+
* using the nearest available ledger event type (rule_drift_detected /
|
|
146
|
+
* baseline_synced). The shape below is what callers receive in `.events`.
|
|
147
|
+
*/
|
|
148
|
+
interface RuleSyncLedgerEvent {
|
|
149
|
+
type: "rule_content_changed" | "rule_added" | "rule_removed";
|
|
150
|
+
stable_id: string;
|
|
151
|
+
path: string;
|
|
152
|
+
prev_hash: string | null;
|
|
153
|
+
new_hash: string | null;
|
|
154
|
+
changed_fields: string[];
|
|
155
|
+
source: "ensureRulesFresh" | "reconcileRules";
|
|
156
|
+
}
|
|
157
|
+
/** Alias so the public API says LedgerEvent (as documented). */
|
|
158
|
+
type LedgerEvent = RuleSyncLedgerEvent;
|
|
159
|
+
interface RuleSyncReport {
|
|
160
|
+
status: "fresh" | "reconciled" | "errors";
|
|
161
|
+
events: LedgerEvent[];
|
|
162
|
+
warnings: StructuredWarning[];
|
|
163
|
+
reconciled_files?: string[];
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Detects drift between disk and agents.meta.json, emits ledger events, and
|
|
167
|
+
* invalidates the cache. Does NOT rewrite agents.meta.json. Optimised for
|
|
168
|
+
* hot-path consumers (MCP tools).
|
|
169
|
+
*/
|
|
170
|
+
declare function ensureRulesFresh(projectRoot: string, opts?: RuleSyncOptions): Promise<RuleSyncReport>;
|
|
171
|
+
interface ReconcileRulesOptions {
|
|
172
|
+
/** Identifies who triggered the reconcile; controls which summary ledger event is written. */
|
|
173
|
+
trigger?: "startup" | "doctor" | "manual";
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Full scan + rewrites agents.meta.json with ground-truth disk state + emits
|
|
177
|
+
* ledger events. Used by startup (TASK-022) and doctor repair (TASK-023).
|
|
178
|
+
* Returns reconciled_files listing all paths whose meta was updated.
|
|
179
|
+
*
|
|
180
|
+
* When `opts.trigger` is `'startup'`, a `meta_reconciled_on_startup` summary
|
|
181
|
+
* ledger event is appended after per-file drift events. Other trigger values
|
|
182
|
+
* append a `meta_reconciled` event. Omitting the trigger skips the summary.
|
|
183
|
+
*/
|
|
184
|
+
declare function reconcileRules(projectRoot: string, opts?: ReconcileRulesOptions): Promise<RuleSyncReport>;
|
|
185
|
+
|
|
186
|
+
declare class ServeLockHeldError extends IOFabricError {
|
|
187
|
+
readonly code = "SERVE_LOCK_HELD";
|
|
188
|
+
readonly httpStatus = 423;
|
|
189
|
+
}
|
|
190
|
+
interface LockState {
|
|
191
|
+
pid: number;
|
|
192
|
+
acquiredAt: number;
|
|
193
|
+
host?: string;
|
|
194
|
+
}
|
|
195
|
+
interface AcquireOptions {
|
|
196
|
+
force?: boolean;
|
|
197
|
+
}
|
|
198
|
+
declare function acquireLock(projectRoot: string, opts?: AcquireOptions): void;
|
|
199
|
+
declare function releaseLock(projectRoot: string): void;
|
|
200
|
+
declare function readLockState(projectRoot: string): LockState | null;
|
|
201
|
+
declare function checkLockOrThrow(projectRoot: string, opts?: AcquireOptions): void;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Returns an info-level startup message when CLAUDE.md or AGENTS.md exist at
|
|
205
|
+
* the project root, or null when neither is present.
|
|
206
|
+
*
|
|
207
|
+
* Extracted as a pure helper so unit tests can exercise it without spawning
|
|
208
|
+
* a full server (TASK-034).
|
|
209
|
+
*/
|
|
210
|
+
declare function formatPreexistingRootMessage(projectRoot: string): string | null;
|
|
211
|
+
|
|
212
|
+
declare function createFabricServer(tracker?: InFlightTracker): McpServer;
|
|
110
213
|
declare function startStdioServer(): Promise<void>;
|
|
214
|
+
/**
|
|
215
|
+
* Dependencies for the shutdown handler factory. Tests inject `exit` to assert
|
|
216
|
+
* exit-code behavior without terminating the test process.
|
|
217
|
+
*/
|
|
218
|
+
interface ShutdownHandlerDeps {
|
|
219
|
+
signal: NodeJS.Signals;
|
|
220
|
+
tracker: InFlightTracker;
|
|
221
|
+
projectRoot: string;
|
|
222
|
+
closeServer: () => Promise<void>;
|
|
223
|
+
/** Override for tests; defaults to `process.exit`. */
|
|
224
|
+
exit?: (code: number) => never;
|
|
225
|
+
/** Override for tests; defaults to 5000ms (Gemini G1). */
|
|
226
|
+
drainDeadlineMs?: number;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Builds a same-signal shutdown handler implementing server.md I1:
|
|
230
|
+
* - First invocation: drain in-flight (5s) → fsync ledger → close server → exit(0)
|
|
231
|
+
* - Second invocation of the same signal (while first is in flight): exit(1)
|
|
232
|
+
*
|
|
233
|
+
* Each call to this factory returns an independent handler with its own
|
|
234
|
+
* `invoked` flag, so per-signal dedup is isolated.
|
|
235
|
+
*/
|
|
236
|
+
declare function createShutdownHandler(deps: ShutdownHandlerDeps): () => void;
|
|
111
237
|
declare function startHttpServer(options: {
|
|
112
238
|
port: number;
|
|
113
239
|
projectRoot: string;
|
|
@@ -117,4 +243,4 @@ declare function startHttpServer(options: {
|
|
|
117
243
|
dev?: boolean;
|
|
118
244
|
}): Promise<Server>;
|
|
119
245
|
|
|
120
|
-
export { AGENTS_MD_RESOURCE_URI, type
|
|
246
|
+
export { AGENTS_MD_RESOURCE_URI, type AcquireOptions, type DoctorFixReport, type DoctorIssue, type DoctorReport, EVENT_LEDGER_PATH, type InFlightTracker, LEDGER_PATH, LEGACY_LEDGER_PATH, type LedgerEvent, type LockState, type ReconcileRulesOptions, type RuleMetaBuildResult, type RuleMetaBuildSource, type RuleSyncLedgerEvent, type RuleSyncOptions, type RuleSyncReport, ServeLockHeldError, type ShutdownHandlerDeps, type StructuredWarning, type WriteRuleMetaOptions, acquireLock, buildRuleMeta, checkLockOrThrow, computeRuleTestIndex, computeRulesBasedAgentsMeta, createFabricServer, createInFlightTracker, createShutdownHandler, deriveRuleMetaLayer, deriveRuleMetaTopologyType, ensureRulesFresh, flushAndSyncEventLedger, formatPreexistingRootMessage, getEventLedgerPath, getLedgerPath, getLegacyLedgerPath, isSameRuleTestIndex, readLockState, reconcileRules, releaseLock, runDoctorFix, runDoctorReport, stableStringify, startHttpServer, startStdioServer, writeRuleMeta };
|