@revisium/orchestrator 0.0.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/LICENSE +21 -0
- package/README.md +20 -0
- package/bin/revo.js +2 -0
- package/control-plane/bootstrap.config.json +931 -0
- package/dist/app.module.js +28 -0
- package/dist/app.module.js.map +1 -0
- package/dist/cli/commands/bootstrap.js +39 -0
- package/dist/cli/commands/bootstrap.js.map +1 -0
- package/dist/cli/commands/dev.js +143 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/inbox.js +288 -0
- package/dist/cli/commands/inbox.js.map +1 -0
- package/dist/cli/commands/mcp.js +16 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/playbook.js +74 -0
- package/dist/cli/commands/playbook.js.map +1 -0
- package/dist/cli/commands/poll-workflow-state.js +144 -0
- package/dist/cli/commands/poll-workflow-state.js.map +1 -0
- package/dist/cli/commands/revisium-context.js +23 -0
- package/dist/cli/commands/revisium-context.js.map +1 -0
- package/dist/cli/commands/revisium-helpers.js +61 -0
- package/dist/cli/commands/revisium-helpers.js.map +1 -0
- package/dist/cli/commands/revisium.js +89 -0
- package/dist/cli/commands/revisium.js.map +1 -0
- package/dist/cli/commands/run.js +426 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/work.js +149 -0
- package/dist/cli/commands/work.js.map +1 -0
- package/dist/cli/config.js +2 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.js +32 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/live-guard.js +49 -0
- package/dist/cli/live-guard.js.map +1 -0
- package/dist/cli/needs-host.js +78 -0
- package/dist/cli/needs-host.js.map +1 -0
- package/dist/cli/program.js +37 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/config.js +102 -0
- package/dist/config.js.map +1 -0
- package/dist/control-plane/client-transport.js +146 -0
- package/dist/control-plane/client-transport.js.map +1 -0
- package/dist/control-plane/data-access.js +99 -0
- package/dist/control-plane/data-access.js.map +1 -0
- package/dist/control-plane/definitions.js +120 -0
- package/dist/control-plane/definitions.js.map +1 -0
- package/dist/control-plane/errors.js +13 -0
- package/dist/control-plane/errors.js.map +1 -0
- package/dist/control-plane/inbox.js +261 -0
- package/dist/control-plane/inbox.js.map +1 -0
- package/dist/control-plane/index.js +6 -0
- package/dist/control-plane/index.js.map +1 -0
- package/dist/control-plane/json-fields.js +68 -0
- package/dist/control-plane/json-fields.js.map +1 -0
- package/dist/control-plane/resolve-cwd.js +75 -0
- package/dist/control-plane/resolve-cwd.js.map +1 -0
- package/dist/control-plane/steps.js +381 -0
- package/dist/control-plane/steps.js.map +1 -0
- package/dist/control-plane/tables.js +13 -0
- package/dist/control-plane/tables.js.map +1 -0
- package/dist/control-plane/versioned-meaning.js +53 -0
- package/dist/control-plane/versioned-meaning.js.map +1 -0
- package/dist/engine/dbos.module.js +18 -0
- package/dist/engine/dbos.module.js.map +1 -0
- package/dist/engine/dbos.service.js +296 -0
- package/dist/engine/dbos.service.js.map +1 -0
- package/dist/engine/ensure-postgres.js +80 -0
- package/dist/engine/ensure-postgres.js.map +1 -0
- package/dist/engine/types.js +2 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/host/ensure-revisium.js +269 -0
- package/dist/host/ensure-revisium.js.map +1 -0
- package/dist/host/host.lifecycle.js +75 -0
- package/dist/host/host.lifecycle.js.map +1 -0
- package/dist/mcp/mcp-capabilities.js +47 -0
- package/dist/mcp/mcp-capabilities.js.map +1 -0
- package/dist/mcp/mcp-facade.service.js +130 -0
- package/dist/mcp/mcp-facade.service.js.map +1 -0
- package/dist/mcp/mcp-stdio.service.js +48 -0
- package/dist/mcp/mcp-stdio.service.js.map +1 -0
- package/dist/mcp/mcp-tools.js +264 -0
- package/dist/mcp/mcp-tools.js.map +1 -0
- package/dist/mcp/mcp.module.js +21 -0
- package/dist/mcp/mcp.module.js.map +1 -0
- package/dist/package-info.js +10 -0
- package/dist/package-info.js.map +1 -0
- package/dist/pipeline/await-human.js +62 -0
- package/dist/pipeline/await-human.js.map +1 -0
- package/dist/pipeline/develop-task.workflow.js +497 -0
- package/dist/pipeline/develop-task.workflow.js.map +1 -0
- package/dist/pipeline/pipeline.module.js +34 -0
- package/dist/pipeline/pipeline.module.js.map +1 -0
- package/dist/playbook/catalog-loader.js +145 -0
- package/dist/playbook/catalog-loader.js.map +1 -0
- package/dist/playbook/errors.js +14 -0
- package/dist/playbook/errors.js.map +1 -0
- package/dist/playbook/import-mapper.js +186 -0
- package/dist/playbook/import-mapper.js.map +1 -0
- package/dist/playbook/manifest.js +60 -0
- package/dist/playbook/manifest.js.map +1 -0
- package/dist/playbook/playbook-installer.js +51 -0
- package/dist/playbook/playbook-installer.js.map +1 -0
- package/dist/playbook/prompt-composer.js +34 -0
- package/dist/playbook/prompt-composer.js.map +1 -0
- package/dist/playbook/source-resolver.js +105 -0
- package/dist/playbook/source-resolver.js.map +1 -0
- package/dist/poller/pr-readiness-core.js +656 -0
- package/dist/poller/pr-readiness-core.js.map +1 -0
- package/dist/poller/pr-readiness.js +91 -0
- package/dist/poller/pr-readiness.js.map +1 -0
- package/dist/revisium/inbox.service.js +67 -0
- package/dist/revisium/inbox.service.js.map +1 -0
- package/dist/revisium/playbooks.service.js +99 -0
- package/dist/revisium/playbooks.service.js.map +1 -0
- package/dist/revisium/revisium.module.js +55 -0
- package/dist/revisium/revisium.module.js.map +1 -0
- package/dist/revisium/roles.service.js +79 -0
- package/dist/revisium/roles.service.js.map +1 -0
- package/dist/revisium/run.service.js +182 -0
- package/dist/revisium/run.service.js.map +1 -0
- package/dist/revisium/tokens.js +7 -0
- package/dist/revisium/tokens.js.map +1 -0
- package/dist/run/append-event.js +112 -0
- package/dist/run/append-event.js.map +1 -0
- package/dist/run/cancel-run.js +47 -0
- package/dist/run/cancel-run.js.map +1 -0
- package/dist/run/create-run.js +208 -0
- package/dist/run/create-run.js.map +1 -0
- package/dist/run/fail-run.js +20 -0
- package/dist/run/fail-run.js.map +1 -0
- package/dist/run/inspect-run.js +287 -0
- package/dist/run/inspect-run.js.map +1 -0
- package/dist/run/terminal-run-status.js +45 -0
- package/dist/run/terminal-run-status.js.map +1 -0
- package/dist/runners/claude-code.service.js +48 -0
- package/dist/runners/claude-code.service.js.map +1 -0
- package/dist/runners/gh-identity.js +108 -0
- package/dist/runners/gh-identity.js.map +1 -0
- package/dist/runners/integrator.js +417 -0
- package/dist/runners/integrator.js.map +1 -0
- package/dist/runners/runner.module.js +40 -0
- package/dist/runners/runner.module.js.map +1 -0
- package/dist/runners/tokens.js +7 -0
- package/dist/runners/tokens.js.map +1 -0
- package/dist/task-control-plane/pr-readiness.service.js +33 -0
- package/dist/task-control-plane/pr-readiness.service.js.map +1 -0
- package/dist/task-control-plane/task-control-plane-api.service.js +440 -0
- package/dist/task-control-plane/task-control-plane-api.service.js.map +1 -0
- package/dist/task-control-plane/task-control-plane.module.js +23 -0
- package/dist/task-control-plane/task-control-plane.module.js.map +1 -0
- package/dist/worker/build-context.js +39 -0
- package/dist/worker/build-context.js.map +1 -0
- package/dist/worker/claude-code-runner.js +135 -0
- package/dist/worker/claude-code-runner.js.map +1 -0
- package/dist/worker/git-worktree-manager.js +84 -0
- package/dist/worker/git-worktree-manager.js.map +1 -0
- package/dist/worker/loop.js +122 -0
- package/dist/worker/loop.js.map +1 -0
- package/dist/worker/process-executor.js +62 -0
- package/dist/worker/process-executor.js.map +1 -0
- package/dist/worker/result-envelope.js +134 -0
- package/dist/worker/result-envelope.js.map +1 -0
- package/dist/worker/runner-dispatch.js +20 -0
- package/dist/worker/runner-dispatch.js.map +1 -0
- package/dist/worker/runner.js +2 -0
- package/dist/worker/runner.js.map +1 -0
- package/dist/worker/script-runner.js +28 -0
- package/dist/worker/script-runner.js.map +1 -0
- package/dist/worker/stub-runner.js +59 -0
- package/dist/worker/stub-runner.js.map +1 -0
- package/dist/worker/worker-id.js +18 -0
- package/dist/worker/worker-id.js.map +1 -0
- package/dist/worker/worktree-manager.js +7 -0
- package/dist/worker/worktree-manager.js.map +1 -0
- package/package.json +66 -0
- package/revisium.config.json +10 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
const GLOBAL_CAP = 500;
|
|
2
|
+
function str(v) {
|
|
3
|
+
return typeof v === 'string' ? v : '';
|
|
4
|
+
}
|
|
5
|
+
function num(v) {
|
|
6
|
+
return typeof v === 'number' ? v : 0;
|
|
7
|
+
}
|
|
8
|
+
function strArr(v) {
|
|
9
|
+
if (!Array.isArray(v))
|
|
10
|
+
return [];
|
|
11
|
+
return v.map((x) => str(x));
|
|
12
|
+
}
|
|
13
|
+
function toRunSummary(row) {
|
|
14
|
+
return {
|
|
15
|
+
runId: row.rowId,
|
|
16
|
+
title: str(row.data.title),
|
|
17
|
+
status: str(row.data.status),
|
|
18
|
+
priority: num(row.data.priority),
|
|
19
|
+
createdAt: str(row.data.created_at ?? row.createdAt),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function toRunDetail(row) {
|
|
23
|
+
return {
|
|
24
|
+
...toRunSummary(row),
|
|
25
|
+
description: str(row.data.description),
|
|
26
|
+
scope: str(row.data.scope),
|
|
27
|
+
repos: strArr(row.data.repos),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function toTaskSummary(row) {
|
|
31
|
+
return {
|
|
32
|
+
taskId: row.rowId,
|
|
33
|
+
title: str(row.data.title),
|
|
34
|
+
status: str(row.data.status),
|
|
35
|
+
roleHint: str(row.data.role_hint),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function toStepSummary(row) {
|
|
39
|
+
return {
|
|
40
|
+
stepId: row.rowId,
|
|
41
|
+
role: str(row.data.role),
|
|
42
|
+
kind: str(row.data.kind),
|
|
43
|
+
status: str(row.data.status),
|
|
44
|
+
attemptCount: num(row.data.attempt_count),
|
|
45
|
+
maxAttempts: num(row.data.max_attempts),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function toEventSummary(row) {
|
|
49
|
+
return {
|
|
50
|
+
eventId: row.rowId,
|
|
51
|
+
type: str(row.data.type),
|
|
52
|
+
actor: str(row.data.actor),
|
|
53
|
+
createdAt: str(row.data.created_at ?? row.createdAt),
|
|
54
|
+
taskId: str(row.data.task_id),
|
|
55
|
+
stepId: str(row.data.step_id),
|
|
56
|
+
payload: row.data.payload ?? null,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function toAttemptSummary(row) {
|
|
60
|
+
return {
|
|
61
|
+
attemptId: row.rowId,
|
|
62
|
+
stepId: str(row.data.step_id),
|
|
63
|
+
iteration: num(row.data.iteration),
|
|
64
|
+
status: str(row.data.status),
|
|
65
|
+
verdict: str(row.data.verdict),
|
|
66
|
+
modelProfile: str(row.data.model_profile),
|
|
67
|
+
inputTokens: num(row.data.input_tokens),
|
|
68
|
+
outputTokens: num(row.data.output_tokens),
|
|
69
|
+
costAmount: num(row.data.cost_amount),
|
|
70
|
+
durationMs: num(row.data.duration_ms),
|
|
71
|
+
outputSummary: str(row.data.output_summary),
|
|
72
|
+
lesson: str(row.data.lesson),
|
|
73
|
+
error: str(row.data.error),
|
|
74
|
+
startedAt: str(row.data.started_at ?? row.createdAt),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Prisma path+equals accepts scalar values; the SDK types equals as an object due to generated types.
|
|
78
|
+
function runIdWhere(runId) {
|
|
79
|
+
return { data: { path: 'run_id', equals: runId } };
|
|
80
|
+
}
|
|
81
|
+
export async function listRuns(da, filter) {
|
|
82
|
+
await da.assertReady();
|
|
83
|
+
const rows = await da.listRows('task_runs', {
|
|
84
|
+
first: GLOBAL_CAP,
|
|
85
|
+
orderBy: [{ field: 'createdAt', direction: 'desc' }],
|
|
86
|
+
});
|
|
87
|
+
if (rows.length === GLOBAL_CAP) {
|
|
88
|
+
process.stderr.write(`warning: task_runs results may be incomplete (cap=${GLOBAL_CAP})\n`);
|
|
89
|
+
}
|
|
90
|
+
let result = rows.map(toRunSummary);
|
|
91
|
+
if (filter?.status)
|
|
92
|
+
result = result.filter((r) => r.status === filter.status);
|
|
93
|
+
if (filter?.limit !== undefined)
|
|
94
|
+
result = result.slice(0, filter.limit);
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
export async function showRun(da, runId) {
|
|
98
|
+
await da.assertReady();
|
|
99
|
+
const runRow = await da.getRow('task_runs', runId);
|
|
100
|
+
if (!runRow)
|
|
101
|
+
return null;
|
|
102
|
+
const where = runIdWhere(runId);
|
|
103
|
+
const tasks = await da.listRows('tasks', {
|
|
104
|
+
first: GLOBAL_CAP,
|
|
105
|
+
orderBy: [{ field: 'createdAt', direction: 'asc' }],
|
|
106
|
+
where,
|
|
107
|
+
});
|
|
108
|
+
const steps = await da.listRows('steps', {
|
|
109
|
+
first: GLOBAL_CAP,
|
|
110
|
+
orderBy: [{ field: 'createdAt', direction: 'asc' }],
|
|
111
|
+
where,
|
|
112
|
+
});
|
|
113
|
+
const taskIds = new Set(tasks.map((t) => t.rowId));
|
|
114
|
+
const stepsByTaskId = new Map();
|
|
115
|
+
for (const step of steps) {
|
|
116
|
+
const tid = str(step.data.task_id);
|
|
117
|
+
if (!taskIds.has(tid))
|
|
118
|
+
continue;
|
|
119
|
+
const list = stepsByTaskId.get(tid) ?? [];
|
|
120
|
+
list.push(toStepSummary(step));
|
|
121
|
+
stepsByTaskId.set(tid, list);
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
run: toRunDetail(runRow),
|
|
125
|
+
tasks: tasks.map((t) => ({ ...toTaskSummary(t), steps: stepsByTaskId.get(t.rowId) ?? [] })),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export async function listRunEvents(da, runId, filter) {
|
|
129
|
+
await da.assertReady();
|
|
130
|
+
const rows = await da.listRows('events', {
|
|
131
|
+
first: GLOBAL_CAP,
|
|
132
|
+
orderBy: [{ field: 'createdAt', direction: 'asc' }],
|
|
133
|
+
where: runIdWhere(runId),
|
|
134
|
+
});
|
|
135
|
+
let events = rows.map(toEventSummary);
|
|
136
|
+
if (filter?.type)
|
|
137
|
+
events = events.filter((e) => e.type === filter.type);
|
|
138
|
+
if (filter?.limit !== undefined)
|
|
139
|
+
events = events.slice(0, filter.limit);
|
|
140
|
+
return events;
|
|
141
|
+
}
|
|
142
|
+
/** List per-attempt observability rows for a run, oldest-first (0008 #4 — `run log`). */
|
|
143
|
+
export async function listRunAttempts(da, runId, filter) {
|
|
144
|
+
await da.assertReady();
|
|
145
|
+
const rows = await da.listRows('attempts', {
|
|
146
|
+
first: GLOBAL_CAP,
|
|
147
|
+
orderBy: [{ field: 'createdAt', direction: 'asc' }],
|
|
148
|
+
where: runIdWhere(runId),
|
|
149
|
+
});
|
|
150
|
+
let attempts = rows.map(toAttemptSummary);
|
|
151
|
+
if (filter?.limit !== undefined)
|
|
152
|
+
attempts = attempts.slice(0, filter.limit);
|
|
153
|
+
return attempts;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* getRunFailure — read the run-row status + the persisted run_failed reason (0008 #2).
|
|
157
|
+
*
|
|
158
|
+
* Used by `run start --wait` so a FAILURE terminal DBOS status surfaces WHY the run failed
|
|
159
|
+
* instead of a bare "status: ERROR". Returns null when the run does not exist.
|
|
160
|
+
*/
|
|
161
|
+
export async function getRunFailure(da, runId) {
|
|
162
|
+
await da.assertReady();
|
|
163
|
+
const runRow = await da.getRow('task_runs', runId);
|
|
164
|
+
if (!runRow)
|
|
165
|
+
return null;
|
|
166
|
+
const runStatus = str(runRow.data.status);
|
|
167
|
+
const rows = await da.listRows('events', {
|
|
168
|
+
first: GLOBAL_CAP,
|
|
169
|
+
orderBy: [{ field: 'createdAt', direction: 'desc' }],
|
|
170
|
+
where: runIdWhere(runId),
|
|
171
|
+
});
|
|
172
|
+
const failed = rows.find((r) => str(r.data.type) === 'run_failed');
|
|
173
|
+
const payload = failed?.data.payload;
|
|
174
|
+
const reason = payload && typeof payload === 'object' && !Array.isArray(payload)
|
|
175
|
+
? payload.reason
|
|
176
|
+
: undefined;
|
|
177
|
+
return { runStatus, reason: typeof reason === 'string' && reason.length > 0 ? reason : undefined };
|
|
178
|
+
}
|
|
179
|
+
// ─────────────────────── formatters ───────────────────────
|
|
180
|
+
function pad(s, width) {
|
|
181
|
+
return s.length >= width ? s : s + ' '.repeat(width - s.length);
|
|
182
|
+
}
|
|
183
|
+
export function formatRunList(runs) {
|
|
184
|
+
const COL = { id: 27, status: 8, pri: 5, ts: 22, title: 0 };
|
|
185
|
+
const header = pad('RUN', COL.id) +
|
|
186
|
+
pad('STATUS', COL.status) +
|
|
187
|
+
pad('PRI', COL.pri) +
|
|
188
|
+
pad('CREATED', COL.ts) +
|
|
189
|
+
'TITLE';
|
|
190
|
+
const lines = runs.map((r) => {
|
|
191
|
+
const ts = r.createdAt ? r.createdAt.slice(0, 19) + 'Z' : '';
|
|
192
|
+
return (pad(r.runId, COL.id) +
|
|
193
|
+
pad(r.status, COL.status) +
|
|
194
|
+
pad(String(r.priority), COL.pri) +
|
|
195
|
+
pad(ts, COL.ts) +
|
|
196
|
+
r.title);
|
|
197
|
+
});
|
|
198
|
+
const summary = `(${runs.length} run${runs.length === 1 ? '' : 's'})`;
|
|
199
|
+
return [header, ...lines, summary].join('\n');
|
|
200
|
+
}
|
|
201
|
+
export function formatRunDetail(detail) {
|
|
202
|
+
const r = detail.run;
|
|
203
|
+
const ts = r.createdAt ? r.createdAt.slice(0, 19) + 'Z' : '';
|
|
204
|
+
const lines = [
|
|
205
|
+
`run ${r.runId}`,
|
|
206
|
+
`status ${r.status}`,
|
|
207
|
+
`title ${r.title}`,
|
|
208
|
+
`created ${ts}`,
|
|
209
|
+
];
|
|
210
|
+
if (r.description)
|
|
211
|
+
lines.push(`desc ${r.description}`);
|
|
212
|
+
if (r.scope)
|
|
213
|
+
lines.push(`scope ${r.scope}`);
|
|
214
|
+
if (r.repos.length > 0)
|
|
215
|
+
lines.push(`repos ${r.repos.join(', ')}`);
|
|
216
|
+
lines.push('');
|
|
217
|
+
for (const task of detail.tasks) {
|
|
218
|
+
lines.push(` task ${task.taskId}`, ` title ${task.title}`, ` status ${task.status}`, ` role ${task.roleHint}`);
|
|
219
|
+
for (const step of task.steps) {
|
|
220
|
+
lines.push(` step ${step.stepId}`, ` role ${step.role} kind=${step.kind} status=${step.status} attempts=${step.attemptCount}/${step.maxAttempts}`);
|
|
221
|
+
}
|
|
222
|
+
lines.push('');
|
|
223
|
+
}
|
|
224
|
+
return lines.join('\n').trimEnd();
|
|
225
|
+
}
|
|
226
|
+
export function formatEventList(events) {
|
|
227
|
+
const COL = { id: 45, type: 16, actor: 14, ts: 22 };
|
|
228
|
+
const header = pad('EVENT', COL.id) +
|
|
229
|
+
pad('TYPE', COL.type) +
|
|
230
|
+
pad('ACTOR', COL.actor) +
|
|
231
|
+
'CREATED';
|
|
232
|
+
const lines = events.map((e) => {
|
|
233
|
+
const ts = e.createdAt ? e.createdAt.slice(0, 19) + 'Z' : '';
|
|
234
|
+
return (pad(e.eventId, COL.id) +
|
|
235
|
+
pad(e.type, COL.type) +
|
|
236
|
+
pad(e.actor, COL.actor) +
|
|
237
|
+
ts);
|
|
238
|
+
});
|
|
239
|
+
const summary = `(${events.length} event${events.length === 1 ? '' : 's'})`;
|
|
240
|
+
return [header, ...lines, summary].join('\n');
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* formatEventListVerbose — like formatRunEvents but expands each event's payload (0008 #4).
|
|
244
|
+
* Surfaces the agent output / verdict / reason that the compact table drops.
|
|
245
|
+
*/
|
|
246
|
+
export function formatEventListVerbose(events) {
|
|
247
|
+
const blocks = events.map((e) => {
|
|
248
|
+
const ts = e.createdAt ? e.createdAt.slice(0, 19) + 'Z' : '';
|
|
249
|
+
const head = `${e.type} actor=${e.actor} ${ts} (${e.eventId})`;
|
|
250
|
+
const payloadJson = JSON.stringify(e.payload ?? null, null, 2)
|
|
251
|
+
.split('\n')
|
|
252
|
+
.map((l) => ' ' + l)
|
|
253
|
+
.join('\n');
|
|
254
|
+
return `${head}\n${payloadJson}`;
|
|
255
|
+
});
|
|
256
|
+
const summary = `(${events.length} event${events.length === 1 ? '' : 's'})`;
|
|
257
|
+
return [...blocks, summary].join('\n');
|
|
258
|
+
}
|
|
259
|
+
/** Two-decimal USD; '$0.0000' is overly noisy, so show 4 dp only when sub-cent. */
|
|
260
|
+
function fmtUsd(amount) {
|
|
261
|
+
return amount > 0 && amount < 0.01 ? `$${amount.toFixed(4)}` : `$${amount.toFixed(2)}`;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* formatAttemptList — per-attempt observability dump for `run log <runId>` (0008 #4).
|
|
265
|
+
* Shows verdict, model, tokens, cost, duration, iteration, status, and the output summary.
|
|
266
|
+
*/
|
|
267
|
+
export function formatAttemptList(attempts) {
|
|
268
|
+
if (attempts.length === 0)
|
|
269
|
+
return '(0 attempts)';
|
|
270
|
+
const blocks = attempts.map((a) => {
|
|
271
|
+
const lines = [
|
|
272
|
+
`attempt ${a.attemptId} step=${a.stepId}`,
|
|
273
|
+
` iter=${a.iteration} status=${a.status} verdict=${a.verdict || '-'} model=${a.modelProfile || '-'}`,
|
|
274
|
+
` tokens=${a.inputTokens}in/${a.outputTokens}out cost=${fmtUsd(a.costAmount)} duration=${a.durationMs}ms`,
|
|
275
|
+
];
|
|
276
|
+
if (a.outputSummary)
|
|
277
|
+
lines.push(` output ${a.outputSummary}`);
|
|
278
|
+
if (a.lesson)
|
|
279
|
+
lines.push(` lesson ${a.lesson}`);
|
|
280
|
+
if (a.error)
|
|
281
|
+
lines.push(` error ${a.error}`);
|
|
282
|
+
return lines.join('\n');
|
|
283
|
+
});
|
|
284
|
+
const summary = `(${attempts.length} attempt${attempts.length === 1 ? '' : 's'})`;
|
|
285
|
+
return [...blocks, summary].join('\n');
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=inspect-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect-run.js","sourceRoot":"","sources":["../../src/run/inspect-run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ControlPlaneError } from '../control-plane/errors.js';
|
|
2
|
+
import { fnv1a64Hex } from '../control-plane/steps.js';
|
|
3
|
+
/**
|
|
4
|
+
* recordTerminalRunStatus — write `<eventType>` event (event-first) + patch task_runs to `status`.
|
|
5
|
+
* Returns `{ previousStatus }`, or null when the run does not exist. Idempotent + replay-safe.
|
|
6
|
+
* When the run is ALREADY in the terminal status, this is a no-op (the first event preserved its
|
|
7
|
+
* true previous_status; no fresh updated_at on replay).
|
|
8
|
+
*/
|
|
9
|
+
export async function recordTerminalRunStatus(da, runId, params) {
|
|
10
|
+
await da.assertReady();
|
|
11
|
+
const row = await da.getRow('task_runs', runId);
|
|
12
|
+
if (!row)
|
|
13
|
+
return null;
|
|
14
|
+
const prev = typeof row.data.status === 'string' ? row.data.status : '';
|
|
15
|
+
if (prev === params.status) {
|
|
16
|
+
return { previousStatus: prev };
|
|
17
|
+
}
|
|
18
|
+
const nowIso = params.now.toISOString();
|
|
19
|
+
const statusPatch = [
|
|
20
|
+
{ op: 'replace', path: 'status', value: params.status },
|
|
21
|
+
{ op: 'replace', path: 'updated_at', value: nowIso },
|
|
22
|
+
];
|
|
23
|
+
const eventId = `event_${fnv1a64Hex(`${runId}|${params.eventType}`)}`;
|
|
24
|
+
try {
|
|
25
|
+
await da.createRow('events', eventId, {
|
|
26
|
+
id: eventId,
|
|
27
|
+
run_id: runId,
|
|
28
|
+
type: params.eventType,
|
|
29
|
+
payload: { ...params.payload, previous_status: prev },
|
|
30
|
+
actor: params.actor,
|
|
31
|
+
created_at: nowIso,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
// Replay: event already written (true prior status preserved) → still apply the status patch.
|
|
36
|
+
if (e instanceof ControlPlaneError && e.code === 'ROW_CONFLICT') {
|
|
37
|
+
await da.patchRow('task_runs', runId, statusPatch);
|
|
38
|
+
return { previousStatus: prev };
|
|
39
|
+
}
|
|
40
|
+
throw e;
|
|
41
|
+
}
|
|
42
|
+
await da.patchRow('task_runs', runId, statusPatch);
|
|
43
|
+
return { previousStatus: prev };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=terminal-run-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-run-status.js","sourceRoot":"","sources":["../../src/run/terminal-run-status.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAiBvD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,EAA0B,EAC1B,KAAa,EACb,MAA4B;IAE5B,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;IAEvB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,IAAI,IAAI,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;QAC3B,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;IACxC,MAAM,WAAW,GAAG;QAClB,EAAE,EAAE,EAAE,SAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAChE,EAAE,EAAE,EAAE,SAAkB,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE;KAC9D,CAAC;IACF,MAAM,OAAO,GAAG,SAAS,UAAU,CAAC,GAAG,KAAK,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;IAEtE,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE;YACpC,EAAE,EAAE,OAAO;YACX,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,MAAM,CAAC,SAAS;YACtB,OAAO,EAAE,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE;YACrD,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,UAAU,EAAE,MAAM;SACnB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,8FAA8F;QAC9F,IAAI,CAAC,YAAY,iBAAiB,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAChE,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;YACnD,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;QAClC,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;IAED,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACnD,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* ClaudeCodeService — Nest provider wrapping createClaudeCodeRunner.
|
|
15
|
+
*
|
|
16
|
+
* Injects a PROCESS_EXECUTOR DI token so tests can inject a fake ProcessExecutor
|
|
17
|
+
* without spawning a real `claude` process (M2).
|
|
18
|
+
*
|
|
19
|
+
* resolveCwd comes from RunService.makeResolveCwd() — STEP-level (reads tasks.repo_ref).
|
|
20
|
+
*
|
|
21
|
+
* DBOS-SEALED: zero @dbos-inc imports.
|
|
22
|
+
*/
|
|
23
|
+
import { Injectable, Inject } from '@nestjs/common';
|
|
24
|
+
import { createClaudeCodeRunner } from '../worker/claude-code-runner.js';
|
|
25
|
+
import { RunService } from '../revisium/run.service.js';
|
|
26
|
+
import { PROCESS_EXECUTOR } from './tokens.js';
|
|
27
|
+
const DEFAULT_TIMEOUT_MS = 600_000;
|
|
28
|
+
let ClaudeCodeService = class ClaudeCodeService {
|
|
29
|
+
runService;
|
|
30
|
+
runner;
|
|
31
|
+
constructor(executor, runService) {
|
|
32
|
+
this.runService = runService;
|
|
33
|
+
this.runner = createClaudeCodeRunner({
|
|
34
|
+
executor,
|
|
35
|
+
resolveCwd: this.runService.makeResolveCwd(),
|
|
36
|
+
timeoutMs: DEFAULT_TIMEOUT_MS,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** Arrow property — safe to pass unbound as a RunAgent. */
|
|
40
|
+
run = (args) => this.runner(args);
|
|
41
|
+
};
|
|
42
|
+
ClaudeCodeService = __decorate([
|
|
43
|
+
Injectable(),
|
|
44
|
+
__param(0, Inject(PROCESS_EXECUTOR)),
|
|
45
|
+
__metadata("design:paramtypes", [Function, RunService])
|
|
46
|
+
], ClaudeCodeService);
|
|
47
|
+
export { ClaudeCodeService };
|
|
48
|
+
//# sourceMappingURL=claude-code.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.service.js","sourceRoot":"","sources":["../../src/runners/claude-code.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAGzE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAG5B,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAKT;IAJF,MAAM,CAAW;IAElC,YAC4B,QAAyB,EAClC,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;QAEvC,IAAI,CAAC,MAAM,GAAG,sBAAsB,CAAC;YACnC,QAAQ;YACR,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE;YAC5C,SAAS,EAAE,kBAAkB;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,2DAA2D;IAC3D,GAAG,GAAa,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CAC7C,CAAA;AAhBY,iBAAiB;IAD7B,UAAU,EAAE;IAKR,WAAA,MAAM,CAAC,gBAAgB,CAAC,CAAA;+CACI,UAAU;GAL9B,iBAAiB,CAgB7B"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh-identity.ts — pin the gh CLI to an explicit, NON-SECRET account name (0008 #1).
|
|
3
|
+
*
|
|
4
|
+
* Proven failure (2026-06-10 live dogfood): the integrator shelled `gh pr create` using the
|
|
5
|
+
* AMBIENT active gh account. On a multi-account machine the active account flips
|
|
6
|
+
* (anton62k push:false ↔ revisium-io push:true), so PR creation failed and the workflow
|
|
7
|
+
* went silently to DBOS ERROR. The fix: resolve a non-secret identity NAME (default
|
|
8
|
+
* `revisium-io`) → host-resolve its token (env/keyring) → spawn gh with `GH_TOKEN` pinned.
|
|
9
|
+
* `GH_TOKEN` takes precedence over gh's active account, so the flip can no longer break us.
|
|
10
|
+
*
|
|
11
|
+
* SECRET BOUNDARY: only the non-secret account NAME is config (env `REVO_GH_ACCOUNT`).
|
|
12
|
+
* The token is resolved host-side at call time and lives only in the spawned gh process env —
|
|
13
|
+
* NEVER persisted to Revisium, never logged. Least-privilege: only the integrator builds a
|
|
14
|
+
* pinned execGh; the LLM runners get no git/gh creds.
|
|
15
|
+
*
|
|
16
|
+
* DBOS-SEALED: zero @dbos-inc imports.
|
|
17
|
+
*/
|
|
18
|
+
import { execFileSync } from 'node:child_process';
|
|
19
|
+
/** Default non-secret gh account identity (push:true/admin on the org repos). */
|
|
20
|
+
export const DEFAULT_GH_ACCOUNT = 'revisium-io';
|
|
21
|
+
const defaultExecFile = (file, args, opts) => execFileSync(file, args, opts);
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the NON-SECRET gh account name from config/env. Never a token.
|
|
24
|
+
* Falls back to DEFAULT_GH_ACCOUNT when unset/blank.
|
|
25
|
+
*/
|
|
26
|
+
export function resolveGhAccount(env = process.env) {
|
|
27
|
+
const raw = env['REVO_GH_ACCOUNT'];
|
|
28
|
+
const account = typeof raw === 'string' ? raw.trim() : '';
|
|
29
|
+
return account.length > 0 ? account : DEFAULT_GH_ACCOUNT;
|
|
30
|
+
}
|
|
31
|
+
/** Per-account env override key, e.g. account "revisium-io" → "GH_TOKEN_REVISIUM_IO". */
|
|
32
|
+
export function ghTokenEnvKey(account) {
|
|
33
|
+
return `GH_TOKEN_${account.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Host-resolve the gh token for a non-secret account name (never stored in Revisium):
|
|
37
|
+
* 1. explicit env override GH_TOKEN_<ACCOUNT> (CI / headless) — takes precedence.
|
|
38
|
+
* 2. the gh keyring entry for that specific account (`gh auth token --user <account>`).
|
|
39
|
+
* Returns undefined when no token can be resolved (caller falls back to ambient gh).
|
|
40
|
+
*/
|
|
41
|
+
export function resolveGhToken(account, deps) {
|
|
42
|
+
const env = deps?.env ?? process.env;
|
|
43
|
+
const execFile = deps?.execFile ?? defaultExecFile;
|
|
44
|
+
const override = env[ghTokenEnvKey(account)];
|
|
45
|
+
if (typeof override === 'string' && override.trim().length > 0)
|
|
46
|
+
return override.trim();
|
|
47
|
+
try {
|
|
48
|
+
const out = execFile('gh', ['auth', 'token', '--user', account], {
|
|
49
|
+
encoding: 'utf8',
|
|
50
|
+
timeout: 15_000,
|
|
51
|
+
}).trim();
|
|
52
|
+
return out.length > 0 ? out : undefined;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// gh missing / account not in keyring — fall back to ambient gh (returns undefined).
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build an ExecGhFn that PINS the gh account by setting GH_TOKEN on the spawned gh process.
|
|
61
|
+
* When `token` is undefined the gh call is left on the ambient account (degraded — logged once
|
|
62
|
+
* by the caller). The OS-level timeout + maxBuffer mirror defaultExecGh (a hung/runaway gh is
|
|
63
|
+
* killed; the synchronous spawn blocks the event loop so no JS timer could otherwise fire).
|
|
64
|
+
*/
|
|
65
|
+
export function makeExecGh(opts) {
|
|
66
|
+
const execFile = opts?.execFile ?? defaultExecFile;
|
|
67
|
+
const baseEnv = opts?.env ?? process.env;
|
|
68
|
+
const timeout = opts?.timeoutMs ?? 60_000;
|
|
69
|
+
const maxBuffer = opts?.maxBuffer ?? 10 * 1024 * 1024;
|
|
70
|
+
const env = opts?.token ? { ...baseEnv, GH_TOKEN: opts.token } : baseEnv;
|
|
71
|
+
return (args) => execFile('gh', args, { encoding: 'utf8', timeout, maxBuffer, env });
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Resolve the pinned gh identity into a ready-to-use ExecGhFn, or FAIL LOUD (0008 #1 hardening).
|
|
75
|
+
*
|
|
76
|
+
* The 2026-06-12 dogfood proved the original silent fallback was wrong: when the pinned token
|
|
77
|
+
* could not be resolved (e.g. a detached/headless host where `gh auth token --user` can't reach
|
|
78
|
+
* the macOS keychain), the integrator fell back to the AMBIENT gh account and opened a PR as the
|
|
79
|
+
* wrong user — re-introducing the exact bug #1 exists to prevent. We now REFUSE to fall back:
|
|
80
|
+
* an unresolved pinned identity returns needsHuman so the integrator blocks for a human instead
|
|
81
|
+
* of opening a PR as the wrong account. The keyring-free fix is to set GH_TOKEN_<ACCOUNT> in the
|
|
82
|
+
* host env (works headless), which resolveGhToken checks first.
|
|
83
|
+
*/
|
|
84
|
+
export function resolvePinnedGh(deps) {
|
|
85
|
+
const env = deps?.env ?? process.env;
|
|
86
|
+
const account = resolveGhAccount(env);
|
|
87
|
+
const token = resolveGhToken(account, { env, execFile: deps?.execFile });
|
|
88
|
+
if (!token) {
|
|
89
|
+
return {
|
|
90
|
+
needsHuman: true,
|
|
91
|
+
lesson: `could not resolve a token for the pinned gh account '${account}' — REFUSING to fall back to the ambient ` +
|
|
92
|
+
`gh account (0008 #1: a PR must never be opened by the wrong account). Fix: set ${ghTokenEnvKey(account)} in ` +
|
|
93
|
+
`the host env (keyring-free, works headless), or run on a host where 'gh auth token --user ${account}' can ` +
|
|
94
|
+
`reach the keychain.`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return { execGh: makeExecGh({ token, env, execFile: deps?.execFile }) };
|
|
98
|
+
}
|
|
99
|
+
const TOKEN_PATTERN = /\b(?:gh[opsru]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,})\b/g;
|
|
100
|
+
/**
|
|
101
|
+
* Mask GitHub token shapes in a free-text string (gho_/ghp_/ghs_/ghr_/ghu_ + github_pat_).
|
|
102
|
+
* redactSecrets (inbox.ts) only masks secret-shaped object KEYS; an error/lesson string that
|
|
103
|
+
* happens to echo a token needs this string-level pass before it is persisted to Revisium.
|
|
104
|
+
*/
|
|
105
|
+
export function redactTokens(text) {
|
|
106
|
+
return text.replace(TOKEN_PATTERN, '[REDACTED]');
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=gh-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh-identity.js","sourceRoot":"","sources":["../../src/runners/gh-identity.ts"],"names":[],"mappings":"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"}
|