open-multi-agent-kit 0.78.6 → 0.78.7

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.
Files changed (169) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +26 -0
  3. package/MATURITY.md +2 -2
  4. package/README.md +19 -4
  5. package/dist/brand/night-city.theme.json +80 -0
  6. package/dist/brand/palette.d.ts +73 -177
  7. package/dist/brand/palette.js +115 -39
  8. package/dist/brand/rust-forge.theme.json +216 -0
  9. package/dist/brand/theme-compiled.d.ts +61 -0
  10. package/dist/brand/theme-compiled.js +241 -0
  11. package/dist/brand/theme.js +50 -37
  12. package/dist/cli/release-promotion-gate.d.ts +8 -1
  13. package/dist/cli/release-promotion-gate.js +20 -9
  14. package/dist/cli/root.d.ts +1 -0
  15. package/dist/cli/root.js +2 -1
  16. package/dist/cli/theme/index.d.ts +11 -2
  17. package/dist/cli/theme/index.js +6 -1
  18. package/dist/cli/theme/oklab-quantize.d.ts +29 -0
  19. package/dist/cli/theme/oklab-quantize.js +105 -0
  20. package/dist/cli/theme/render-table.d.ts +59 -0
  21. package/dist/cli/theme/render-table.js +112 -0
  22. package/dist/cli/theme/status-frame.d.ts +10 -0
  23. package/dist/cli/theme/status-frame.js +22 -0
  24. package/dist/cli/theme/terminal-capability.d.ts +6 -1
  25. package/dist/cli/theme/terminal-capability.js +20 -4
  26. package/dist/cli/theme/theme-doc.d.ts +22 -0
  27. package/dist/cli/theme/theme-doc.js +97 -0
  28. package/dist/cli/theme/theme-registry.js +39 -18
  29. package/dist/cli/theme/tier-explain.d.ts +21 -0
  30. package/dist/cli/theme/tier-explain.js +60 -0
  31. package/dist/cli/ui/green-rain-renderer.js +3 -2
  32. package/dist/cli/ui/neon-grid-renderer.js +4 -3
  33. package/dist/cli/ui/rust-forge-renderer.js +17 -3
  34. package/dist/cli/ui/system24-renderer.d.ts +18 -1
  35. package/dist/cli/ui/system24-renderer.js +39 -16
  36. package/dist/cli/v2/chat-repl.js +3 -1
  37. package/dist/cli/v2/cli-v2-skeleton.d.ts +6 -0
  38. package/dist/cli/v2/cli-v2-skeleton.js +121 -9
  39. package/dist/cli/v2/interactive-prompt.d.ts +1 -0
  40. package/dist/cli/v2/interactive-prompt.js +6 -2
  41. package/dist/commands/chat/core.js +2 -2
  42. package/dist/commands/chat/runtime.js +2 -0
  43. package/dist/commands/chat/utils.js +12 -4
  44. package/dist/commands/cockpit/render.js +102 -64
  45. package/dist/commands/cockpit/utils.d.ts +2 -0
  46. package/dist/commands/design.js +18 -16
  47. package/dist/commands/doctor/checks.d.ts +0 -1
  48. package/dist/commands/doctor/checks.js +1 -36
  49. package/dist/commands/doctor/report.js +0 -11
  50. package/dist/commands/init/content.d.ts +1 -1
  51. package/dist/commands/init/content.js +3 -11
  52. package/dist/commands/init.js +2 -2
  53. package/dist/commands/mcp/config.d.ts +32 -0
  54. package/dist/commands/mcp/config.js +264 -0
  55. package/dist/commands/mcp/doctor-fix.d.ts +12 -0
  56. package/dist/commands/mcp/doctor-fix.js +261 -0
  57. package/dist/commands/mcp/doctor.d.ts +55 -0
  58. package/dist/commands/mcp/doctor.js +401 -0
  59. package/dist/commands/mcp/list.d.ts +1 -0
  60. package/dist/commands/mcp/list.js +56 -0
  61. package/dist/commands/mcp/shared.d.ts +47 -0
  62. package/dist/commands/mcp/shared.js +192 -0
  63. package/dist/commands/mcp/test.d.ts +5 -0
  64. package/dist/commands/mcp/test.js +457 -0
  65. package/dist/commands/mcp.d.ts +8 -104
  66. package/dist/commands/mcp.js +5 -1603
  67. package/dist/contracts/proof.d.ts +1 -1
  68. package/dist/goal/control-loop.d.ts +15 -0
  69. package/dist/goal/control-loop.js +39 -5
  70. package/dist/hud/render.d.ts +2 -0
  71. package/dist/hud/render.js +7 -1
  72. package/dist/mcp/secret-scanner.d.ts +6 -0
  73. package/dist/mcp/secret-scanner.js +44 -11
  74. package/dist/memory/graph-delta-log.d.ts +137 -0
  75. package/dist/memory/graph-delta-log.js +650 -0
  76. package/dist/memory/graph-viewer.js +13 -32
  77. package/dist/memory/local-graph-memory-store.d.ts +36 -3
  78. package/dist/memory/local-graph-memory-store.js +255 -10
  79. package/dist/orchestration/log-streamer.js +13 -8
  80. package/dist/orchestration/routing.d.ts +4 -0
  81. package/dist/orchestration/routing.js +28 -3
  82. package/dist/orchestration/state-persister.js +8 -1
  83. package/dist/providers/anthropic-messages-runner.d.ts +17 -0
  84. package/dist/providers/anthropic-messages-runner.js +197 -0
  85. package/dist/providers/model-registry.d.ts +1 -1
  86. package/dist/providers/model-registry.js +37 -3
  87. package/dist/providers/provider-runtime.js +27 -11
  88. package/dist/providers/thinking-levels.js +4 -1
  89. package/dist/providers/types.d.ts +3 -3
  90. package/dist/runtime/contracts/weakness-remediation.d.ts +9 -1
  91. package/dist/runtime/contracts/weakness-remediation.js +9 -1
  92. package/dist/runtime/router-v2-scoring.d.ts +8 -3
  93. package/dist/runtime/router-v2-scoring.js +27 -22
  94. package/dist/runtime/runtime-router.d.ts +5 -0
  95. package/dist/runtime/runtime-router.js +40 -8
  96. package/dist/runtime/sandbox-profile.d.ts +29 -0
  97. package/dist/runtime/sandbox-profile.js +101 -0
  98. package/dist/runtime/slash-commands.js +300 -2
  99. package/dist/runtime/tool-dispatch-contracts.d.ts +15 -0
  100. package/dist/runtime/tool-dispatch-contracts.js +12 -0
  101. package/dist/runtime/weights-config.d.ts +90 -0
  102. package/dist/runtime/weights-config.js +249 -0
  103. package/dist/schema/envelope.schema.d.ts +18 -18
  104. package/dist/schema/evidence.schema.d.ts +2 -2
  105. package/dist/schema/proof-bundle.schema.d.ts +6 -6
  106. package/dist/schema/proof-bundle.schema.js +0 -1
  107. package/dist/schema/provider.schema.d.ts +2 -2
  108. package/dist/schema/run-manifest.schema.d.ts +16 -16
  109. package/dist/theme/ansi.js +9 -2
  110. package/dist/theme/extended-palette.d.ts +85 -0
  111. package/dist/theme/extended-palette.js +108 -0
  112. package/dist/theme/layout.js +29 -8
  113. package/dist/theme/metrics.js +5 -5
  114. package/dist/theme/parallel.js +25 -15
  115. package/dist/ui/omk-sigil.js +5 -14
  116. package/dist/ui/omk-working-sweep.js +5 -15
  117. package/dist/util/chat-agent-mode.d.ts +11 -0
  118. package/dist/util/chat-agent-mode.js +41 -8
  119. package/dist/util/chat-cockpit.d.ts +9 -0
  120. package/dist/util/chat-cockpit.js +77 -20
  121. package/dist/util/fs/core.d.ts +5 -0
  122. package/dist/util/fs/core.js +35 -0
  123. package/dist/util/fs/internal.d.ts +14 -0
  124. package/dist/util/fs/internal.js +169 -0
  125. package/dist/util/fs/kimi-sync.d.ts +41 -0
  126. package/dist/util/fs/kimi-sync.js +495 -0
  127. package/dist/util/fs/logo.d.ts +2 -0
  128. package/dist/util/fs/logo.js +78 -0
  129. package/dist/util/fs/manifest.d.ts +6 -0
  130. package/dist/util/fs/manifest.js +40 -0
  131. package/dist/util/fs/mcp-diagnose.d.ts +15 -0
  132. package/dist/util/fs/mcp-diagnose.js +204 -0
  133. package/dist/util/fs/mcp-runtime-config.d.ts +23 -0
  134. package/dist/util/fs/mcp-runtime-config.js +412 -0
  135. package/dist/util/fs/paths.d.ts +13 -0
  136. package/dist/util/fs/paths.js +82 -0
  137. package/dist/util/fs/preflight.d.ts +27 -0
  138. package/dist/util/fs/preflight.js +271 -0
  139. package/dist/util/fs.d.ts +8 -128
  140. package/dist/util/fs.js +8 -1757
  141. package/dist/util/terminal-layout.js +5 -1
  142. package/dist/util/version.js +2 -1
  143. package/docs/2026-06-11/critical-issues.md +20 -0
  144. package/docs/2026-06-11/improvements.md +14 -0
  145. package/docs/2026-06-11/init-checklist.md +25 -0
  146. package/docs/2026-06-11/plan.md +20 -0
  147. package/docs/ARCHITECTURE_ANALYSIS_CODEGRAPH.md +223 -0
  148. package/docs/adr/0001-no-native-rust-lane.md +52 -0
  149. package/docs/codex-oauth-setup.md +14 -0
  150. package/docs/decisions/2026-06-10-git-history-bloat.md +61 -0
  151. package/docs/decisions/ADR-theme-dark-only-assets.md +43 -0
  152. package/docs/getting-started.md +1 -1
  153. package/docs/headroom-omk-final-summary.md +188 -0
  154. package/docs/headroom-omk-integration.md +394 -0
  155. package/docs/headroom-omk-setup-guide.md +422 -0
  156. package/docs/headroom-omk-usage-examples.md +371 -0
  157. package/docs/provider-maturity.md +1 -1
  158. package/docs/versioning.md +3 -3
  159. package/package.json +10 -10
  160. package/readmeasset/.npmignore +2 -0
  161. package/readmeasset/ASSET_INDEX.md +7 -5
  162. package/readmeasset/ASSET_PROVENANCE.md +21 -5
  163. package/readmeasset/omk-control-surfaces.svg +55 -0
  164. package/readmeasset/omk-core-loop.svg +1 -0
  165. package/readmeasset/omk-logo-mark.svg +1 -0
  166. package/readmeasset/omk-release-assertions.svg +51 -0
  167. package/dist/native/linux-x64/omk-safety +0 -0
  168. package/dist/util/native-safety.d.ts +0 -28
  169. package/dist/util/native-safety.js +0 -118
@@ -1,5 +1,5 @@
1
1
  import type { OMK_PROOF_BUNDLE_SCHEMA_VERSION, OMK_RUNTIME_VERSION } from "../version.js";
2
- export type ProofBundleScenario = "no-kimi-smoke" | "evidence-block" | "fallback-route" | "dag-dependent-block" | "replay-inspect" | "graph-audit" | "example-generation" | "doctor-provider" | "native-safety" | "contract-version-smoke";
2
+ export type ProofBundleScenario = "no-kimi-smoke" | "evidence-block" | "fallback-route" | "dag-dependent-block" | "replay-inspect" | "graph-audit" | "example-generation" | "doctor-provider" | "contract-version-smoke";
3
3
  export type ProofBundleVerdict = "passed" | "failed" | "partial";
4
4
  export type ProofBundleFiles = {
5
5
  rawPrompt: string;
@@ -95,6 +95,21 @@ export interface NextPromptResult {
95
95
  }
96
96
  export declare function recallMemoryForGoal(goal: GoalSpec, root: string, runState?: RunState, signal?: AbortSignal): Promise<string>;
97
97
  export declare function generateNextPrompt(goal: GoalSpec, evidence: GoalEvidence[], runState?: RunState, memorySummary?: string, root?: string): Promise<NextPromptResult>;
98
+ /** Buckets of run-state nodes grouped by lifecycle status. */
99
+ export interface RunStateNodeBuckets {
100
+ failed: RunState["nodes"];
101
+ blocked: RunState["nodes"];
102
+ running: RunState["nodes"];
103
+ pending: RunState["nodes"];
104
+ success: RunState["nodes"];
105
+ }
106
+ /**
107
+ * Classify `runState.nodes` into status buckets in a SINGLE pass. Behavior-preserving
108
+ * replacement for five separate `.filter()` passes: each bucket holds exactly the nodes
109
+ * the matching `status === ...` filter would have selected, in the same order. `success`
110
+ * collects `status === "done"` nodes. Statuses outside these five are ignored.
111
+ */
112
+ export declare function bucketRunStateNodesByStatus(runState: RunState | undefined): RunStateNodeBuckets;
98
113
  /**
99
114
  * Evaluate which success criteria still lack passing evidence.
100
115
  * Returns ordered list with required criteria first, then by weight desc.
@@ -858,6 +858,41 @@ export async function generateNextPrompt(goal, evidence, runState, memorySummary
858
858
  };
859
859
  });
860
860
  }
861
+ /**
862
+ * Classify `runState.nodes` into status buckets in a SINGLE pass. Behavior-preserving
863
+ * replacement for five separate `.filter()` passes: each bucket holds exactly the nodes
864
+ * the matching `status === ...` filter would have selected, in the same order. `success`
865
+ * collects `status === "done"` nodes. Statuses outside these five are ignored.
866
+ */
867
+ export function bucketRunStateNodesByStatus(runState) {
868
+ const failed = [];
869
+ const blocked = [];
870
+ const running = [];
871
+ const pending = [];
872
+ const success = [];
873
+ for (const node of runState?.nodes ?? []) {
874
+ switch (node.status) {
875
+ case "failed":
876
+ failed.push(node);
877
+ break;
878
+ case "blocked":
879
+ blocked.push(node);
880
+ break;
881
+ case "running":
882
+ running.push(node);
883
+ break;
884
+ case "pending":
885
+ pending.push(node);
886
+ break;
887
+ case "done":
888
+ success.push(node);
889
+ break;
890
+ default:
891
+ break;
892
+ }
893
+ }
894
+ return { failed, blocked, running, pending, success };
895
+ }
861
896
  async function generateNextPromptInner(goal, evidence, runState, memorySummary, root, signal) {
862
897
  if (signal?.aborted)
863
898
  throw signal.reason ?? new Error("Aborted");
@@ -880,11 +915,10 @@ async function generateNextPromptInner(goal, evidence, runState, memorySummary,
880
915
  const ev = evidence.find((e) => e.criterionId === c.id);
881
916
  return ev?.passed ?? false;
882
917
  });
883
- const failedNodes = runState?.nodes.filter((n) => n.status === "failed") ?? [];
884
- const blockedNodes = runState?.nodes.filter((n) => n.status === "blocked") ?? [];
885
- const runningNodes = runState?.nodes.filter((n) => n.status === "running") ?? [];
886
- const pendingNodes = runState?.nodes.filter((n) => n.status === "pending") ?? [];
887
- const successNodes = runState?.nodes.filter((n) => n.status === "done") ?? [];
918
+ // Single pass over runState.nodes replaces five separate .filter() passes per
919
+ // iteration. Bucket contents and order are identical to the prior per-status
920
+ // filters because nodes are appended in iteration order.
921
+ const { failed: failedNodes, blocked: blockedNodes, running: runningNodes, pending: pendingNodes, success: successNodes, } = bucketRunStateNodesByStatus(runState);
888
922
  const proposedAction = suggestion.type === "close"
889
923
  ? "close"
890
924
  : failedNodes.length > 0 || blockedNodes.length > 0
@@ -29,6 +29,8 @@ export interface HudRenderOptions {
29
29
  showUptime?: boolean;
30
30
  systemRefreshMs?: number;
31
31
  thinking?: import("./types.js").HudThinkingEntry[];
32
+ /** Optional live brand theme override; OMK_THEME is used when this is absent. */
33
+ theme?: string;
32
34
  /** Current working phase for gradient-animated status line */
33
35
  workingPhase?: import("../theme/working-indicator.js").WorkingPhase | null;
34
36
  /** Spinner animation type (defaults to "braille") */
@@ -12,6 +12,8 @@ import { t } from "../util/i18n.js";
12
12
  import { parseRunStateResult, buildRunViewModel, renderRunSummary, sanitizeForDisplay, } from "../util/run-view-model.js";
13
13
  import { hudTheme } from "../util/theme.js";
14
14
  import { renderWorkingIndicator } from "../theme/working-indicator.js";
15
+ import { setBrandPaletteTheme } from "../brand/palette.js";
16
+ import { getActiveBrandHudStatus } from "../brand/theme-compiled.js";
15
17
  import { loadTodos } from "../util/todo-sync.js";
16
18
  import { readSessionMeta } from "../util/session.js";
17
19
  const theme = hudTheme;
@@ -254,7 +256,7 @@ function renderNeonControlHeader(runId, workingPhase, workingSpinner) {
254
256
  const parts = [
255
257
  "",
256
258
  theme.style.phosphor("OMK//HUD") + " " + runLabel,
257
- theme.style.gray("NEON GRID ONLINE"),
259
+ theme.style.gray(getActiveBrandHudStatus()),
258
260
  theme.style.gray("Route agents. Verify evidence. Control the loop."),
259
261
  ];
260
262
  if (workingLine) {
@@ -940,6 +942,10 @@ async function renderSectionDashboard(options) {
940
942
  return output.join("\n");
941
943
  }
942
944
  export async function renderHudDashboard(options = {}) {
945
+ const requestedBrandTheme = options.theme ?? process.env.OMK_THEME;
946
+ if (requestedBrandTheme !== undefined) {
947
+ setBrandPaletteTheme(requestedBrandTheme);
948
+ }
943
949
  const width = options.terminalWidth ?? defaultHudTerminalWidth();
944
950
  if (options.section) {
945
951
  return renderSectionDashboard(options);
@@ -168,6 +168,12 @@ export declare class SecretScanner extends EventEmitter {
168
168
  static severityIcon(severity: SecretSeverity): string;
169
169
  private findInText;
170
170
  private redactText;
171
+ /**
172
+ * Precompute the byte offset at which each line begins.
173
+ * lineStarts[0] is always 0; each subsequent entry is the index just after a
174
+ * "\n". Used to make getLineColumn O(log n) per lookup instead of O(offset).
175
+ */
176
+ private computeLineStarts;
171
177
  private getLineColumn;
172
178
  private getContext;
173
179
  private readFileSafe;
@@ -313,13 +313,14 @@ export class SecretScanner extends EventEmitter {
313
313
  const findings = [];
314
314
  let redacted = text;
315
315
  const activePatterns = this.getActivePatterns();
316
+ const lineStarts = this.computeLineStarts(text);
316
317
  for (const pattern of activePatterns) {
317
318
  pattern.pattern.lastIndex = 0;
318
319
  let match;
319
320
  while ((match = pattern.pattern.exec(text)) !== null) {
320
321
  const matchedText = match[0];
321
322
  const offset = match.index;
322
- const { line, column } = this.getLineColumn(text, offset);
323
+ const { line, column } = this.getLineColumn(text, offset, lineStarts);
323
324
  const context = this.getContext(text, offset, matchedText.length);
324
325
  findings.push({
325
326
  id: this.generateId(),
@@ -519,13 +520,14 @@ export class SecretScanner extends EventEmitter {
519
520
  findInText(text, sourceFile) {
520
521
  const findings = [];
521
522
  const activePatterns = this.getActivePatterns();
523
+ const lineStarts = this.computeLineStarts(text);
522
524
  for (const pattern of activePatterns) {
523
525
  pattern.pattern.lastIndex = 0;
524
526
  let match;
525
527
  while ((match = pattern.pattern.exec(text)) !== null) {
526
528
  const matchedText = match[0];
527
529
  const offset = match.index;
528
- const { line, column } = this.getLineColumn(text, offset);
530
+ const { line, column } = this.getLineColumn(text, offset, lineStarts);
529
531
  const context = this.getContext(text, offset, matchedText.length);
530
532
  findings.push({
531
533
  id: this.generateId(),
@@ -553,19 +555,50 @@ export class SecretScanner extends EventEmitter {
553
555
  }
554
556
  return result;
555
557
  }
556
- getLineColumn(text, offset) {
557
- let line = 1;
558
- let column = 1;
559
- for (let i = 0; i < offset && i < text.length; i++) {
560
- if (text[i] === "\n") {
561
- line++;
562
- column = 1;
558
+ /**
559
+ * Precompute the byte offset at which each line begins.
560
+ * lineStarts[0] is always 0; each subsequent entry is the index just after a
561
+ * "\n". Used to make getLineColumn O(log n) per lookup instead of O(offset).
562
+ */
563
+ computeLineStarts(text) {
564
+ const lineStarts = [0];
565
+ for (let i = 0; i < text.length; i++) {
566
+ if (text[i] === "\n")
567
+ lineStarts.push(i + 1);
568
+ }
569
+ return lineStarts;
570
+ }
571
+ getLineColumn(text, offset, lineStarts) {
572
+ // Backward-compatible fallback: original O(offset) scan when no precomputed
573
+ // index is supplied. Produces identical line/column numbers.
574
+ if (!lineStarts) {
575
+ let line = 1;
576
+ let column = 1;
577
+ for (let i = 0; i < offset && i < text.length; i++) {
578
+ if (text[i] === "\n") {
579
+ line++;
580
+ column = 1;
581
+ }
582
+ else {
583
+ column++;
584
+ }
585
+ }
586
+ return { line, column };
587
+ }
588
+ // Binary search for the rightmost line start that is <= offset.
589
+ let lo = 0;
590
+ let hi = lineStarts.length - 1;
591
+ while (lo < hi) {
592
+ const mid = (lo + hi + 1) >> 1;
593
+ if (lineStarts[mid] <= offset) {
594
+ lo = mid;
563
595
  }
564
596
  else {
565
- column++;
597
+ hi = mid - 1;
566
598
  }
567
599
  }
568
- return { line, column };
600
+ const lineStartOffset = lineStarts[lo];
601
+ return { line: lo + 1, column: offset - lineStartOffset + 1 };
569
602
  }
570
603
  getContext(text, offset, matchLength) {
571
604
  const ctxChars = this.contextChars;
@@ -0,0 +1,137 @@
1
+ import type { LocalGraphState, LocalGraphNode, LocalGraphEdge } from "./local-graph-memory-store.js";
2
+ export interface DeltaRecord {
3
+ v: 2;
4
+ epoch: number;
5
+ seq: number;
6
+ ts: string;
7
+ meta: {
8
+ updatedAt: string;
9
+ project: {
10
+ key: string;
11
+ name: string;
12
+ root: string;
13
+ };
14
+ ontology: string;
15
+ };
16
+ nodes: {
17
+ del: string[];
18
+ put: LocalGraphNode[];
19
+ };
20
+ edges: {
21
+ del: string[];
22
+ put: LocalGraphEdge[];
23
+ };
24
+ crc: string;
25
+ }
26
+ export interface DeltaManifest {
27
+ formatVersion: 2;
28
+ snapshot: string;
29
+ snapshotEpoch: number;
30
+ delta: string;
31
+ deltaOpCount: number;
32
+ }
33
+ export type DurabilityMode = "legacy" | "delta";
34
+ export declare function resolveDurabilityMode(env?: NodeJS.ProcessEnv): DurabilityMode;
35
+ /**
36
+ * Compute an order-faithful delta between pre-mutation and post-mutation state.
37
+ * `put` entries are ordered by their index in the final array and repositioned
38
+ * entries are deleted-before-put, so Map-based replay reproduces the EXACT raw
39
+ * array order of the legacy full-rewrite (see `computeOrderedDelta`).
40
+ */
41
+ export declare function computeDelta(preNodes: ReadonlyMap<string, LocalGraphNode>, preEdges: ReadonlyMap<string, LocalGraphEdge>, state: LocalGraphState): {
42
+ nodes: {
43
+ del: string[];
44
+ put: LocalGraphNode[];
45
+ };
46
+ edges: {
47
+ del: string[];
48
+ put: LocalGraphEdge[];
49
+ };
50
+ };
51
+ export declare function readManifest(graphPath: string): Promise<DeltaManifest | null>;
52
+ export declare function writeManifest(graphPath: string, manifest: DeltaManifest): Promise<void>;
53
+ /**
54
+ * Append a single delta record to the journal + fdatasync.
55
+ * Returns the seq number assigned to the record.
56
+ */
57
+ export declare function appendDelta(graphPath: string, epoch: number, seq: number, ts: string, meta: DeltaRecord["meta"], nodesDelta: {
58
+ del: string[];
59
+ put: LocalGraphNode[];
60
+ }, edgesDelta: {
61
+ del: string[];
62
+ put: LocalGraphEdge[];
63
+ }): Promise<void>;
64
+ /**
65
+ * Load snapshot from disk plus replay all valid delta records.
66
+ *
67
+ * Replay correctness lemma:
68
+ * 1. Base: nodes/edges loaded from snapshot into insertion-ordered Map.
69
+ * 2. For each record with epoch === currentEpoch:
70
+ * a. Apply all `del` ids: Map.delete(key).
71
+ * b. Apply all `put` entries in array order: Map.set(key, entry).
72
+ * Map.set on existing key keeps position; on new/deleted key appends.
73
+ * 3. Materialize: `[...map.values()]` produces the exact same array order
74
+ * as the full-rewrite saveState().
75
+ *
76
+ * Crash recovery: the last line of the delta log may be torn. If JSON.parse
77
+ * fails AND it is the last line, we treat it as a torn tail and discard it.
78
+ * A CRC mismatch on a non-final line is corruption → throws in strict mode.
79
+ */
80
+ export declare function replayDeltas(baseState: LocalGraphState, records: DeltaRecord[], epoch: number): LocalGraphState;
81
+ export interface DeltaParseResult {
82
+ records: DeltaRecord[];
83
+ /** Byte offset (exclusive end) of the last valid, newline-terminated record. */
84
+ validBytes: number;
85
+ /** True when a trailing, non-newline-terminated partial record was detected. */
86
+ torn: boolean;
87
+ }
88
+ export interface DeltaLoadResult {
89
+ state: LocalGraphState;
90
+ epoch: number;
91
+ lastSeq: number;
92
+ deltaOpCount: number;
93
+ /** Byte offset of the last valid record == where the next append lands. */
94
+ validBytes: number;
95
+ }
96
+ /**
97
+ * Full cold load in delta mode: manifest → snapshot → replay delta tail.
98
+ *
99
+ * Torn-tail recovery: if the log ends in a partial (non-newline-terminated)
100
+ * record, physically truncate the file to the last valid record boundary BEFORE
101
+ * returning, so the next O_APPEND write can never merge into the half-written
102
+ * line. Any cached append fd is closed first to drop the stale handle.
103
+ */
104
+ export declare function loadStateViaDelta(graphPath: string, strict: boolean, emptyState: LocalGraphState): Promise<DeltaLoadResult>;
105
+ /**
106
+ * One-time setup: load legacy graph-state.json (or empty), write snapshot,
107
+ * write manifest, create empty delta log. Does NOT delete the legacy file.
108
+ * If manifest already exists, this is a no-op.
109
+ */
110
+ export declare function setupDeltaMode(graphPath: string, legacyState: LocalGraphState): Promise<DeltaManifest>;
111
+ export interface CompactionThresholds {
112
+ maxBytes: number;
113
+ maxOps: number;
114
+ }
115
+ export declare function resolveCompactionThresholds(env?: NodeJS.ProcessEnv): CompactionThresholds;
116
+ /**
117
+ * Check if compaction is needed and perform it if so.
118
+ * Procedure: write snapshot → write new manifest (commit pivot) → truncate delta.
119
+ * The manifest is the single commit point; crash before manifest pivot is safe.
120
+ */
121
+ export declare function compactIfNeeded(graphPath: string, state: LocalGraphState, currentEpoch: number, currentOpCount: number, thresholds: CompactionThresholds): Promise<{
122
+ compacted: boolean;
123
+ newEpoch: number;
124
+ newOpCount: number;
125
+ }>;
126
+ export interface DeltaFileStats {
127
+ snapshotMtimeMs: number;
128
+ snapshotSize: number;
129
+ snapshotCtimeMs: number;
130
+ snapshotIno: number;
131
+ deltaSize: number;
132
+ }
133
+ export declare function statDeltaFiles(graphPath: string): DeltaFileStats | null;
134
+ export declare function deltaStatsMatch(a: DeltaFileStats | null, b: DeltaFileStats | null): boolean;
135
+ export declare function acquireDeltaLock(graphPath: string, maxWaitMs?: number): Promise<void>;
136
+ export declare function releaseDeltaLock(graphPath: string): void;
137
+ export declare function withDeltaLock<T>(graphPath: string, fn: () => Promise<T>, env?: NodeJS.ProcessEnv, maxWaitMs?: number): Promise<T>;