agent-conveyor 0.1.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 (85) hide show
  1. package/README.md +1123 -0
  2. package/dist/cli/main.d.ts +2 -0
  3. package/dist/cli/main.js +19 -0
  4. package/dist/cli/main.js.map +1 -0
  5. package/dist/cli/program-name.d.ts +2 -0
  6. package/dist/cli/program-name.js +12 -0
  7. package/dist/cli/program-name.js.map +1 -0
  8. package/dist/cli/typescript-runtime.d.ts +52 -0
  9. package/dist/cli/typescript-runtime.js +18009 -0
  10. package/dist/cli/typescript-runtime.js.map +1 -0
  11. package/dist/index.d.ts +37 -0
  12. package/dist/index.js +20 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/runtime/audit.d.ts +96 -0
  15. package/dist/runtime/audit.js +298 -0
  16. package/dist/runtime/audit.js.map +1 -0
  17. package/dist/runtime/classify.d.ts +8 -0
  18. package/dist/runtime/classify.js +128 -0
  19. package/dist/runtime/classify.js.map +1 -0
  20. package/dist/runtime/codex-session.d.ts +103 -0
  21. package/dist/runtime/codex-session.js +408 -0
  22. package/dist/runtime/codex-session.js.map +1 -0
  23. package/dist/runtime/commands.d.ts +92 -0
  24. package/dist/runtime/commands.js +408 -0
  25. package/dist/runtime/commands.js.map +1 -0
  26. package/dist/runtime/dispatch.d.ts +74 -0
  27. package/dist/runtime/dispatch.js +669 -0
  28. package/dist/runtime/dispatch.js.map +1 -0
  29. package/dist/runtime/export.d.ts +22 -0
  30. package/dist/runtime/export.js +77 -0
  31. package/dist/runtime/export.js.map +1 -0
  32. package/dist/runtime/ingest.d.ts +28 -0
  33. package/dist/runtime/ingest.js +177 -0
  34. package/dist/runtime/ingest.js.map +1 -0
  35. package/dist/runtime/loop-evidence.d.ts +87 -0
  36. package/dist/runtime/loop-evidence.js +448 -0
  37. package/dist/runtime/loop-evidence.js.map +1 -0
  38. package/dist/runtime/manager-config.d.ts +20 -0
  39. package/dist/runtime/manager-config.js +34 -0
  40. package/dist/runtime/manager-config.js.map +1 -0
  41. package/dist/runtime/manager-permissions.d.ts +7 -0
  42. package/dist/runtime/manager-permissions.js +85 -0
  43. package/dist/runtime/manager-permissions.js.map +1 -0
  44. package/dist/runtime/notifications.d.ts +89 -0
  45. package/dist/runtime/notifications.js +208 -0
  46. package/dist/runtime/notifications.js.map +1 -0
  47. package/dist/runtime/replay.d.ts +29 -0
  48. package/dist/runtime/replay.js +331 -0
  49. package/dist/runtime/replay.js.map +1 -0
  50. package/dist/runtime/tasks.d.ts +54 -0
  51. package/dist/runtime/tasks.js +195 -0
  52. package/dist/runtime/tasks.js.map +1 -0
  53. package/dist/runtime/tmux.d.ts +61 -0
  54. package/dist/runtime/tmux.js +189 -0
  55. package/dist/runtime/tmux.js.map +1 -0
  56. package/dist/runtime/visual-diff.d.ts +23 -0
  57. package/dist/runtime/visual-diff.js +234 -0
  58. package/dist/runtime/visual-diff.js.map +1 -0
  59. package/dist/state/database.d.ts +21 -0
  60. package/dist/state/database.js +142 -0
  61. package/dist/state/database.js.map +1 -0
  62. package/dist/state/files.d.ts +38 -0
  63. package/dist/state/files.js +73 -0
  64. package/dist/state/files.js.map +1 -0
  65. package/dist/state/schema-v22.d.ts +1 -0
  66. package/dist/state/schema-v22.js +566 -0
  67. package/dist/state/schema-v22.js.map +1 -0
  68. package/dist/state/sqlite-contract.d.ts +4 -0
  69. package/dist/state/sqlite-contract.js +78 -0
  70. package/dist/state/sqlite-contract.js.map +1 -0
  71. package/dist/state/status.d.ts +12 -0
  72. package/dist/state/status.js +40 -0
  73. package/dist/state/status.js.map +1 -0
  74. package/docs/typescript-migration/cli-contract.md +147 -0
  75. package/docs/typescript-migration/dashboard-contract.md +76 -0
  76. package/docs/typescript-migration/package-install-contract.md +98 -0
  77. package/docs/typescript-migration/qa-gate-matrix.md +103 -0
  78. package/docs/typescript-migration/sqlite-state-contract.md +92 -0
  79. package/docs/typescript-migration/t005-runtime-parity.md +47 -0
  80. package/package.json +88 -0
  81. package/scripts/capture-static-html-screenshot.mjs +88 -0
  82. package/skills/codex-review/SKILL.md +116 -0
  83. package/skills/codex-review/scripts/codex-review +344 -0
  84. package/skills/manage-codex-workers/SKILL.md +696 -0
  85. package/skills/manage-codex-workers/agents/openai.yaml +5 -0
@@ -0,0 +1,103 @@
1
+ import type { DatabaseSync } from "node:sqlite";
2
+ export interface CodexSessionMeta {
3
+ cli_version?: string;
4
+ cwd?: string;
5
+ id: string;
6
+ originator?: string;
7
+ timestamp?: string;
8
+ }
9
+ export interface CodexSessionDiscovery {
10
+ cli_version: string;
11
+ codex_session_id: string;
12
+ codex_session_path: string;
13
+ cwd: string;
14
+ native_pid: number;
15
+ originator: string;
16
+ pid: number;
17
+ }
18
+ export interface RegisteredSessionRecord {
19
+ codex_session_id: string | null;
20
+ codex_session_path: string | null;
21
+ communication: SessionCommunication;
22
+ cwd: string;
23
+ id: string;
24
+ identity_token: string;
25
+ last_heartbeat_at: string | null;
26
+ last_ingest_offset?: number | null;
27
+ name: string;
28
+ pid: number | null;
29
+ registered_at: string;
30
+ role: "manager" | "worker";
31
+ state: "active" | "gone";
32
+ tmux_pane_id: string | null;
33
+ tmux_session: string | null;
34
+ }
35
+ interface SessionCommunication {
36
+ can_receive_pull: boolean;
37
+ can_receive_push: boolean;
38
+ delivery_mode: "pull_required" | "push";
39
+ detection_source: "codex_session_without_tmux" | "missing_tmux_session" | "tmux_session";
40
+ poll_command?: string | null;
41
+ poll_command_template: string | null;
42
+ receive_style: "pull" | "push";
43
+ requires_polling: boolean;
44
+ session_kind: "codex_app" | "no_tmux" | "tmux";
45
+ tmux_session: string | null;
46
+ }
47
+ export interface RegisterSessionResult {
48
+ codex_session_id: string;
49
+ codex_session_path: string;
50
+ communication: SessionCommunication;
51
+ cwd: string;
52
+ name: string;
53
+ pid: number;
54
+ role: "manager" | "worker";
55
+ session_id: string;
56
+ tmux_session: string | null;
57
+ }
58
+ export interface DiscoverResult {
59
+ bindings: Array<Record<string, unknown>>;
60
+ query: string;
61
+ sessions: RegisteredSessionRecord[];
62
+ suggestions: Array<Record<string, unknown>>;
63
+ tasks: Array<Record<string, unknown>>;
64
+ telemetry: Array<Record<string, unknown>>;
65
+ }
66
+ export declare function readSessionMeta(path: string): CodexSessionMeta;
67
+ export declare function findNativeCodexPid(pid: number, children: number[]): number;
68
+ export declare function findRolloutPathInLsof(output: string, pid: number): string;
69
+ export declare function findRolloutPathForPid(pid: number, lsofForPid: (pid: number) => string): string;
70
+ export declare function discoverSession(options: {
71
+ childrenForPid: (pid: number) => number[];
72
+ lsofForPid: (pid: number) => string;
73
+ pid: number;
74
+ }): CodexSessionDiscovery;
75
+ export declare function registerSessionSync(database: DatabaseSync, options: {
76
+ codexSessionPath: string;
77
+ cwd?: string | null;
78
+ name: string;
79
+ now?: string;
80
+ pid: number;
81
+ role: "manager" | "worker";
82
+ tmuxSession?: string | null;
83
+ }): RegisterSessionResult;
84
+ export declare function deregisterSessionSync(database: DatabaseSync, options: {
85
+ name: string;
86
+ now?: string;
87
+ }): void;
88
+ export declare function listRegisteredSessionsSync(database: DatabaseSync, options?: {
89
+ dbPath?: string | null;
90
+ includeLegacy?: boolean;
91
+ names?: string[];
92
+ redactIdentityToken?: boolean;
93
+ role?: "manager" | "worker" | null;
94
+ state?: "active" | "all" | "gone" | null;
95
+ }): RegisteredSessionRecord[];
96
+ export declare function discoverRegistrySync(database: DatabaseSync, options?: {
97
+ all?: boolean;
98
+ dbPath?: string | null;
99
+ limit?: number;
100
+ query?: string;
101
+ }): DiscoverResult;
102
+ export declare function sessionRow(database: DatabaseSync, name: string, role?: "manager" | "worker" | null): Omit<RegisteredSessionRecord, "communication">;
103
+ export {};
@@ -0,0 +1,408 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
3
+ class CodexSessionError extends Error {
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = "CodexSessionError";
7
+ }
8
+ }
9
+ export function readSessionMeta(path) {
10
+ let firstLine;
11
+ try {
12
+ [firstLine = ""] = readFileSync(path, "utf8").split(/\r?\n/, 1);
13
+ }
14
+ catch (error) {
15
+ if (error.code === "ENOENT") {
16
+ throw new CodexSessionError(`rollout file not found: ${path}`);
17
+ }
18
+ throw error;
19
+ }
20
+ if (!firstLine) {
21
+ throw new CodexSessionError(`rollout file is empty: ${path}`);
22
+ }
23
+ let record;
24
+ try {
25
+ record = JSON.parse(firstLine);
26
+ }
27
+ catch {
28
+ throw new CodexSessionError(`rollout file first line is not JSON: ${path}`);
29
+ }
30
+ if (!isRecord(record) || record.type !== "session_meta") {
31
+ throw new CodexSessionError(`rollout file first record is not session_meta: ${path}`);
32
+ }
33
+ if (!isRecord(record.payload)) {
34
+ throw new CodexSessionError(`rollout session_meta payload is not an object: ${path}`);
35
+ }
36
+ if (typeof record.payload.id !== "string") {
37
+ throw new CodexSessionError(`rollout session_meta payload is missing id: ${path}`);
38
+ }
39
+ return record.payload;
40
+ }
41
+ export function findNativeCodexPid(pid, children) {
42
+ return children[0] ?? pid;
43
+ }
44
+ export function findRolloutPathInLsof(output, pid) {
45
+ for (const line of output.split(/\r?\n/)) {
46
+ const stripped = line.trim();
47
+ if (!stripped || !stripped.endsWith(".jsonl")) {
48
+ continue;
49
+ }
50
+ const parts = stripped.split(/\s+/);
51
+ const path = parts.at(-1) ?? "";
52
+ if (path.includes("/sessions/") && path.includes("/rollout-") && path.endsWith(".jsonl")) {
53
+ return path;
54
+ }
55
+ }
56
+ throw new CodexSessionError(`no rollout-*.jsonl file open for pid ${pid}`);
57
+ }
58
+ export function findRolloutPathForPid(pid, lsofForPid) {
59
+ return findRolloutPathInLsof(lsofForPid(pid), pid);
60
+ }
61
+ export function discoverSession(options) {
62
+ const nativePid = findNativeCodexPid(options.pid, options.childrenForPid(options.pid));
63
+ const rolloutPath = findRolloutPathForPid(nativePid, options.lsofForPid);
64
+ const meta = readSessionMeta(rolloutPath);
65
+ return {
66
+ cli_version: meta.cli_version ?? "",
67
+ codex_session_id: meta.id,
68
+ codex_session_path: rolloutPath,
69
+ cwd: meta.cwd ?? "",
70
+ native_pid: nativePid,
71
+ originator: meta.originator ?? "",
72
+ pid: options.pid,
73
+ };
74
+ }
75
+ export function registerSessionSync(database, options) {
76
+ const meta = readSessionMeta(options.codexSessionPath);
77
+ const cwd = options.cwd || meta.cwd || "";
78
+ const timestamp = options.now ?? new Date().toISOString();
79
+ const existing = database.prepare(`
80
+ select id, role, identity_token
81
+ from sessions
82
+ where name = ?
83
+ `).get(options.name);
84
+ if (existing && existing.role !== options.role) {
85
+ throw new CodexSessionError(`session name ${JSON.stringify(options.name)} already exists with role ${JSON.stringify(existing.role)}; `
86
+ + `refusing to re-register as ${JSON.stringify(options.role)}`);
87
+ }
88
+ const sessionId = existing?.id ?? `session-${randomUUID()}`;
89
+ const identityToken = existing?.identity_token ?? `session-token-${randomUUID()}`;
90
+ database.prepare(`
91
+ insert into sessions(
92
+ id, name, role, identity_token,
93
+ tmux_session, tmux_pane_id,
94
+ codex_session_path, codex_session_id, pid,
95
+ cwd, registered_at, last_heartbeat_at, state
96
+ )
97
+ values (?, ?, ?, ?, ?, null, ?, ?, ?, ?, ?, ?, 'active')
98
+ on conflict(name) do update set
99
+ tmux_session = excluded.tmux_session,
100
+ tmux_pane_id = coalesce(excluded.tmux_pane_id, sessions.tmux_pane_id),
101
+ codex_session_path = excluded.codex_session_path,
102
+ codex_session_id = excluded.codex_session_id,
103
+ pid = excluded.pid,
104
+ cwd = excluded.cwd,
105
+ last_heartbeat_at = excluded.last_heartbeat_at,
106
+ last_ingest_offset = null,
107
+ state = 'active'
108
+ `).run(sessionId, options.name, options.role, identityToken, options.tmuxSession ?? null, options.codexSessionPath, meta.id, options.pid, cwd, timestamp, timestamp);
109
+ const session = sessionRow(database, options.name, options.role);
110
+ return {
111
+ codex_session_id: meta.id,
112
+ codex_session_path: options.codexSessionPath,
113
+ communication: sessionCommunication(session),
114
+ cwd,
115
+ name: options.name,
116
+ pid: options.pid,
117
+ role: options.role,
118
+ session_id: sessionId,
119
+ tmux_session: session.tmux_session,
120
+ };
121
+ }
122
+ export function deregisterSessionSync(database, options) {
123
+ const timestamp = options.now ?? new Date().toISOString();
124
+ const existing = database.prepare("select id from sessions where name = ?")
125
+ .get(options.name);
126
+ if (!existing) {
127
+ throw new CodexSessionError(`no session registered with name ${JSON.stringify(options.name)}`);
128
+ }
129
+ const activeBinding = database.prepare(`
130
+ select id, task_id
131
+ from bindings
132
+ where state in ('active', 'ending')
133
+ and (worker_session_id = ? or manager_session_id = ?)
134
+ limit 1
135
+ `).get(existing.id, existing.id);
136
+ if (activeBinding) {
137
+ throw new CodexSessionError(`cannot deregister session ${JSON.stringify(options.name)}: it is still bound to task `
138
+ + `${JSON.stringify(activeBinding.task_id)} (binding ${JSON.stringify(activeBinding.id)}). Unbind the task first.`);
139
+ }
140
+ database.prepare("update sessions set state = 'gone', last_heartbeat_at = ? where name = ?")
141
+ .run(timestamp, options.name);
142
+ }
143
+ export function listRegisteredSessionsSync(database, options) {
144
+ const rows = listSessionRows(database, {
145
+ includeLegacy: options?.includeLegacy,
146
+ role: options?.role,
147
+ state: options?.state,
148
+ });
149
+ const names = new Set(options?.names ?? []);
150
+ return rows
151
+ .filter((session) => names.size === 0 || names.has(session.name))
152
+ .map((session) => {
153
+ const record = {
154
+ ...session,
155
+ communication: sessionCommunication(session, { dbPath: options?.dbPath }),
156
+ };
157
+ if (options?.redactIdentityToken && record.identity_token !== null) {
158
+ return { ...record, identity_token: "[REDACTED]" };
159
+ }
160
+ return record;
161
+ });
162
+ }
163
+ export function discoverRegistrySync(database, options) {
164
+ const query = (options?.query ?? "").trim();
165
+ const limit = options?.limit ?? 10;
166
+ const tasks = listDiscoverTasks(database, { activeOnly: !(options?.all ?? false) });
167
+ const sessions = listRegisteredSessionsSync(database, {
168
+ dbPath: options?.dbPath,
169
+ state: options?.all ? "all" : "active",
170
+ });
171
+ const bindings = activeBindings(database);
172
+ const telemetry = query ? queryTelemetryEvents(database, { limit, search: query }) : [];
173
+ const matchedTasks = tasks
174
+ .filter((task) => rowMatchesQuery(task, query, ["name", "goal", "summary", "state"]))
175
+ .slice(0, limit);
176
+ const matchedSessions = sessions
177
+ .filter((session) => rowMatchesQuery(session, query, ["name", "role", "state", "cwd", "tmux_session", "codex_session_id"]))
178
+ .slice(0, limit);
179
+ const matchedBindings = bindings
180
+ .filter((binding) => rowMatchesQuery(binding, query, ["task_name", "task_goal", "worker_name", "manager_name", "state"]))
181
+ .slice(0, limit);
182
+ return {
183
+ bindings: matchedBindings,
184
+ query,
185
+ sessions: matchedSessions,
186
+ suggestions: discoverSuggestions(matchedTasks, matchedSessions, matchedBindings),
187
+ tasks: matchedTasks,
188
+ telemetry: telemetry.slice(0, limit),
189
+ };
190
+ }
191
+ export function sessionRow(database, name, role) {
192
+ const row = database.prepare("select * from sessions where name = ?").get(name);
193
+ if (!row) {
194
+ throw new CodexSessionError(`no session registered with name ${JSON.stringify(name)}`);
195
+ }
196
+ if (role && row.role !== role) {
197
+ throw new CodexSessionError(`session ${JSON.stringify(name)} has role ${JSON.stringify(row.role)}, expected ${JSON.stringify(role)}`);
198
+ }
199
+ return sessionRecord(row);
200
+ }
201
+ function listSessionRows(database, options) {
202
+ const state = options?.state ?? null;
203
+ if (state !== null && state !== "active" && state !== "gone" && state !== "all") {
204
+ throw new CodexSessionError(`invalid state filter: ${JSON.stringify(state)}`);
205
+ }
206
+ const clauses = [];
207
+ const params = [];
208
+ if (options?.role) {
209
+ clauses.push("role = ?");
210
+ params.push(options.role);
211
+ }
212
+ if (state === "gone") {
213
+ clauses.push("state = 'gone'");
214
+ }
215
+ else if (state !== "all") {
216
+ clauses.push("state != 'gone'");
217
+ }
218
+ if (state === null && !options?.includeLegacy) {
219
+ clauses.push("pid is not null");
220
+ }
221
+ else if (state === "active") {
222
+ clauses.push("pid is not null");
223
+ }
224
+ const where = clauses.length > 0 ? ` where ${clauses.join(" and ")}` : "";
225
+ const rows = database.prepare(`select * from sessions${where} order by registered_at`).all(...params);
226
+ return rows.map(sessionRecord);
227
+ }
228
+ function sessionCommunication(session, options) {
229
+ const hasTmux = Boolean(session.tmux_session);
230
+ const hasCodexIdentity = Boolean(session.codex_session_path || session.codex_session_id);
231
+ const pollCommand = sessionPollCommand(session.role, { dbPath: options?.dbPath, taskName: options?.taskName });
232
+ return {
233
+ can_receive_pull: pollCommand !== null,
234
+ can_receive_push: hasTmux,
235
+ delivery_mode: hasTmux ? "push" : "pull_required",
236
+ detection_source: hasTmux ? "tmux_session" : hasCodexIdentity ? "codex_session_without_tmux" : "missing_tmux_session",
237
+ ...(options?.taskName !== undefined ? { poll_command: pollCommand } : {}),
238
+ poll_command_template: sessionPollCommand(session.role, { dbPath: options?.dbPath }),
239
+ receive_style: hasTmux ? "push" : "pull",
240
+ requires_polling: !hasTmux,
241
+ session_kind: hasTmux ? "tmux" : hasCodexIdentity ? "codex_app" : "no_tmux",
242
+ tmux_session: session.tmux_session,
243
+ };
244
+ }
245
+ function sessionPollCommand(role, options) {
246
+ if (role === "worker") {
247
+ return `conveyor worker-inbox ${pollTaskArg(options?.taskName)} --consume-next --wait --timeout 60${pollPathSuffix(options?.dbPath)} --json`;
248
+ }
249
+ if (role === "manager") {
250
+ return `conveyor manager-inbox ${pollTaskArg(options?.taskName)} --consume-next --wait --timeout 60${pollPathSuffix(options?.dbPath)} --json`;
251
+ }
252
+ return null;
253
+ }
254
+ function pollTaskArg(taskName) {
255
+ return taskName ? shellQuote(taskName) : "<task>";
256
+ }
257
+ function pollPathSuffix(dbPath) {
258
+ return dbPath ? ` --path ${shellQuote(dbPath)}` : "";
259
+ }
260
+ function shellQuote(value) {
261
+ return `'${value.replace(/'/g, "'\"'\"'")}'`;
262
+ }
263
+ function sessionRecord(row) {
264
+ return {
265
+ codex_session_id: row.codex_session_id,
266
+ codex_session_path: row.codex_session_path,
267
+ cwd: row.cwd,
268
+ id: row.id,
269
+ identity_token: row.identity_token,
270
+ last_heartbeat_at: row.last_heartbeat_at,
271
+ ...(Object.hasOwn(row, "last_ingest_offset") ? { last_ingest_offset: row.last_ingest_offset ?? null } : {}),
272
+ name: row.name,
273
+ pid: row.pid,
274
+ registered_at: row.registered_at,
275
+ role: row.role,
276
+ state: row.state,
277
+ tmux_pane_id: row.tmux_pane_id,
278
+ tmux_session: row.tmux_session,
279
+ };
280
+ }
281
+ function listDiscoverTasks(database, options) {
282
+ const where = options?.activeOnly ? "where tasks.state in ('candidate', 'managed', 'paused')" : "";
283
+ const rows = database.prepare(`
284
+ select tasks.id, tasks.name, tasks.goal, tasks.summary, tasks.state,
285
+ tasks.created_at, tasks.updated_at,
286
+ budgets.max_nudges, budgets.nudges_used, budgets.expires_at
287
+ from tasks
288
+ left join budgets on budgets.task_id = tasks.id
289
+ ${where}
290
+ order by tasks.created_at, tasks.id
291
+ `).all();
292
+ return rows.map((row) => ({
293
+ budget: row.max_nudges === null ? null : {
294
+ expires_at: row.expires_at,
295
+ max_nudges: row.max_nudges,
296
+ nudges_remaining: row.max_nudges - (row.nudges_used ?? 0),
297
+ nudges_used: row.nudges_used,
298
+ },
299
+ created_at: row.created_at,
300
+ goal: row.goal,
301
+ id: row.id,
302
+ name: row.name,
303
+ state: row.state,
304
+ summary: row.summary,
305
+ updated_at: row.updated_at,
306
+ }));
307
+ }
308
+ function activeBindings(database) {
309
+ return database.prepare(`
310
+ select bindings.id, bindings.state, bindings.created_at,
311
+ tasks.name as task_name, tasks.goal as task_goal,
312
+ ws.name as worker_name, ws.state as worker_state, ws.tmux_session as worker_tmux_session,
313
+ ms.name as manager_name, ms.state as manager_state, ms.tmux_session as manager_tmux_session
314
+ from bindings
315
+ join tasks on tasks.id = bindings.task_id
316
+ left join sessions ws on ws.id = bindings.worker_session_id
317
+ left join sessions ms on ms.id = bindings.manager_session_id
318
+ where bindings.state in ('active', 'ending')
319
+ order by bindings.created_at desc
320
+ `).all();
321
+ }
322
+ function discoverSuggestions(tasks, sessions, bindings) {
323
+ const suggestions = [];
324
+ const activeBoundTasks = new Set(bindings.map((binding) => binding.task_name).filter(Boolean));
325
+ const workers = sessions.filter((session) => session.role === "worker" && session.state === "active");
326
+ const managers = sessions.filter((session) => session.role === "manager" && session.state === "active");
327
+ for (const task of tasks) {
328
+ if (!["candidate", "managed", "paused"].includes(String(task.state))) {
329
+ continue;
330
+ }
331
+ if (activeBoundTasks.has(task.name)) {
332
+ continue;
333
+ }
334
+ if (workers.length > 0 && managers.length > 0) {
335
+ suggestions.push({
336
+ command: `conveyor bind --task ${shellQuote(String(task.name))} --worker ${shellQuote(workers[0].name)} --manager ${shellQuote(managers[0].name)}`,
337
+ kind: "bind",
338
+ manager: managers[0].name,
339
+ task: task.name,
340
+ worker: workers[0].name,
341
+ });
342
+ break;
343
+ }
344
+ }
345
+ if (workers.length === 0) {
346
+ suggestions.push({
347
+ kind: "register-worker",
348
+ prompt: "Open the intended worker Codex session and ask it to use the manage-codex-workers skill to register as the worker for this dashboard setup.",
349
+ });
350
+ }
351
+ if (managers.length === 0) {
352
+ suggestions.push({
353
+ kind: "register-manager",
354
+ prompt: "Open the intended manager Codex session and ask it to use the manage-codex-workers skill to register as the manager for this dashboard setup.",
355
+ });
356
+ }
357
+ return suggestions;
358
+ }
359
+ function queryTelemetryEvents(database, options) {
360
+ const rows = database.prepare(`
361
+ select te.id, te.run_id, te.task_id, te.timestamp, te.actor,
362
+ te.event_type, te.severity, te.summary,
363
+ te.correlation_json, te.attributes_json
364
+ from telemetry_events te
365
+ where (
366
+ te.id in (
367
+ select event_id
368
+ from telemetry_events_fts
369
+ where telemetry_events_fts match ?
370
+ )
371
+ or te.event_type = ?
372
+ )
373
+ order by te.timestamp asc, te.rowid asc
374
+ limit ?
375
+ `).all(telemetryFtsQuery(options.search), options.search, options.limit);
376
+ return rows.map((row) => ({
377
+ actor: row.actor,
378
+ attributes: JSON.parse(row.attributes_json),
379
+ correlation: JSON.parse(row.correlation_json),
380
+ event_type: row.event_type,
381
+ id: row.id,
382
+ run_id: row.run_id,
383
+ severity: row.severity,
384
+ summary: row.summary,
385
+ task_id: row.task_id,
386
+ timestamp: row.timestamp,
387
+ }));
388
+ }
389
+ function telemetryFtsQuery(search) {
390
+ return search.split(/\s+/).filter(Boolean).map((term) => `"${term.replace(/"/g, "\"\"")}"`).join(" ");
391
+ }
392
+ function rowMatchesQuery(row, query, fields) {
393
+ return fields.some((field) => matchesQuery(row[field], query));
394
+ }
395
+ function matchesQuery(value, query) {
396
+ if (!query) {
397
+ return true;
398
+ }
399
+ if (value === null || value === undefined) {
400
+ return false;
401
+ }
402
+ const haystack = typeof value === "object" ? JSON.stringify(value, Object.keys(value).sort()) : String(value);
403
+ return haystack.toLowerCase().includes(query.toLowerCase());
404
+ }
405
+ function isRecord(value) {
406
+ return value !== null && typeof value === "object" && !Array.isArray(value);
407
+ }
408
+ //# sourceMappingURL=codex-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-session.js","sourceRoot":"","sources":["../../src/runtime/codex-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ export interface CommandRecord {
3
+ attempts: number;
4
+ available_at: string | null;
5
+ claim_expires_at: string | null;
6
+ claimed_at: string | null;
7
+ claimed_by: string | null;
8
+ correlation_id: string | null;
9
+ created_at: string;
10
+ error: string | null;
11
+ id: string;
12
+ idempotency_key: string;
13
+ manager_id: string | null;
14
+ max_attempts: number;
15
+ payload: Record<string, unknown>;
16
+ required_permission: string | null;
17
+ result: Record<string, unknown> | null;
18
+ state: string;
19
+ task_id: string | null;
20
+ type: string;
21
+ updated_at: string;
22
+ worker_id: string | null;
23
+ }
24
+ export interface CommandAttemptRecord {
25
+ command_id: string;
26
+ correlation_id: string;
27
+ dispatcher_id: string;
28
+ error: string | null;
29
+ finished_at: string | null;
30
+ id: number;
31
+ result: Record<string, unknown> | null;
32
+ side_effect_completed: boolean;
33
+ side_effect_started: boolean;
34
+ started_at: string;
35
+ state: string;
36
+ }
37
+ export interface ClaimedCommand {
38
+ attempt: CommandAttemptRecord;
39
+ command: CommandRecord;
40
+ }
41
+ export interface RecoveredDispatchClaim {
42
+ attempt_id: number | null;
43
+ command_id: string;
44
+ command_type: string;
45
+ error: string;
46
+ side_effect_started: boolean;
47
+ state: "failed" | "requeued";
48
+ }
49
+ export declare class CommandQueueError extends Error {
50
+ constructor(message: string);
51
+ }
52
+ export declare function claimableDispatchCommandsSync(database: DatabaseSync, options: {
53
+ commandTypes: string[];
54
+ limit?: number;
55
+ now?: string;
56
+ }): CommandRecord[];
57
+ export declare function createCommandSync(database: DatabaseSync, options: {
58
+ availableAt?: string | null;
59
+ commandId?: string;
60
+ commandType: string;
61
+ correlationId?: string | null;
62
+ idempotencyKey?: string | null;
63
+ managerId?: string | null;
64
+ maxAttempts?: number;
65
+ now?: string;
66
+ payload: Record<string, unknown>;
67
+ requiredPermission?: string | null;
68
+ taskId?: string | null;
69
+ workerId?: string | null;
70
+ }): string;
71
+ export declare function recoverStaleDispatchClaimsSync(database: DatabaseSync, options: {
72
+ commandTypes: string[];
73
+ dispatcherId: string;
74
+ limit?: number;
75
+ now?: string;
76
+ }): RecoveredDispatchClaim[];
77
+ export declare function claimNextDispatchCommandSync(database: DatabaseSync, options: {
78
+ commandTypes: string[];
79
+ dispatcherId: string;
80
+ leaseSeconds?: number;
81
+ now?: string;
82
+ }): ClaimedCommand | null;
83
+ export declare function finishCommandAttemptSync(database: DatabaseSync, options: {
84
+ attemptId: number;
85
+ error?: string | null;
86
+ now?: string;
87
+ result?: Record<string, unknown> | null;
88
+ sideEffectCompleted?: boolean;
89
+ sideEffectStarted?: boolean;
90
+ state: "abandoned" | "blocked" | "failed" | "succeeded";
91
+ }): CommandAttemptRecord;
92
+ export declare function markCommandAttemptSideEffectStartedSync(database: DatabaseSync, attemptId: number): void;