@h-rig/server 0.0.6-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 (60) hide show
  1. package/README.md +14 -0
  2. package/dist/src/bootstrap.js +161 -0
  3. package/dist/src/index.js +13153 -0
  4. package/dist/src/inspector/agent-runtime.js +1077 -0
  5. package/dist/src/inspector/analysis.js +41 -0
  6. package/dist/src/inspector/discovery.js +137 -0
  7. package/dist/src/inspector/journal.js +518 -0
  8. package/dist/src/inspector/mission.js +562 -0
  9. package/dist/src/inspector/prompt.js +97 -0
  10. package/dist/src/inspector/provider-session.js +65 -0
  11. package/dist/src/inspector/reconcile.js +118 -0
  12. package/dist/src/inspector/review.js +13 -0
  13. package/dist/src/inspector/service.js +1759 -0
  14. package/dist/src/inspector/skills.js +155 -0
  15. package/dist/src/inspector/tools.js +1592 -0
  16. package/dist/src/inspector/types.js +1 -0
  17. package/dist/src/inspector/upstream-sync.js +479 -0
  18. package/dist/src/orchestration.js +402 -0
  19. package/dist/src/remote.js +123 -0
  20. package/dist/src/scheduler.js +84 -0
  21. package/dist/src/server-helpers/broadcasters.js +161 -0
  22. package/dist/src/server-helpers/conversation-snapshot.js +382 -0
  23. package/dist/src/server-helpers/event-emitter.js +41 -0
  24. package/dist/src/server-helpers/github-auth-store.js +155 -0
  25. package/dist/src/server-helpers/github-credentials.js +38 -0
  26. package/dist/src/server-helpers/github-project-status-sync.js +196 -0
  27. package/dist/src/server-helpers/github-projects.js +147 -0
  28. package/dist/src/server-helpers/github-reconciler.js +89 -0
  29. package/dist/src/server-helpers/http-router.js +3781 -0
  30. package/dist/src/server-helpers/http-utils.js +135 -0
  31. package/dist/src/server-helpers/inspector-agent-lifecycle.js +104 -0
  32. package/dist/src/server-helpers/inspector-jobs.js +4145 -0
  33. package/dist/src/server-helpers/issue-analysis.js +362 -0
  34. package/dist/src/server-helpers/normalizers.js +31 -0
  35. package/dist/src/server-helpers/notifications.js +96 -0
  36. package/dist/src/server-helpers/orchestration-ops.js +287 -0
  37. package/dist/src/server-helpers/orchestration.js +39 -0
  38. package/dist/src/server-helpers/plugin-host-cache.js +86 -0
  39. package/dist/src/server-helpers/project-fs-ops.js +194 -0
  40. package/dist/src/server-helpers/project-registry.js +124 -0
  41. package/dist/src/server-helpers/queue-state.js +78 -0
  42. package/dist/src/server-helpers/remote-checkout.js +140 -0
  43. package/dist/src/server-helpers/remote-snapshots.js +119 -0
  44. package/dist/src/server-helpers/run-io.js +262 -0
  45. package/dist/src/server-helpers/run-mutations.js +1784 -0
  46. package/dist/src/server-helpers/run-steering.js +176 -0
  47. package/dist/src/server-helpers/run-writers.js +75 -0
  48. package/dist/src/server-helpers/server-paths.js +27 -0
  49. package/dist/src/server-helpers/snapshot-orchestrator.js +832 -0
  50. package/dist/src/server-helpers/snapshot-service.js +1143 -0
  51. package/dist/src/server-helpers/summaries.js +126 -0
  52. package/dist/src/server-helpers/task-config.js +50 -0
  53. package/dist/src/server-helpers/task-projection.js +98 -0
  54. package/dist/src/server-helpers/terminal-runtime.js +156 -0
  55. package/dist/src/server-helpers/terminal-sessions.js +22 -0
  56. package/dist/src/server-helpers/validation-failure.js +31 -0
  57. package/dist/src/server-helpers/ws-router.js +1308 -0
  58. package/dist/src/server.js +12628 -0
  59. package/dist/src/websocket.js +63 -0
  60. package/package.json +33 -0
@@ -0,0 +1,262 @@
1
+ // @bun
2
+ // packages/server/src/server-helpers/run-io.ts
3
+ import { dirname, resolve } from "path";
4
+ import { closeSync, existsSync, mkdirSync, openSync, readSync, statSync, writeFileSync } from "fs";
5
+ import { createReadStream } from "fs";
6
+ import { createInterface } from "readline";
7
+ import {
8
+ listAuthorityRuns,
9
+ readAuthorityRun,
10
+ readJsonlFile,
11
+ resolveAuthorityRunDir
12
+ } from "@rig/runtime/control-plane/authority-files";
13
+
14
+ // packages/server/src/server-helpers/normalizers.ts
15
+ function normalizeString(value) {
16
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
17
+ }
18
+
19
+ // packages/server/src/server-helpers/run-io.ts
20
+ function matchesRunFilter(entry, filter) {
21
+ return (!filter.runId || entry.runId === filter.runId) && (!filter.taskId || entry.taskId === filter.taskId);
22
+ }
23
+ function readApprovalsForRuns(projectRoot, runs, filter = {}) {
24
+ return runs.filter((entry) => matchesRunFilter(entry, filter)).flatMap((entry) => readJsonlFile(resolve(resolveAuthorityRunDir(projectRoot, entry.runId), "approvals.jsonl")).flatMap((record) => {
25
+ if (!record || typeof record !== "object") {
26
+ return [];
27
+ }
28
+ const value = record;
29
+ return [
30
+ {
31
+ runId: entry.runId,
32
+ taskId: entry.taskId,
33
+ requestId: normalizeString(value.requestId) ?? normalizeString(value.id),
34
+ status: normalizeString(value.status),
35
+ record: value
36
+ }
37
+ ];
38
+ }));
39
+ }
40
+ function readApprovals(projectRoot, filter = {}) {
41
+ return readApprovalsForRuns(projectRoot, listAuthorityRuns(projectRoot), filter);
42
+ }
43
+ function readUserInputsForRuns(projectRoot, runs, filter = {}) {
44
+ return runs.filter((entry) => matchesRunFilter(entry, filter)).flatMap((entry) => readJsonlFile(resolve(resolveAuthorityRunDir(projectRoot, entry.runId), "user-input.jsonl")).flatMap((record) => {
45
+ if (!record || typeof record !== "object") {
46
+ return [];
47
+ }
48
+ const value = record;
49
+ return [
50
+ {
51
+ runId: entry.runId,
52
+ taskId: entry.taskId,
53
+ requestId: normalizeString(value.requestId) ?? normalizeString(value.id),
54
+ status: normalizeString(value.status),
55
+ record: value
56
+ }
57
+ ];
58
+ }));
59
+ }
60
+ function readUserInputs(projectRoot, filter = {}) {
61
+ return readUserInputsForRuns(projectRoot, listAuthorityRuns(projectRoot), filter);
62
+ }
63
+ function writeRunJsonlFile(projectRoot, runId, fileName, rows) {
64
+ const filePath = resolve(resolveAuthorityRunDir(projectRoot, runId), fileName);
65
+ mkdirSync(dirname(filePath), { recursive: true });
66
+ const next = rows.map((row) => JSON.stringify(row)).join(`
67
+ `);
68
+ writeFileSync(filePath, next.length > 0 ? `${next}
69
+ ` : "", "utf8");
70
+ }
71
+ function resolveApproval(projectRoot, input) {
72
+ const approvalsPath = resolve(resolveAuthorityRunDir(projectRoot, input.runId), "approvals.jsonl");
73
+ const approvals = readJsonlFile(approvalsPath);
74
+ const resolvedAt = new Date().toISOString();
75
+ const rows = approvals.map((entry) => entry.requestId === input.requestId || entry.id === input.requestId ? {
76
+ ...entry,
77
+ status: "resolved",
78
+ decision: input.decision,
79
+ note: input.note ?? null,
80
+ resolvedAt
81
+ } : entry);
82
+ writeRunJsonlFile(projectRoot, input.runId, "approvals.jsonl", rows);
83
+ return { ok: true, runId: input.runId, requestId: input.requestId, decision: input.decision };
84
+ }
85
+ function respondToUserInput(projectRoot, input) {
86
+ const requestsPath = resolve(resolveAuthorityRunDir(projectRoot, input.runId), "user-input.jsonl");
87
+ const requests = readJsonlFile(requestsPath);
88
+ const resolvedAt = new Date().toISOString();
89
+ const rows = requests.map((entry) => entry.requestId === input.requestId || entry.id === input.requestId ? {
90
+ ...entry,
91
+ status: "resolved",
92
+ answers: input.answers,
93
+ respondedAt: resolvedAt,
94
+ resolvedAt
95
+ } : entry);
96
+ writeRunJsonlFile(projectRoot, input.runId, "user-input.jsonl", rows);
97
+ return { ok: true, runId: input.runId, requestId: input.requestId, answers: input.answers };
98
+ }
99
+ function isGenericRunFailure(value) {
100
+ return typeof value === "string" && /^Task run failed \([^)]*\)$/i.test(value.trim());
101
+ }
102
+ function summarizeUsefulRunError(projectRoot, runId, fallback) {
103
+ const logs = readJsonlFileTail(runLogsPath(projectRoot, runId), { limit: 80, maxBytes: 512 * 1024 }).filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry)));
104
+ const errorLines = logs.filter((entry) => normalizeString(entry.tone) === "error" || normalizeString(entry.status) === "failed").map((entry) => normalizeString(entry.detail)).filter((entry) => Boolean(entry && !isGenericRunFailure(entry)));
105
+ const taskSourceFailure = errorLines.find((line) => /failed to update task source/i.test(line));
106
+ if (taskSourceFailure)
107
+ return `Task source update failed: ${taskSourceFailure}`;
108
+ const moduleFailure = errorLines.find((line) => /cannot find module/i.test(line));
109
+ if (moduleFailure)
110
+ return `Runtime module resolution failed: ${moduleFailure}`;
111
+ const providerFailure = errorLines.find((line) => /no api key found|unauthorized|authentication failed|invalid api key/i.test(line));
112
+ if (providerFailure)
113
+ return `Provider authentication failed: ${providerFailure}`;
114
+ const nonGeneric = errorLines.at(-1);
115
+ return nonGeneric ?? (typeof fallback === "string" ? fallback : null);
116
+ }
117
+ function readRunDetails(projectRoot, runId) {
118
+ const run = readAuthorityRun(projectRoot, runId);
119
+ if (!run) {
120
+ return null;
121
+ }
122
+ const usefulErrorText = isGenericRunFailure(run.errorText) ? summarizeUsefulRunError(projectRoot, runId, run.errorText) : null;
123
+ return {
124
+ run: usefulErrorText ? { ...run, errorText: usefulErrorText } : run,
125
+ timeline: readJsonlFile(resolve(resolveAuthorityRunDir(projectRoot, runId), "timeline.jsonl")),
126
+ approvals: readApprovals(projectRoot, { runId }),
127
+ userInputs: readUserInputs(projectRoot, { runId })
128
+ };
129
+ }
130
+ function runTimelinePath(projectRoot, runId) {
131
+ return resolve(resolveAuthorityRunDir(projectRoot, runId), "timeline.jsonl");
132
+ }
133
+ function runLogsPath(projectRoot, runId) {
134
+ return resolve(resolveAuthorityRunDir(projectRoot, runId), "logs.jsonl");
135
+ }
136
+ function parseJsonlRecords(lines) {
137
+ return lines.map((line) => line.trim()).filter(Boolean).flatMap((line) => {
138
+ try {
139
+ return [JSON.parse(line)];
140
+ } catch {
141
+ return [];
142
+ }
143
+ });
144
+ }
145
+ function readJsonlFileTail(path, options) {
146
+ const limit = Math.max(0, Math.trunc(options.limit));
147
+ if (limit === 0 || !existsSync(path))
148
+ return [];
149
+ const maxBytes = Math.max(1024, Math.trunc(options.maxBytes ?? 256 * 1024));
150
+ const size = statSync(path).size;
151
+ if (size === 0)
152
+ return [];
153
+ const start = Math.max(0, size - maxBytes);
154
+ const length = size - start;
155
+ const buffer = Buffer.alloc(length);
156
+ const fd = openSync(path, "r");
157
+ try {
158
+ readSync(fd, buffer, 0, length, start);
159
+ } finally {
160
+ closeSync(fd);
161
+ }
162
+ const text = buffer.toString("utf8");
163
+ const lines = text.split(/\r?\n/);
164
+ const completeLines = start > 0 ? lines.slice(1) : lines;
165
+ return parseJsonlRecords(completeLines.filter(Boolean).slice(-limit));
166
+ }
167
+ function readRawRunLogs(projectRoot, runId) {
168
+ return readJsonlFile(runLogsPath(projectRoot, runId)).filter((entry) => Boolean(entry && typeof entry === "object"));
169
+ }
170
+ var INITIAL_RUN_LOG_TAIL_MAX_BYTES = 8 * 1024 * 1024;
171
+ async function readRunLogsPage(projectRoot, runId, options = {}) {
172
+ const limit = Math.max(1, Math.min(Math.trunc(options.limit ?? 200), 500));
173
+ const cursor = options.cursor == null ? null : Number.parseInt(options.cursor, 10);
174
+ const logsPath = runLogsPath(projectRoot, runId);
175
+ if ((options.cursor == null || !Number.isFinite(cursor)) && existsSync(logsPath)) {
176
+ const size = statSync(logsPath).size;
177
+ if (size > INITIAL_RUN_LOG_TAIL_MAX_BYTES) {
178
+ const tail = readJsonlFileTail(logsPath, {
179
+ limit,
180
+ maxBytes: INITIAL_RUN_LOG_TAIL_MAX_BYTES
181
+ }).filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry)));
182
+ return {
183
+ entries: tail.toReversed(),
184
+ nextCursor: null,
185
+ hasMore: true
186
+ };
187
+ }
188
+ }
189
+ const endExclusive = cursor == null || !Number.isFinite(cursor) ? Number.POSITIVE_INFINITY : Math.max(0, cursor);
190
+ const window = [];
191
+ let index = 0;
192
+ let hasMore = false;
193
+ const stream = createReadStream(logsPath, { encoding: "utf8" });
194
+ stream.on("error", (error) => {
195
+ if (error.code !== "ENOENT") {
196
+ stream.destroy(error);
197
+ }
198
+ });
199
+ const lines = createInterface({ input: stream, crlfDelay: Infinity });
200
+ try {
201
+ for await (const line of lines) {
202
+ const currentIndex = index;
203
+ index += 1;
204
+ if (currentIndex >= endExclusive) {
205
+ break;
206
+ }
207
+ const trimmed = line.trim();
208
+ if (trimmed.length === 0) {
209
+ continue;
210
+ }
211
+ try {
212
+ const parsed = JSON.parse(trimmed);
213
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
214
+ window.push({ index: currentIndex, entry: parsed });
215
+ }
216
+ } catch {
217
+ window.push({
218
+ index: currentIndex,
219
+ entry: { title: "Unparsed log line", detail: line, tone: "info" }
220
+ });
221
+ }
222
+ if (window.length > limit) {
223
+ window.shift();
224
+ hasMore = true;
225
+ }
226
+ }
227
+ } catch (error) {
228
+ const code = error.code;
229
+ if (code !== "ENOENT") {
230
+ throw error;
231
+ }
232
+ }
233
+ return {
234
+ entries: window.toReversed().map((item) => item.entry),
235
+ nextCursor: hasMore ? String(window[0]?.index ?? 0) : null,
236
+ hasMore
237
+ };
238
+ }
239
+ function readLatestRawRunLog(projectRoot, runId) {
240
+ const logs = readJsonlFileTail(runLogsPath(projectRoot, runId), { limit: 20 });
241
+ return logs.findLast((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) ?? null;
242
+ }
243
+ function remoteArtifactsRoot(projectRoot, runId) {
244
+ return resolve(resolveAuthorityRunDir(projectRoot, runId), "remote-artifacts");
245
+ }
246
+ export {
247
+ writeRunJsonlFile,
248
+ runTimelinePath,
249
+ runLogsPath,
250
+ respondToUserInput,
251
+ resolveApproval,
252
+ remoteArtifactsRoot,
253
+ readUserInputsForRuns,
254
+ readUserInputs,
255
+ readRunLogsPage,
256
+ readRunDetails,
257
+ readRawRunLogs,
258
+ readLatestRawRunLog,
259
+ readJsonlFileTail,
260
+ readApprovalsForRuns,
261
+ readApprovals
262
+ };