opencastle 0.27.1 → 0.27.3

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 (77) hide show
  1. package/dist/cli/convoy/dashboard-types.d.ts +146 -0
  2. package/dist/cli/convoy/dashboard-types.d.ts.map +1 -0
  3. package/dist/cli/convoy/dashboard-types.js +2 -0
  4. package/dist/cli/convoy/dashboard-types.js.map +1 -0
  5. package/dist/cli/convoy/engine.d.ts +0 -1
  6. package/dist/cli/convoy/engine.d.ts.map +1 -1
  7. package/dist/cli/convoy/engine.js +31 -99
  8. package/dist/cli/convoy/engine.js.map +1 -1
  9. package/dist/cli/convoy/engine.test.js +88 -1
  10. package/dist/cli/convoy/engine.test.js.map +1 -1
  11. package/dist/cli/convoy/event-schemas.d.ts +9 -0
  12. package/dist/cli/convoy/event-schemas.d.ts.map +1 -0
  13. package/dist/cli/convoy/event-schemas.js +185 -0
  14. package/dist/cli/convoy/event-schemas.js.map +1 -0
  15. package/dist/cli/convoy/events.d.ts +8 -0
  16. package/dist/cli/convoy/events.d.ts.map +1 -1
  17. package/dist/cli/convoy/events.js +117 -5
  18. package/dist/cli/convoy/events.js.map +1 -1
  19. package/dist/cli/convoy/events.test.js +173 -3
  20. package/dist/cli/convoy/events.test.js.map +1 -1
  21. package/dist/cli/convoy/log-merge.test.d.ts +2 -0
  22. package/dist/cli/convoy/log-merge.test.d.ts.map +1 -0
  23. package/dist/cli/convoy/log-merge.test.js +147 -0
  24. package/dist/cli/convoy/log-merge.test.js.map +1 -0
  25. package/dist/cli/convoy/store.d.ts +52 -2
  26. package/dist/cli/convoy/store.d.ts.map +1 -1
  27. package/dist/cli/convoy/store.js +244 -17
  28. package/dist/cli/convoy/store.js.map +1 -1
  29. package/dist/cli/convoy/store.test.js +481 -22
  30. package/dist/cli/convoy/store.test.js.map +1 -1
  31. package/dist/cli/convoy/types.d.ts +271 -3
  32. package/dist/cli/convoy/types.d.ts.map +1 -1
  33. package/dist/cli/convoy/types.js +42 -1
  34. package/dist/cli/convoy/types.js.map +1 -1
  35. package/dist/cli/log.d.ts +11 -0
  36. package/dist/cli/log.d.ts.map +1 -1
  37. package/dist/cli/log.js +114 -2
  38. package/dist/cli/log.js.map +1 -1
  39. package/dist/cli/run.d.ts.map +1 -1
  40. package/dist/cli/run.js +37 -1
  41. package/dist/cli/run.js.map +1 -1
  42. package/package.json +6 -1
  43. package/src/cli/convoy/TELEMETRY.md +203 -0
  44. package/src/cli/convoy/dashboard-types.ts +141 -0
  45. package/src/cli/convoy/engine.test.ts +99 -1
  46. package/src/cli/convoy/engine.ts +27 -96
  47. package/src/cli/convoy/event-schemas.ts +195 -0
  48. package/src/cli/convoy/events.test.ts +207 -3
  49. package/src/cli/convoy/events.ts +119 -5
  50. package/src/cli/convoy/log-merge.test.ts +179 -0
  51. package/src/cli/convoy/store.test.ts +545 -22
  52. package/src/cli/convoy/store.ts +274 -21
  53. package/src/cli/convoy/types.ts +108 -3
  54. package/src/cli/log.ts +120 -2
  55. package/src/cli/run.ts +37 -1
  56. package/src/dashboard/dist/_astro/{index.DtnyD8a5.css → index.6L3_HsPT.css} +1 -1
  57. package/src/dashboard/dist/data/.gitkeep +0 -0
  58. package/src/dashboard/dist/data/convoy-list.json +20 -0
  59. package/src/dashboard/dist/data/convoys/demo-convoy-1.json +111 -0
  60. package/src/dashboard/dist/data/convoys/demo-convoy-2.json +72 -0
  61. package/src/dashboard/dist/data/overall-stats.json +36 -0
  62. package/src/dashboard/dist/index.html +701 -3
  63. package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
  64. package/src/dashboard/public/data/.gitkeep +0 -0
  65. package/src/dashboard/public/data/convoy-list.json +20 -0
  66. package/src/dashboard/public/data/convoys/demo-convoy-1.json +111 -0
  67. package/src/dashboard/public/data/convoys/demo-convoy-2.json +72 -0
  68. package/src/dashboard/public/data/overall-stats.json +36 -0
  69. package/src/dashboard/scripts/etl.test.ts +210 -0
  70. package/src/dashboard/scripts/etl.ts +121 -0
  71. package/src/dashboard/scripts/generate-demo-db.test.ts +30 -0
  72. package/src/dashboard/scripts/generate-demo-db.ts +140 -0
  73. package/src/dashboard/scripts/integration-test.ts +504 -0
  74. package/src/dashboard/scripts/verify-demo-data.sh +51 -0
  75. package/src/dashboard/src/pages/index.astro +854 -15
  76. package/src/dashboard/src/styles/dashboard.css +557 -1
  77. package/src/orchestrator/prompts/generate-convoy.prompt.md +212 -13
@@ -0,0 +1,146 @@
1
+ export interface DashboardOverallStats {
2
+ total_convoys: number;
3
+ running_convoys: number;
4
+ successful_convoys: number;
5
+ failed_convoys: number;
6
+ avg_convoy_duration_sec: number | null;
7
+ p95_convoy_duration_sec: number | null;
8
+ total_tokens: number;
9
+ total_cost_usd: number;
10
+ top_agents: Array<{
11
+ agent: string;
12
+ task_count: number;
13
+ total_tokens: number;
14
+ }>;
15
+ top_models: Array<{
16
+ model: string;
17
+ task_count: number;
18
+ total_tokens: number;
19
+ }>;
20
+ retry_queue_count: number;
21
+ disputed_tasks: number;
22
+ }
23
+ export interface DashboardConvoySummary {
24
+ id: string;
25
+ name: string;
26
+ status: string;
27
+ branch: string | null;
28
+ created_at: string;
29
+ started_at: string | null;
30
+ finished_at: string | null;
31
+ duration_sec: number | null;
32
+ total_tokens: number | null;
33
+ total_cost_usd: number | null;
34
+ tasks_total: number;
35
+ tasks_done: number;
36
+ tasks_running: number;
37
+ tasks_waiting: number;
38
+ tasks_failed: number;
39
+ tasks_retrying: number;
40
+ }
41
+ export interface DashboardTaskSummary {
42
+ id: string;
43
+ phase: number;
44
+ agent: string;
45
+ model: string | null;
46
+ status: string;
47
+ duration_sec: number | null;
48
+ retries: number;
49
+ files: string[];
50
+ total_tokens: number | null;
51
+ cost_usd: number | null;
52
+ review_level: string | null;
53
+ review_verdict: string | null;
54
+ drift_score: number | null;
55
+ }
56
+ export interface DashboardConvoyDetail {
57
+ convoy: {
58
+ id: string;
59
+ name: string;
60
+ status: string;
61
+ created_at: string;
62
+ finished_at: string | null;
63
+ branch: string | null;
64
+ total_tokens: number | null;
65
+ total_cost_usd: number | null;
66
+ };
67
+ taskSummary: {
68
+ total: number;
69
+ done: number;
70
+ running: number;
71
+ failed: number;
72
+ review_blocked: number;
73
+ disputed: number;
74
+ reviewed: number;
75
+ panel_reviewed: number;
76
+ tasks_with_drift: number;
77
+ max_drift_score: number | null;
78
+ drift_retried: number;
79
+ };
80
+ quality: {
81
+ reviewed_tasks: number;
82
+ review_blocked_tasks: number;
83
+ disputed_tasks: number;
84
+ panel_reviews: number;
85
+ };
86
+ drift: {
87
+ tasks_with_drift: number;
88
+ max_drift_score: number | null;
89
+ drift_retried_tasks: number;
90
+ };
91
+ dlq_count: number;
92
+ dlq_entries: Array<{
93
+ id: string;
94
+ task_id: string;
95
+ agent: string;
96
+ failure_type: string;
97
+ attempts: number;
98
+ resolved: number;
99
+ }>;
100
+ artifact_count: number;
101
+ artifacts: Array<{
102
+ id: string;
103
+ name: string;
104
+ type: string;
105
+ task_id: string;
106
+ created_at: string;
107
+ }>;
108
+ has_more_events: boolean;
109
+ events: Array<{
110
+ type: string;
111
+ task_id: string | null;
112
+ data: unknown;
113
+ created_at: string;
114
+ }>;
115
+ tasks: Array<{
116
+ id: string;
117
+ phase: number;
118
+ agent: string;
119
+ model: string | null;
120
+ status: string;
121
+ retries: number;
122
+ started_at: string | null;
123
+ finished_at: string | null;
124
+ total_tokens: number | null;
125
+ cost_usd: number | null;
126
+ review_level: string | null;
127
+ review_verdict: string | null;
128
+ review_tokens: number | null;
129
+ review_model: string | null;
130
+ panel_attempts: number | null;
131
+ dispute_id: string | null;
132
+ drift_score: number | null;
133
+ drift_retried: number | null;
134
+ files: string[] | null;
135
+ }>;
136
+ }
137
+ export interface DashboardTimelineEvent {
138
+ id: number;
139
+ timestamp: string;
140
+ type: string;
141
+ convoy_id: string | null;
142
+ task_id: string | null;
143
+ worker_id: string | null;
144
+ summary: string;
145
+ }
146
+ //# sourceMappingURL=dashboard-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-types.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/dashboard-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dashboard-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-types.js","sourceRoot":"","sources":["../../../src/cli/convoy/dashboard-types.ts"],"names":[],"mappings":""}
@@ -86,7 +86,6 @@ export declare class CircuitBreakerManager {
86
86
  * Fails fast if there are uncommitted changes.
87
87
  */
88
88
  export declare function ensureBranch(branchName: string, basePath: string): Promise<void>;
89
- export declare function recoverNdjson(store: ConvoyStore, convoyId: string, ndjsonPath: string): void;
90
89
  export interface ConvoyGuardResult {
91
90
  passed: boolean;
92
91
  warnings: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/engine.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { execFile as execFileCb } from 'node:child_process';
2
2
  import { createHash } from 'node:crypto';
3
- import { appendFileSync, closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from 'node:fs';
3
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, } from 'node:fs';
4
4
  import { dirname, join, resolve } from 'node:path';
5
5
  import { DatabaseSync } from 'node:sqlite';
6
6
  import { promisify } from 'node:util';
7
7
  import { createConvoyStore, ConvoyArtifactLimitError } from './store.js';
8
8
  import { acquireEngineLock } from './lock.js';
9
- import { createEventEmitter } from './events.js';
9
+ import { createEventEmitter, ndjsonPathForConvoy, recoverNdjson } from './events.js';
10
10
  import { createWorktreeManager } from './worktree.js';
11
11
  import { createMergeQueue, MergeConflictError } from './merge.js';
12
12
  import { createHealthMonitor, detectDrift } from './health.js';
@@ -129,83 +129,6 @@ export async function ensureBranch(branchName, basePath) {
129
129
  await execFile('git', ['checkout', '-b', branchName], { cwd: basePath });
130
130
  }
131
131
  }
132
- // ── Internal helpers ──────────────────────────────────────────────────────────
133
- /**
134
- * Truncate any trailing partial line in the NDJSON file, then replay any SQLite
135
- * events for the given convoy that are missing from the file.
136
- * Exported for unit testing.
137
- */
138
- function safeJsonParse(raw) {
139
- try {
140
- return JSON.parse(raw);
141
- }
142
- catch {
143
- return {};
144
- }
145
- }
146
- export function recoverNdjson(store, convoyId, ndjsonPath) {
147
- // 1. Read the NDJSON file (if it exists)
148
- let fileContent;
149
- try {
150
- fileContent = readFileSync(ndjsonPath, 'utf8');
151
- }
152
- catch {
153
- fileContent = '';
154
- }
155
- // 2. Truncate any partial trailing line (no \n terminator)
156
- if (fileContent.length > 0 && !fileContent.endsWith('\n')) {
157
- const lastNewline = fileContent.lastIndexOf('\n');
158
- if (lastNewline === -1) {
159
- writeFileSync(ndjsonPath, '');
160
- fileContent = '';
161
- }
162
- else {
163
- writeFileSync(ndjsonPath, fileContent.slice(0, lastNewline + 1));
164
- fileContent = fileContent.slice(0, lastNewline + 1);
165
- }
166
- }
167
- // 3. Count valid NDJSON event IDs for this convoy
168
- const ndjsonIds = new Set();
169
- for (const line of fileContent.split('\n')) {
170
- if (!line.trim())
171
- continue;
172
- try {
173
- const parsed = JSON.parse(line);
174
- if (parsed.convoy_id === convoyId && parsed._event_id != null) {
175
- ndjsonIds.add(parsed._event_id);
176
- }
177
- }
178
- catch {
179
- // Skip unparseable lines
180
- }
181
- }
182
- // 4. Get all SQLite events for this convoy
183
- const sqliteEvents = store.getEvents(convoyId);
184
- // 5. Replay missing events (those in SQLite but not in NDJSON)
185
- const missing = sqliteEvents.filter(e => e.id != null && !ndjsonIds.has(e.id));
186
- if (missing.length > 0) {
187
- const fd = openSync(ndjsonPath, 'a');
188
- try {
189
- for (const event of missing) {
190
- const parsedData = event.data ? safeJsonParse(event.data) : {};
191
- const record = {
192
- ...parsedData,
193
- _event_id: event.id,
194
- timestamp: event.created_at,
195
- type: event.type,
196
- convoy_id: event.convoy_id,
197
- task_id: event.task_id,
198
- worker_id: event.worker_id,
199
- };
200
- appendFileSync(fd, JSON.stringify(record) + '\n');
201
- }
202
- fsyncSync(fd);
203
- }
204
- finally {
205
- closeSync(fd);
206
- }
207
- }
208
- }
209
132
  export function runConvoyGuard(store, convoyId, _wtManager, ndjsonPath, guardConfig) {
210
133
  // If guard is explicitly disabled, skip all checks
211
134
  if (guardConfig?.enabled === false) {
@@ -224,16 +147,9 @@ export function runConvoyGuard(store, convoyId, _wtManager, ndjsonPath, guardCon
224
147
  try {
225
148
  const content = readFileSync(ndjsonPath, 'utf8');
226
149
  const lines = content.split('\n').filter(l => l.trim());
227
- const convoyLines = lines.filter(l => {
228
- try {
229
- return JSON.parse(l).convoy_id === convoyId;
230
- }
231
- catch {
232
- return false;
233
- }
234
- });
235
- if (convoyLines.length < completedTasks.length) {
236
- warnings.push(`NDJSON record count (${convoyLines.length}) < completed tasks (${completedTasks.length})`);
150
+ // Per-convoy file — all records belong to this convoy, no need to filter by convoy_id
151
+ if (lines.length < completedTasks.length) {
152
+ warnings.push(`NDJSON record count (${lines.length}) < completed tasks (${completedTasks.length})`);
237
153
  }
238
154
  }
239
155
  catch {
@@ -251,7 +167,19 @@ export function runConvoyGuard(store, convoyId, _wtManager, ndjsonPath, guardCon
251
167
  }
252
168
  }
253
169
  // Check 4: Gate results recorded for all gates that ran
254
- const gateEvents = events.filter(e => e.type === 'built_in_gate_result' || (e.data != null && e.data.includes('gate')));
170
+ const gateEvents = events.filter(e => {
171
+ if (e.type === 'built_in_gate_result')
172
+ return true;
173
+ if (e.data == null)
174
+ return false;
175
+ try {
176
+ const parsed = JSON.parse(e.data);
177
+ return 'gate' in parsed;
178
+ }
179
+ catch {
180
+ return false;
181
+ }
182
+ });
255
183
  const tasksWithGates = tasks.filter(t => t.gates);
256
184
  if (tasksWithGates.length > 0 && gateEvents.length === 0) {
257
185
  warnings.push('Tasks have gates configured but no gate result events found');
@@ -827,6 +755,7 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
827
755
  skipTask(t.id, `on_exhausted: stop — task "${taskRecord.id}" exhausted retries`);
828
756
  }
829
757
  store.updateConvoyStatus(convoyId, 'failed');
758
+ events.emit('convoy_failed', { status: 'failed', reason: `on_exhausted: stop — task "${taskRecord.id}" exhausted retries` }, { convoy_id: convoyId });
830
759
  }
831
760
  else if (exhausted === 'dlq' || exhausted === 'skip') {
832
761
  // Default behavior: cascade failure to dependents only
@@ -2253,6 +2182,12 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
2253
2182
  finished_at: new Date().toISOString(),
2254
2183
  total_tokens: convoyTotalTokens,
2255
2184
  });
2185
+ if (finalStatus === 'done') {
2186
+ events.emit('convoy_finished', { status: 'done' }, { convoy_id: convoyId });
2187
+ }
2188
+ else {
2189
+ events.emit('convoy_failed', { status: finalStatus, reason: finalStatus === 'gate-failed' ? 'Gate check failed' : 'One or more tasks failed' }, { convoy_id: convoyId });
2190
+ }
2256
2191
  // Run convoy guard checks
2257
2192
  const guardResult = runConvoyGuard(store, convoyId, wtManager, ndjsonPath, spec.guard);
2258
2193
  if (guardResult.warnings.length > 0) {
@@ -2330,9 +2265,8 @@ export function createConvoyEngine(options) {
2330
2265
  lock.startHeartbeat();
2331
2266
  const store = createConvoyStore(dbPath);
2332
2267
  const ndjsonPath = options.logsDir
2333
- ? join(options.logsDir, 'convoy-events.ndjson')
2334
- : join(basePath, '.opencastle', 'logs', 'convoy-events.ndjson');
2335
- mkdirSync(dirname(ndjsonPath), { recursive: true });
2268
+ ? join(options.logsDir, 'convoys', `${convoyId}.ndjson`)
2269
+ : ndjsonPathForConvoy(convoyId, basePath);
2336
2270
  const events = createEventEmitter(store, { ndjsonPath });
2337
2271
  const wtManager = options._worktreeManager ?? createWorktreeManager(basePath);
2338
2272
  const mergeQueue = options._mergeQueue ?? createMergeQueue(basePath);
@@ -2428,9 +2362,8 @@ export function createConvoyEngine(options) {
2428
2362
  lock.startHeartbeat();
2429
2363
  const store = createConvoyStore(dbPath);
2430
2364
  const ndjsonPath = options.logsDir
2431
- ? join(options.logsDir, 'convoy-events.ndjson')
2432
- : join(basePath, '.opencastle', 'logs', 'convoy-events.ndjson');
2433
- mkdirSync(dirname(ndjsonPath), { recursive: true });
2365
+ ? join(options.logsDir, 'convoys', `${convoyId}.ndjson`)
2366
+ : ndjsonPathForConvoy(convoyId, basePath);
2434
2367
  const events = createEventEmitter(store, { ndjsonPath });
2435
2368
  const wtManager = options._worktreeManager ?? createWorktreeManager(basePath);
2436
2369
  const mergeQueue = options._mergeQueue ?? createMergeQueue(basePath);
@@ -2486,9 +2419,8 @@ export function createConvoyEngine(options) {
2486
2419
  mkdirSync(dirname(dbPath), { recursive: true });
2487
2420
  const store = createConvoyStore(dbPath);
2488
2421
  const ndjsonPath = options.logsDir
2489
- ? join(options.logsDir, 'convoy-events.ndjson')
2490
- : join(basePath, '.opencastle', 'logs', 'convoy-events.ndjson');
2491
- mkdirSync(dirname(ndjsonPath), { recursive: true });
2422
+ ? join(options.logsDir, 'convoys', `${convoyId}.ndjson`)
2423
+ : ndjsonPathForConvoy(convoyId, basePath);
2492
2424
  const events = createEventEmitter(store, { ndjsonPath });
2493
2425
  try {
2494
2426
  const allTasks = store.getTasksByConvoy(convoyId);