agent-cli-runtime 0.1.0-alpha.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.
Files changed (151) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/CONTRIBUTING.md +60 -0
  3. package/LICENSE +202 -0
  4. package/README.md +573 -0
  5. package/README.zh-CN.md +571 -0
  6. package/SECURITY.md +35 -0
  7. package/dist/adapters/adapter-types.d.ts +138 -0
  8. package/dist/adapters/adapter-types.js +2 -0
  9. package/dist/adapters/adapter-types.js.map +1 -0
  10. package/dist/adapters/claude.d.ts +2 -0
  11. package/dist/adapters/claude.js +97 -0
  12. package/dist/adapters/claude.js.map +1 -0
  13. package/dist/adapters/codex.d.ts +3 -0
  14. package/dist/adapters/codex.js +120 -0
  15. package/dist/adapters/codex.js.map +1 -0
  16. package/dist/adapters/opencode.d.ts +4 -0
  17. package/dist/adapters/opencode.js +111 -0
  18. package/dist/adapters/opencode.js.map +1 -0
  19. package/dist/adapters/registry.d.ts +9 -0
  20. package/dist/adapters/registry.js +23 -0
  21. package/dist/adapters/registry.js.map +1 -0
  22. package/dist/cli/main.d.ts +2 -0
  23. package/dist/cli/main.js +978 -0
  24. package/dist/cli/main.js.map +1 -0
  25. package/dist/core/async-queue.d.ts +10 -0
  26. package/dist/core/async-queue.js +49 -0
  27. package/dist/core/async-queue.js.map +1 -0
  28. package/dist/core/diagnostics.d.ts +20 -0
  29. package/dist/core/diagnostics.js +4 -0
  30. package/dist/core/diagnostics.js.map +1 -0
  31. package/dist/core/event-contract.d.ts +32 -0
  32. package/dist/core/event-contract.js +128 -0
  33. package/dist/core/event-contract.js.map +1 -0
  34. package/dist/core/events.d.ts +147 -0
  35. package/dist/core/events.js +4 -0
  36. package/dist/core/events.js.map +1 -0
  37. package/dist/core/ids.d.ts +1 -0
  38. package/dist/core/ids.js +5 -0
  39. package/dist/core/ids.js.map +1 -0
  40. package/dist/core/redaction.d.ts +4 -0
  41. package/dist/core/redaction.js +51 -0
  42. package/dist/core/redaction.js.map +1 -0
  43. package/dist/core/runtime.d.ts +41 -0
  44. package/dist/core/runtime.js +83 -0
  45. package/dist/core/runtime.js.map +1 -0
  46. package/dist/core/schema-contract.d.ts +55 -0
  47. package/dist/core/schema-contract.js +143 -0
  48. package/dist/core/schema-contract.js.map +1 -0
  49. package/dist/detection/detect.d.ts +14 -0
  50. package/dist/detection/detect.js +293 -0
  51. package/dist/detection/detect.js.map +1 -0
  52. package/dist/detection/env.d.ts +2 -0
  53. package/dist/detection/env.js +15 -0
  54. package/dist/detection/env.js.map +1 -0
  55. package/dist/detection/executable-resolution.d.ts +12 -0
  56. package/dist/detection/executable-resolution.js +50 -0
  57. package/dist/detection/executable-resolution.js.map +1 -0
  58. package/dist/detection/invocation.d.ts +9 -0
  59. package/dist/detection/invocation.js +22 -0
  60. package/dist/detection/invocation.js.map +1 -0
  61. package/dist/goals/goal-scheduler.d.ts +31 -0
  62. package/dist/goals/goal-scheduler.js +518 -0
  63. package/dist/goals/goal-scheduler.js.map +1 -0
  64. package/dist/goals/goal-store.d.ts +37 -0
  65. package/dist/goals/goal-store.js +300 -0
  66. package/dist/goals/goal-store.js.map +1 -0
  67. package/dist/goals/goal-types.d.ts +103 -0
  68. package/dist/goals/goal-types.js +2 -0
  69. package/dist/goals/goal-types.js.map +1 -0
  70. package/dist/goals/planner-prompts.d.ts +3 -0
  71. package/dist/goals/planner-prompts.js +26 -0
  72. package/dist/goals/planner-prompts.js.map +1 -0
  73. package/dist/goals/task-graph.d.ts +9 -0
  74. package/dist/goals/task-graph.js +229 -0
  75. package/dist/goals/task-graph.js.map +1 -0
  76. package/dist/goals/validation-runner.d.ts +7 -0
  77. package/dist/goals/validation-runner.js +63 -0
  78. package/dist/goals/validation-runner.js.map +1 -0
  79. package/dist/index.d.ts +11 -0
  80. package/dist/index.js +2 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/parsers/claude-stream-json.d.ts +11 -0
  83. package/dist/parsers/claude-stream-json.js +102 -0
  84. package/dist/parsers/claude-stream-json.js.map +1 -0
  85. package/dist/parsers/codex-json.d.ts +8 -0
  86. package/dist/parsers/codex-json.js +107 -0
  87. package/dist/parsers/codex-json.js.map +1 -0
  88. package/dist/parsers/line-buffer.d.ts +7 -0
  89. package/dist/parsers/line-buffer.js +28 -0
  90. package/dist/parsers/line-buffer.js.map +1 -0
  91. package/dist/parsers/opencode-json.d.ts +8 -0
  92. package/dist/parsers/opencode-json.js +72 -0
  93. package/dist/parsers/opencode-json.js.map +1 -0
  94. package/dist/parsers/plain-lines.d.ts +6 -0
  95. package/dist/parsers/plain-lines.js +9 -0
  96. package/dist/parsers/plain-lines.js.map +1 -0
  97. package/dist/public-types.d.ts +143 -0
  98. package/dist/public-types.js +2 -0
  99. package/dist/public-types.js.map +1 -0
  100. package/dist/runs/process-runner.d.ts +35 -0
  101. package/dist/runs/process-runner.js +97 -0
  102. package/dist/runs/process-runner.js.map +1 -0
  103. package/dist/runs/prompt-transport.d.ts +10 -0
  104. package/dist/runs/prompt-transport.js +43 -0
  105. package/dist/runs/prompt-transport.js.map +1 -0
  106. package/dist/runs/run-result.d.ts +9 -0
  107. package/dist/runs/run-result.js +22 -0
  108. package/dist/runs/run-result.js.map +1 -0
  109. package/dist/runs/run-scheduler.d.ts +25 -0
  110. package/dist/runs/run-scheduler.js +552 -0
  111. package/dist/runs/run-scheduler.js.map +1 -0
  112. package/dist/runs/run-store.d.ts +42 -0
  113. package/dist/runs/run-store.js +297 -0
  114. package/dist/runs/run-store.js.map +1 -0
  115. package/dist/runs/run-types.d.ts +59 -0
  116. package/dist/runs/run-types.js +2 -0
  117. package/dist/runs/run-types.js.map +1 -0
  118. package/dist/smoke/parser-samples.d.ts +17 -0
  119. package/dist/smoke/parser-samples.js +186 -0
  120. package/dist/smoke/parser-samples.js.map +1 -0
  121. package/dist/storage/file-storage.d.ts +35 -0
  122. package/dist/storage/file-storage.js +271 -0
  123. package/dist/storage/file-storage.js.map +1 -0
  124. package/dist/storage/jsonl-store.d.ts +9 -0
  125. package/dist/storage/jsonl-store.js +138 -0
  126. package/dist/storage/jsonl-store.js.map +1 -0
  127. package/dist/storage/manifest-validation.d.ts +11 -0
  128. package/dist/storage/manifest-validation.js +102 -0
  129. package/dist/storage/manifest-validation.js.map +1 -0
  130. package/dist/storage/storage-lease.d.ts +40 -0
  131. package/dist/storage/storage-lease.js +223 -0
  132. package/dist/storage/storage-lease.js.map +1 -0
  133. package/dist/storage/storage-types.d.ts +55 -0
  134. package/dist/storage/storage-types.js +2 -0
  135. package/dist/storage/storage-types.js.map +1 -0
  136. package/dist/storage/store-inspection.d.ts +28 -0
  137. package/dist/storage/store-inspection.js +941 -0
  138. package/dist/storage/store-inspection.js.map +1 -0
  139. package/docs/api-schema-contract.md +92 -0
  140. package/docs/compatibility.md +832 -0
  141. package/docs/daemon-ready-contract.md +283 -0
  142. package/docs/production-readiness.md +281 -0
  143. package/docs/release-checklist.md +257 -0
  144. package/docs/release-publish-runbook.md +201 -0
  145. package/docs/release-report.md +517 -0
  146. package/docs/ssot.md +1257 -0
  147. package/examples/cli-dogfood.md +113 -0
  148. package/examples/library-goal.js +94 -0
  149. package/examples/library-run.js +84 -0
  150. package/package.json +79 -0
  151. package/scripts/dogfood.mjs +243 -0
@@ -0,0 +1,271 @@
1
+ import { closeSync, existsSync, fdatasyncSync, fsyncSync, mkdirSync, openSync, readdirSync, readFileSync, renameSync, appendFileSync, unlinkSync, writeSync, } from "node:fs";
2
+ import path from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { redactUnknown } from "../core/redaction.js";
5
+ import { appendJsonl, readJsonl } from "./jsonl-store.js";
6
+ import { validateGoalManifest, validateRunManifest } from "./manifest-validation.js";
7
+ export class JsonFileStorage {
8
+ rootDir;
9
+ options;
10
+ diagnostics = [];
11
+ durability;
12
+ constructor(rootDir, options = {}) {
13
+ this.rootDir = rootDir;
14
+ this.options = options;
15
+ this.durability = options.durability ?? "relaxed";
16
+ mkdirSync(this.runsDir, { recursive: true });
17
+ mkdirSync(this.goalsDir, { recursive: true });
18
+ }
19
+ listRuns() {
20
+ return listManifestDirs(this.runsDir).map((dir) => {
21
+ const runId = path.basename(dir);
22
+ const manifest = readRunManifest(path.join(dir, "manifest.json"), runId);
23
+ const events = readJsonl(path.join(dir, "events.jsonl"));
24
+ return {
25
+ manifest: manifest.value ?? corruptRunManifest(runId, manifest.error),
26
+ manifestError: manifest.error,
27
+ events: events.records.map((record) => normalizeReplayEvent(record, { runId })),
28
+ eventsError: events.error,
29
+ eventsIssue: events.issue,
30
+ };
31
+ });
32
+ }
33
+ writeRunManifest(record) {
34
+ this.assertCanWrite();
35
+ atomicWriteJson(this.runManifestPath(record.id), sanitizeForStorage(record), this.writeOptions("manifest"));
36
+ }
37
+ appendRunEvent(runId, event) {
38
+ this.assertCanWrite();
39
+ this.ensureRunDir(runId);
40
+ appendJsonl(this.runEventsPath(runId), sanitizeForStorage(event), this.writeOptions("event"));
41
+ }
42
+ listGoals() {
43
+ return listManifestDirs(this.goalsDir).map((dir) => {
44
+ const goalId = path.basename(dir);
45
+ const manifest = readGoalManifest(path.join(dir, "manifest.json"), goalId);
46
+ const events = readJsonl(path.join(dir, "events.jsonl"));
47
+ return {
48
+ manifest: manifest.value ?? corruptGoalManifest(goalId, manifest.error),
49
+ manifestError: manifest.error,
50
+ events: events.records.map((record) => normalizeReplayEvent(record, { goalId })),
51
+ eventsError: events.error,
52
+ eventsIssue: events.issue,
53
+ };
54
+ });
55
+ }
56
+ writeGoalManifest(record) {
57
+ this.assertCanWrite();
58
+ atomicWriteJson(this.goalManifestPath(record.id), sanitizeForStorage(record), this.writeOptions("manifest"));
59
+ }
60
+ appendGoalEvent(goalId, event) {
61
+ this.assertCanWrite();
62
+ this.ensureGoalDir(goalId);
63
+ appendJsonl(this.goalEventsPath(goalId), sanitizeForStorage(event), this.writeOptions("event"));
64
+ }
65
+ getDurabilityDiagnostics() {
66
+ return [...this.diagnostics];
67
+ }
68
+ get runsDir() {
69
+ return path.join(this.rootDir, "runs");
70
+ }
71
+ get goalsDir() {
72
+ return path.join(this.rootDir, "goals");
73
+ }
74
+ ensureRunDir(runId) {
75
+ mkdirSync(path.join(this.runsDir, runId), { recursive: true });
76
+ }
77
+ ensureGoalDir(goalId) {
78
+ mkdirSync(path.join(this.goalsDir, goalId), { recursive: true });
79
+ }
80
+ runManifestPath(runId) {
81
+ this.ensureRunDir(runId);
82
+ return path.join(this.runsDir, runId, "manifest.json");
83
+ }
84
+ runEventsPath(runId) {
85
+ return path.join(this.runsDir, runId, "events.jsonl");
86
+ }
87
+ goalManifestPath(goalId) {
88
+ this.ensureGoalDir(goalId);
89
+ return path.join(this.goalsDir, goalId, "manifest.json");
90
+ }
91
+ goalEventsPath(goalId) {
92
+ return path.join(this.goalsDir, goalId, "events.jsonl");
93
+ }
94
+ writeOptions(operation) {
95
+ return {
96
+ durability: this.durability,
97
+ sync: this.options.sync,
98
+ faults: this.options.faults,
99
+ onSyncDiagnostic: (message) => {
100
+ this.recordDurabilityDiagnostic(`Storage ${operation} sync fallback: ${message}`);
101
+ },
102
+ };
103
+ }
104
+ recordDurabilityDiagnostic(message) {
105
+ const safeMessage = redactUnknown(message);
106
+ this.diagnostics.push(safeMessage);
107
+ try {
108
+ appendFileSync(path.join(this.rootDir, "diagnostics.jsonl"), `${JSON.stringify({
109
+ timestamp: Date.now(),
110
+ diagnostic: {
111
+ code: "AGENT_STORAGE_SYNC_FALLBACK",
112
+ message: safeMessage,
113
+ retryable: false,
114
+ },
115
+ })}\n`, "utf8");
116
+ }
117
+ catch {
118
+ // Sync fallback diagnostics are best-effort and must not make the primary write fail.
119
+ }
120
+ }
121
+ assertCanWrite() {
122
+ if (this.options.canWrite && !this.options.canWrite()) {
123
+ throw new Error("storage lease is no longer held by this runtime");
124
+ }
125
+ }
126
+ }
127
+ function listManifestDirs(parent) {
128
+ if (!existsSync(parent))
129
+ return [];
130
+ return readdirSync(parent, { withFileTypes: true })
131
+ .filter((entry) => entry.isDirectory() && existsSync(path.join(parent, entry.name, "manifest.json")))
132
+ .map((entry) => path.join(parent, entry.name));
133
+ }
134
+ function readRunManifest(file, runId) {
135
+ const parsed = readJson(file);
136
+ if (parsed.error)
137
+ return { error: parsed.error };
138
+ return validateRunManifest(parsed.value, runId);
139
+ }
140
+ function readGoalManifest(file, goalId) {
141
+ const parsed = readJson(file);
142
+ if (parsed.error)
143
+ return { error: parsed.error };
144
+ return validateGoalManifest(parsed.value, goalId);
145
+ }
146
+ function readJson(file) {
147
+ try {
148
+ return { value: JSON.parse(readFileSync(file, "utf8")) };
149
+ }
150
+ catch (error) {
151
+ return { error: new Error(`${path.basename(file)} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`) };
152
+ }
153
+ }
154
+ function atomicWriteJson(file, value, options = {}) {
155
+ mkdirSync(path.dirname(file), { recursive: true });
156
+ const tmp = path.join(path.dirname(file), `.manifest.${process.pid}.${randomUUID()}.tmp`);
157
+ let fd;
158
+ let renamed = false;
159
+ try {
160
+ options.faults?.beforeManifestTempWrite?.(file);
161
+ fd = openSync(tmp, "w");
162
+ writeSync(fd, `${JSON.stringify(value, null, 2)}\n`, undefined, "utf8");
163
+ syncFileDescriptor(fd, options);
164
+ closeSync(fd);
165
+ fd = undefined;
166
+ options.faults?.beforeManifestRename?.(tmp, file);
167
+ renameSync(tmp, file);
168
+ renamed = true;
169
+ syncDirectory(path.dirname(file), options);
170
+ }
171
+ finally {
172
+ if (fd !== undefined)
173
+ closeSync(fd);
174
+ if (!renamed) {
175
+ try {
176
+ if (existsSync(tmp))
177
+ unlinkSync(tmp);
178
+ }
179
+ catch {
180
+ // Temp cleanup is best-effort; the old manifest remains untouched.
181
+ }
182
+ }
183
+ }
184
+ }
185
+ function sanitizeForStorage(value) {
186
+ return redactUnknown(value);
187
+ }
188
+ function normalizeReplayEvent(record, scope) {
189
+ const sequence = typeof record.sequence === "number" ? record.sequence : record.id;
190
+ return {
191
+ ...record,
192
+ ...scope,
193
+ sequence,
194
+ };
195
+ }
196
+ function syncFileDescriptor(fd, options) {
197
+ if (options.durability !== "fsync")
198
+ return;
199
+ try {
200
+ const fdatasync = options.sync?.fdatasyncSync ?? fdatasyncSync;
201
+ fdatasync(fd);
202
+ }
203
+ catch (fdatasyncError) {
204
+ try {
205
+ const fsync = options.sync?.fsyncSync ?? fsyncSync;
206
+ fsync(fd);
207
+ }
208
+ catch (fsyncError) {
209
+ options.onSyncDiagnostic?.(`fdatasync failed (${errorMessage(fdatasyncError)}); fsync fallback failed (${errorMessage(fsyncError)}); continuing with relaxed durability`);
210
+ }
211
+ }
212
+ }
213
+ function syncDirectory(dir, options) {
214
+ if (options.durability !== "fsync")
215
+ return;
216
+ let fd;
217
+ try {
218
+ fd = openSync(dir, "r");
219
+ const fsync = options.sync?.fsyncSync ?? fsyncSync;
220
+ fsync(fd);
221
+ }
222
+ catch (error) {
223
+ options.onSyncDiagnostic?.(`directory fsync skipped (${errorMessage(error)}); continuing with file-level durability`);
224
+ }
225
+ finally {
226
+ if (fd !== undefined)
227
+ closeSync(fd);
228
+ }
229
+ }
230
+ function errorMessage(error) {
231
+ return error instanceof Error ? error.message : String(error);
232
+ }
233
+ function corruptRunManifest(runId, error) {
234
+ const now = Date.now();
235
+ return {
236
+ id: runId,
237
+ agentId: "unknown",
238
+ cwd: "<unknown>",
239
+ status: "failed",
240
+ createdAt: now,
241
+ updatedAt: now,
242
+ exitCode: null,
243
+ signal: null,
244
+ error: error?.message ?? "Run manifest is corrupt.",
245
+ errorCode: "AGENT_STORE_RECORD_CORRUPT",
246
+ diagnostics: [{
247
+ code: "AGENT_STORE_RECORD_CORRUPT",
248
+ message: error?.message ?? "Run manifest is corrupt.",
249
+ retryable: false,
250
+ }],
251
+ };
252
+ }
253
+ function corruptGoalManifest(goalId, error) {
254
+ const now = Date.now();
255
+ return {
256
+ id: goalId,
257
+ cwd: "<unknown>",
258
+ objective: "<unknown>",
259
+ status: "failed",
260
+ result: "failed",
261
+ tasks: [],
262
+ diagnostics: [{
263
+ code: "AGENT_STORE_RECORD_CORRUPT",
264
+ message: error?.message ?? "Goal manifest is corrupt.",
265
+ retryable: false,
266
+ }],
267
+ createdAt: now,
268
+ updatedAt: now,
269
+ };
270
+ }
271
+ //# sourceMappingURL=file-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-storage.js","sourceRoot":"","sources":["../../src/storage/file-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ReplayEvent } from "../core/events.js";
2
+ import type { JsonlReadResult, StorageDurability, StorageFaultHooks, StorageSyncHooks } from "./storage-types.js";
3
+ export declare function appendJsonl<T>(file: string, record: ReplayEvent<T>, options?: {
4
+ durability?: StorageDurability;
5
+ sync?: StorageSyncHooks;
6
+ faults?: StorageFaultHooks;
7
+ onSyncDiagnostic?: (message: string) => void;
8
+ }): void;
9
+ export declare function readJsonl<T>(file: string): JsonlReadResult<T>;
@@ -0,0 +1,138 @@
1
+ import { closeSync, existsSync, fdatasyncSync, fsyncSync, mkdirSync, openSync, readFileSync, readSync, statSync, writeSync, } from "node:fs";
2
+ import path from "node:path";
3
+ import { redactText } from "../core/redaction.js";
4
+ export function appendJsonl(file, record, options = {}) {
5
+ mkdirSync(path.dirname(file), { recursive: true });
6
+ options.faults?.beforeJsonlAppend?.(file);
7
+ const fd = openSync(file, "a");
8
+ try {
9
+ if (needsJsonlBoundary(file)) {
10
+ writeSync(fd, "\n", undefined, "utf8");
11
+ }
12
+ writeSync(fd, `${JSON.stringify(record)}\n`, undefined, "utf8");
13
+ syncFileDescriptor(fd, options);
14
+ }
15
+ finally {
16
+ closeSync(fd);
17
+ }
18
+ }
19
+ function needsJsonlBoundary(file) {
20
+ if (!existsSync(file))
21
+ return false;
22
+ try {
23
+ const { size } = statSync(file);
24
+ if (size === 0)
25
+ return false;
26
+ const handle = openSync(file, "r");
27
+ try {
28
+ const buffer = Buffer.alloc(1);
29
+ readSync(handle, buffer, 0, 1, size - 1);
30
+ return buffer[0] !== 10;
31
+ }
32
+ finally {
33
+ closeSync(handle);
34
+ }
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ export function readJsonl(file) {
41
+ if (!existsSync(file))
42
+ return { records: [], issues: [] };
43
+ const text = readFileSync(file, "utf8");
44
+ const records = [];
45
+ const lines = text.split(/\r?\n/);
46
+ const lastNonEmptyLine = lastNonEmptyLineIndex(lines);
47
+ const issues = [];
48
+ for (let index = 0; index < lines.length; index += 1) {
49
+ const line = lines[index];
50
+ if (!line.trim())
51
+ continue;
52
+ try {
53
+ const parsed = JSON.parse(line);
54
+ if (!isReplayEvent(parsed)) {
55
+ issues.push(jsonlIssue(file, index + 1, "line is not a replay event", records, false, line));
56
+ continue;
57
+ }
58
+ records.push(parsed);
59
+ }
60
+ catch (error) {
61
+ const reason = error instanceof Error ? error.message : String(error);
62
+ const partialTail = isPartialTail(text, index, lastNonEmptyLine, reason);
63
+ issues.push(jsonlIssue(file, index + 1, reason, records, partialTail, line));
64
+ if (partialTail)
65
+ break;
66
+ }
67
+ }
68
+ if (issues.length === 0)
69
+ return { records, issues };
70
+ return {
71
+ records,
72
+ error: new Error(issueSummary(issues)),
73
+ issue: issues[0],
74
+ issues,
75
+ };
76
+ }
77
+ function jsonlIssue(file, line, reason, records, partialTail, rawLine) {
78
+ const lastGood = records.at(-1);
79
+ return {
80
+ file: path.basename(file),
81
+ line,
82
+ reason,
83
+ retainedEventCount: records.length,
84
+ partialTail,
85
+ corruptLineCount: 1,
86
+ partialTailDetected: partialTail,
87
+ lastGoodEventId: lastGood?.id,
88
+ lastGoodSequence: lastGood?.sequence,
89
+ repairRecommendation: partialTail ? "truncate_partial_tail" : "isolate_corrupt_line",
90
+ redactedTailPreview: redactText(rawLine.slice(0, 256)),
91
+ };
92
+ }
93
+ function issueSummary(issues) {
94
+ const [first] = issues;
95
+ const partialTailCount = issues.filter((issue) => issue.partialTail).length;
96
+ return `${first?.file ?? "events.jsonl"} has ${issues.length} corrupt JSONL line(s)`
97
+ + `${partialTailCount > 0 ? ` including ${partialTailCount} partial tail(s)` : ""}`
98
+ + `; retained ${first?.retainedEventCount ?? 0} event(s) before first issue`;
99
+ }
100
+ function isReplayEvent(value) {
101
+ if (!value || typeof value !== "object")
102
+ return false;
103
+ const record = value;
104
+ return typeof record.id === "number" && typeof record.timestamp === "number" && Boolean(record.event);
105
+ }
106
+ function lastNonEmptyLineIndex(lines) {
107
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
108
+ if (lines[index]?.trim())
109
+ return index;
110
+ }
111
+ return -1;
112
+ }
113
+ function isPartialTail(text, index, lastNonEmptyLine, reason) {
114
+ return index === lastNonEmptyLine
115
+ && !/\r?\n$/u.test(text)
116
+ && /(end of JSON input|unterminated|string|property name|after|expected|unexpected)/iu.test(reason);
117
+ }
118
+ function syncFileDescriptor(fd, options) {
119
+ if (options.durability !== "fsync")
120
+ return;
121
+ try {
122
+ const fdatasync = options.sync?.fdatasyncSync ?? fdatasyncSync;
123
+ fdatasync(fd);
124
+ }
125
+ catch (fdatasyncError) {
126
+ try {
127
+ const fsync = options.sync?.fsyncSync ?? fsyncSync;
128
+ fsync(fd);
129
+ }
130
+ catch (fsyncError) {
131
+ options.onSyncDiagnostic?.(`fdatasync failed (${errorMessage(fdatasyncError)}); fsync fallback failed (${errorMessage(fsyncError)}); continuing with relaxed durability`);
132
+ }
133
+ }
134
+ }
135
+ function errorMessage(error) {
136
+ return error instanceof Error ? error.message : String(error);
137
+ }
138
+ //# sourceMappingURL=jsonl-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-store.js","sourceRoot":"","sources":["../../src/storage/jsonl-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { GoalRecord } from "../goals/goal-types.js";
2
+ import type { RunRecord } from "../runs/run-types.js";
3
+ export declare function validateRunManifest(value: unknown, runId: string): {
4
+ value?: RunRecord;
5
+ error?: Error;
6
+ };
7
+ export declare function validateGoalManifest(value: unknown, goalId: string): {
8
+ value?: GoalRecord;
9
+ error?: Error;
10
+ };
11
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
@@ -0,0 +1,102 @@
1
+ import { parseRuntimeOwner } from "./storage-lease.js";
2
+ export function validateRunManifest(value, runId) {
3
+ if (!isRecord(value))
4
+ return invalidManifest("run", "manifest is not an object");
5
+ if (value.id !== runId)
6
+ return invalidManifest("run", "id does not match storage directory");
7
+ if (typeof value.agentId !== "string")
8
+ return invalidManifest("run", "agentId must be a string");
9
+ if (typeof value.cwd !== "string")
10
+ return invalidManifest("run", "cwd must be a string");
11
+ if (!isRunStatus(value.status))
12
+ return invalidManifest("run", "status is invalid");
13
+ if (typeof value.createdAt !== "number" || typeof value.updatedAt !== "number") {
14
+ return invalidManifest("run", "createdAt and updatedAt must be numbers");
15
+ }
16
+ if ("diagnostics" in value && !Array.isArray(value.diagnostics))
17
+ return invalidManifest("run", "diagnostics must be an array");
18
+ return {
19
+ value: {
20
+ id: value.id,
21
+ agentId: value.agentId,
22
+ cwd: value.cwd,
23
+ status: value.status,
24
+ createdAt: value.createdAt,
25
+ updatedAt: value.updatedAt,
26
+ exitCode: typeof value.exitCode === "number" || value.exitCode === null ? value.exitCode : null,
27
+ signal: typeof value.signal === "string" || value.signal === null ? value.signal : null,
28
+ error: typeof value.error === "string" || value.error === null ? value.error : null,
29
+ errorCode: typeof value.errorCode === "string" || value.errorCode === null ? value.errorCode : null,
30
+ diagnostics: Array.isArray(value.diagnostics) ? value.diagnostics : [],
31
+ owner: parseRuntimeOwner(value.owner),
32
+ },
33
+ };
34
+ }
35
+ export function validateGoalManifest(value, goalId) {
36
+ if (!isRecord(value))
37
+ return invalidManifest("goal", "manifest is not an object");
38
+ if (value.id !== goalId)
39
+ return invalidManifest("goal", "id does not match storage directory");
40
+ if (typeof value.cwd !== "string")
41
+ return invalidManifest("goal", "cwd must be a string");
42
+ if (typeof value.objective !== "string")
43
+ return invalidManifest("goal", "objective must be a string");
44
+ if (!isGoalStatus(value.status))
45
+ return invalidManifest("goal", "status is invalid");
46
+ if (!Array.isArray(value.tasks))
47
+ return invalidManifest("goal", "tasks must be an array");
48
+ if (!value.tasks.every(isStoredTask))
49
+ return invalidManifest("goal", "tasks entries are invalid");
50
+ if (typeof value.createdAt !== "number" || typeof value.updatedAt !== "number") {
51
+ return invalidManifest("goal", "createdAt and updatedAt must be numbers");
52
+ }
53
+ if ("diagnostics" in value && !Array.isArray(value.diagnostics))
54
+ return invalidManifest("goal", "diagnostics must be an array");
55
+ if ("result" in value && value.result !== undefined && !isRunResult(value.result))
56
+ return invalidManifest("goal", "result is invalid");
57
+ return {
58
+ value: {
59
+ id: value.id,
60
+ cwd: value.cwd,
61
+ objective: value.objective,
62
+ status: value.status,
63
+ tasks: value.tasks,
64
+ diagnostics: Array.isArray(value.diagnostics) ? value.diagnostics : [],
65
+ createdAt: value.createdAt,
66
+ updatedAt: value.updatedAt,
67
+ result: value.result,
68
+ owner: parseRuntimeOwner(value.owner),
69
+ },
70
+ };
71
+ }
72
+ export function isRecord(value) {
73
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
74
+ }
75
+ function invalidManifest(kind, reason) {
76
+ return { error: new Error(`${kind} manifest is corrupt: ${reason}`) };
77
+ }
78
+ function isRunStatus(value) {
79
+ return value === "queued" || value === "running" || value === "succeeded" || value === "failed" || value === "canceled";
80
+ }
81
+ function isGoalStatus(value) {
82
+ return value === "planning" || value === "running" || value === "succeeded" || value === "failed" || value === "canceled";
83
+ }
84
+ function isRunResult(value) {
85
+ return value === "success" || value === "failed" || value === "cancelled";
86
+ }
87
+ function isStoredTask(value) {
88
+ if (!isRecord(value))
89
+ return false;
90
+ return typeof value.id === "string"
91
+ && typeof value.title === "string"
92
+ && typeof value.objective === "string"
93
+ && isTaskStatus(value.status)
94
+ && Array.isArray(value.dependencies)
95
+ && value.dependencies.every((dependency) => typeof dependency === "string")
96
+ && typeof value.cwd === "string"
97
+ && typeof value.permissionPolicy === "string";
98
+ }
99
+ function isTaskStatus(value) {
100
+ return value === "pending" || value === "running" || value === "succeeded" || value === "failed" || value === "canceled" || value === "blocked";
101
+ }
102
+ //# sourceMappingURL=manifest-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-validation.js","sourceRoot":"","sources":["../../src/storage/manifest-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { OwnerStatus, RuntimeOwner, StorageLockInspection } from "../public-types.js";
2
+ export declare const STORAGE_LOCK_FILE = "runtime.lock.json";
3
+ export declare const DEFAULT_LEASE_STALE_MS = 30000;
4
+ export interface OwnerInspection {
5
+ status: OwnerStatus;
6
+ owner?: RuntimeOwner;
7
+ ageMs?: number;
8
+ reason?: string;
9
+ }
10
+ export interface StorageLeaseFaultHooks {
11
+ beforeAcquire?: (file: string) => void;
12
+ beforeClose?: (file: string) => void;
13
+ }
14
+ export declare class StorageLease {
15
+ private readonly storageDir;
16
+ private readonly owner;
17
+ private readonly staleMs;
18
+ private readonly faults;
19
+ private closed;
20
+ private lost;
21
+ private constructor();
22
+ static acquire(storageDir: string, init?: {
23
+ staleMs?: number;
24
+ faults?: StorageLeaseFaultHooks;
25
+ }): StorageLease;
26
+ currentOwner(): RuntimeOwner;
27
+ ownsCurrentLock(): boolean;
28
+ heartbeat(): RuntimeOwner | undefined;
29
+ close(): RuntimeOwner | undefined;
30
+ private writeIfCurrentOwner;
31
+ }
32
+ export declare function createRuntimeOwner(): RuntimeOwner;
33
+ export declare function inspectStorageLock(storageDir: string, init?: {
34
+ staleMs?: number;
35
+ }): StorageLockInspection;
36
+ export declare function inspectOwner(owner: RuntimeOwner | undefined, init?: {
37
+ staleMs?: number;
38
+ now?: number;
39
+ }): OwnerInspection;
40
+ export declare function parseRuntimeOwner(value: unknown): RuntimeOwner | undefined;