opencastle 0.28.0 → 0.29.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/README.md +12 -3
- package/dist/cli/convoy/engine.d.ts.map +1 -1
- package/dist/cli/convoy/engine.js +0 -9
- package/dist/cli/convoy/engine.js.map +1 -1
- package/dist/cli/convoy/engine.test.js +1 -0
- package/dist/cli/convoy/engine.test.js.map +1 -1
- package/dist/cli/convoy/export.d.ts +1 -3
- package/dist/cli/convoy/export.d.ts.map +1 -1
- package/dist/cli/convoy/export.js +9 -88
- package/dist/cli/convoy/export.js.map +1 -1
- package/dist/cli/convoy/export.test.js +7 -186
- package/dist/cli/convoy/export.test.js.map +1 -1
- package/dist/cli/convoy/pipeline.d.ts.map +1 -1
- package/dist/cli/convoy/pipeline.js +0 -21
- package/dist/cli/convoy/pipeline.js.map +1 -1
- package/dist/cli/convoy/pipeline.test.js +0 -21
- package/dist/cli/convoy/pipeline.test.js.map +1 -1
- package/dist/cli/dashboard.d.ts.map +1 -1
- package/dist/cli/dashboard.js +32 -8
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/destroy.d.ts.map +1 -1
- package/dist/cli/destroy.js +13 -0
- package/dist/cli/destroy.js.map +1 -1
- package/dist/cli/dispute.d.ts +3 -0
- package/dist/cli/dispute.d.ts.map +1 -0
- package/dist/cli/dispute.js +25 -0
- package/dist/cli/dispute.js.map +1 -0
- package/dist/cli/doctor.d.ts +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +14 -1
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/eject.d.ts.map +1 -1
- package/dist/cli/eject.js +14 -0
- package/dist/cli/eject.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +14 -0
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/log.d.ts +0 -11
- package/dist/cli/log.d.ts.map +1 -1
- package/dist/cli/log.js +2 -114
- package/dist/cli/log.js.map +1 -1
- package/dist/cli/pipeline.js +21 -5
- package/dist/cli/pipeline.js.map +1 -1
- package/dist/cli/run.js +2 -2
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +16 -0
- package/dist/cli/update.js.map +1 -1
- package/dist/cli/watch.d.ts.map +1 -1
- package/dist/cli/watch.js +1 -3
- package/dist/cli/watch.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/convoy/engine.test.ts +1 -0
- package/src/cli/convoy/engine.ts +0 -3
- package/src/cli/convoy/export.test.ts +7 -224
- package/src/cli/convoy/export.ts +10 -106
- package/src/cli/convoy/pipeline.test.ts +0 -25
- package/src/cli/convoy/pipeline.ts +0 -19
- package/src/cli/dashboard.ts +33 -8
- package/src/cli/destroy.ts +15 -0
- package/src/cli/dispute.ts +28 -0
- package/src/cli/doctor.ts +16 -1
- package/src/cli/eject.ts +16 -0
- package/src/cli/init.ts +16 -0
- package/src/cli/log.ts +2 -120
- package/src/cli/pipeline.ts +24 -5
- package/src/cli/run.ts +2 -2
- package/src/cli/update.ts +18 -0
- package/src/cli/watch.ts +1 -3
- package/src/dashboard/dist/_astro/index.Je1YjU_y.css +1 -0
- package/src/dashboard/dist/index.html +141 -1391
- package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
- package/src/dashboard/scripts/etl.test.ts +4 -62
- package/src/dashboard/scripts/etl.ts +13 -33
- package/src/dashboard/src/pages/index.astro +204 -1630
- package/src/dashboard/src/styles/dashboard.css +473 -7
- package/src/orchestrator/prompts/brainstorm.prompt.md +1 -0
- package/src/orchestrator/prompts/generate-convoy.prompt.md +7 -0
- package/src/orchestrator/prompts/generate-prd.prompt.md +6 -0
- package/dist/cli/convoy/log-merge.test.d.ts +0 -2
- package/dist/cli/convoy/log-merge.test.d.ts.map +0 -1
- package/dist/cli/convoy/log-merge.test.js +0 -147
- package/dist/cli/convoy/log-merge.test.js.map +0 -1
- package/src/cli/convoy/log-merge.test.ts +0 -179
- package/src/dashboard/dist/_astro/index.6L3_HsPT.css +0 -1
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
"hash": "
|
|
2
|
+
"hash": "0aac54bb",
|
|
3
3
|
"configHash": "30f8ea04",
|
|
4
|
-
"lockfileHash": "
|
|
5
|
-
"browserHash": "
|
|
4
|
+
"lockfileHash": "407e8b0e",
|
|
5
|
+
"browserHash": "3a6bf93e",
|
|
6
6
|
"optimized": {
|
|
7
7
|
"astro > cssesc": {
|
|
8
8
|
"src": "../../../../../node_modules/cssesc/cssesc.js",
|
|
9
9
|
"file": "astro___cssesc.js",
|
|
10
|
-
"fileHash": "
|
|
10
|
+
"fileHash": "2a163e0c",
|
|
11
11
|
"needsInterop": true
|
|
12
12
|
},
|
|
13
13
|
"astro > aria-query": {
|
|
14
14
|
"src": "../../../../../node_modules/aria-query/lib/index.js",
|
|
15
15
|
"file": "astro___aria-query.js",
|
|
16
|
-
"fileHash": "
|
|
16
|
+
"fileHash": "34f9775b",
|
|
17
17
|
"needsInterop": true
|
|
18
18
|
},
|
|
19
19
|
"astro > axobject-query": {
|
|
20
20
|
"src": "../../../../../node_modules/axobject-query/lib/index.js",
|
|
21
21
|
"file": "astro___axobject-query.js",
|
|
22
|
-
"fileHash": "
|
|
22
|
+
"fileHash": "29370f9f",
|
|
23
23
|
"needsInterop": true
|
|
24
24
|
}
|
|
25
25
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdtempSync, rmSync, realpathSync, readFileSync, existsSync
|
|
1
|
+
import { mkdtempSync, rmSync, realpathSync, readFileSync, existsSync } from 'node:fs'
|
|
2
2
|
import { tmpdir } from 'node:os'
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
@@ -47,14 +47,13 @@ describe('runEtl — no database', () => {
|
|
|
47
47
|
it('returns zero counts when db is missing', async () => {
|
|
48
48
|
const dbPath = join(tmpDir, 'nonexistent.db')
|
|
49
49
|
const result = await runEtl({ dbPath, outputDir })
|
|
50
|
-
expect(result).toEqual({ convoyCount: 0
|
|
50
|
+
expect(result).toEqual({ convoyCount: 0 })
|
|
51
51
|
})
|
|
52
52
|
|
|
53
|
-
it('creates the output directory
|
|
53
|
+
it('creates the output directory when db is missing', async () => {
|
|
54
54
|
const dbPath = join(tmpDir, 'nonexistent.db')
|
|
55
55
|
await runEtl({ dbPath, outputDir })
|
|
56
56
|
expect(existsSync(outputDir)).toBe(true)
|
|
57
|
-
expect(existsSync(join(outputDir, 'convoys'))).toBe(true)
|
|
58
57
|
})
|
|
59
58
|
})
|
|
60
59
|
|
|
@@ -120,10 +119,9 @@ describe('runEtl — with seeded database', () => {
|
|
|
120
119
|
}
|
|
121
120
|
})
|
|
122
121
|
|
|
123
|
-
it('returns correct convoy
|
|
122
|
+
it('returns correct convoy count', async () => {
|
|
124
123
|
const result = await runEtl({ dbPath, outputDir })
|
|
125
124
|
expect(result.convoyCount).toBe(2)
|
|
126
|
-
expect(result.taskCount).toBe(2)
|
|
127
125
|
})
|
|
128
126
|
|
|
129
127
|
it('overall-stats.json has correct convoy counts', async () => {
|
|
@@ -151,60 +149,4 @@ describe('runEtl — with seeded database', () => {
|
|
|
151
149
|
expect(item).toHaveProperty('total_cost_usd')
|
|
152
150
|
}
|
|
153
151
|
})
|
|
154
|
-
|
|
155
|
-
it('creates per-convoy detail JSON files', async () => {
|
|
156
|
-
await runEtl({ dbPath, outputDir })
|
|
157
|
-
const detailPath = join(outputDir, 'convoys', 'convoy-abc.json')
|
|
158
|
-
expect(existsSync(detailPath)).toBe(true)
|
|
159
|
-
const detail = JSON.parse(readFileSync(detailPath, 'utf8'))
|
|
160
|
-
expect(detail.convoy.id).toBe('convoy-abc')
|
|
161
|
-
expect(detail.convoy.name).toBe('Test Convoy')
|
|
162
|
-
expect(detail.convoy.status).toBe('done')
|
|
163
|
-
expect(detail.convoy).toHaveProperty('branch')
|
|
164
|
-
expect(detail.convoy).toHaveProperty('total_tokens')
|
|
165
|
-
expect(detail.convoy).toHaveProperty('total_cost_usd')
|
|
166
|
-
expect(detail).toHaveProperty('taskSummary')
|
|
167
|
-
expect(detail.taskSummary).toHaveProperty('total')
|
|
168
|
-
expect(Array.isArray(detail.tasks)).toBe(true)
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
it('detail file has correct task fields', async () => {
|
|
172
|
-
await runEtl({ dbPath, outputDir })
|
|
173
|
-
const detail = JSON.parse(
|
|
174
|
-
readFileSync(join(outputDir, 'convoys', 'convoy-abc.json'), 'utf8'),
|
|
175
|
-
)
|
|
176
|
-
expect(detail.tasks).toHaveLength(2)
|
|
177
|
-
for (const task of detail.tasks) {
|
|
178
|
-
expect(task).toHaveProperty('id')
|
|
179
|
-
expect(task).toHaveProperty('phase')
|
|
180
|
-
expect(task).toHaveProperty('agent')
|
|
181
|
-
expect(task).toHaveProperty('model')
|
|
182
|
-
expect(task).toHaveProperty('status')
|
|
183
|
-
expect(task).toHaveProperty('retries')
|
|
184
|
-
expect(task).toHaveProperty('started_at')
|
|
185
|
-
expect(task).toHaveProperty('finished_at')
|
|
186
|
-
expect(task).toHaveProperty('total_tokens')
|
|
187
|
-
expect(task).toHaveProperty('cost_usd')
|
|
188
|
-
expect(task).toHaveProperty('review_level')
|
|
189
|
-
expect(task).toHaveProperty('review_verdict')
|
|
190
|
-
expect(task).toHaveProperty('drift_score')
|
|
191
|
-
}
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
it('creates detail file for each convoy', async () => {
|
|
195
|
-
await runEtl({ dbPath, outputDir })
|
|
196
|
-
expect(existsSync(join(outputDir, 'convoys', 'convoy-abc.json'))).toBe(true)
|
|
197
|
-
expect(existsSync(join(outputDir, 'convoys', 'convoy-def.json'))).toBe(true)
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
it('detail file includes artifacts and events fields', async () => {
|
|
201
|
-
await runEtl({ dbPath, outputDir })
|
|
202
|
-
const detail = JSON.parse(
|
|
203
|
-
readFileSync(join(outputDir, 'convoys', 'convoy-abc.json'), 'utf8'),
|
|
204
|
-
)
|
|
205
|
-
expect(Array.isArray(detail.artifacts)).toBe(true)
|
|
206
|
-
expect(typeof detail.artifact_count).toBe('number')
|
|
207
|
-
expect(typeof detail.has_more_events).toBe('boolean')
|
|
208
|
-
expect(Array.isArray(detail.events)).toBe(true)
|
|
209
|
-
})
|
|
210
152
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, writeFileSync
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
|
|
2
2
|
import { resolve, dirname } from 'node:path'
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
4
|
|
|
@@ -8,12 +8,10 @@ const __dirname = dirname(__filename)
|
|
|
8
8
|
export interface EtlOptions {
|
|
9
9
|
dbPath: string
|
|
10
10
|
outputDir: string
|
|
11
|
-
eventsPath?: string
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
export interface EtlResult {
|
|
15
14
|
convoyCount: number
|
|
16
|
-
taskCount: number
|
|
17
15
|
}
|
|
18
16
|
|
|
19
17
|
const EMPTY_OVERALL_STATS = {
|
|
@@ -29,7 +27,6 @@ export async function runEtl(options: EtlOptions): Promise<EtlResult> {
|
|
|
29
27
|
const { dbPath, outputDir } = options
|
|
30
28
|
|
|
31
29
|
mkdirSync(outputDir, { recursive: true })
|
|
32
|
-
mkdirSync(resolve(outputDir, 'convoys'), { recursive: true })
|
|
33
30
|
|
|
34
31
|
if (!existsSync(dbPath)) {
|
|
35
32
|
console.warn(` \u26a0 No convoy database found at ${dbPath}. Writing empty JSON files.`)
|
|
@@ -39,7 +36,7 @@ export async function runEtl(options: EtlOptions): Promise<EtlResult> {
|
|
|
39
36
|
'utf8',
|
|
40
37
|
)
|
|
41
38
|
writeFileSync(resolve(outputDir, 'convoy-list.json'), JSON.stringify([], null, 2), 'utf8')
|
|
42
|
-
return { convoyCount: 0
|
|
39
|
+
return { convoyCount: 0 }
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
const { createConvoyStore } = await import('../../cli/convoy/store.js')
|
|
@@ -66,6 +63,7 @@ export async function runEtl(options: EtlOptions): Promise<EtlResult> {
|
|
|
66
63
|
name: c.name,
|
|
67
64
|
status: c.status,
|
|
68
65
|
created_at: c.created_at,
|
|
66
|
+
started_at: c.started_at,
|
|
69
67
|
finished_at: c.finished_at,
|
|
70
68
|
total_tokens: c.total_tokens,
|
|
71
69
|
total_cost_usd: c.total_cost_usd,
|
|
@@ -76,53 +74,35 @@ export async function runEtl(options: EtlOptions): Promise<EtlResult> {
|
|
|
76
74
|
'utf8',
|
|
77
75
|
)
|
|
78
76
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
mkdirSync(resolve(outputDir, 'convoys'), { recursive: true })
|
|
78
|
+
let detailCount = 0
|
|
79
|
+
for (const c of allConvoys) {
|
|
80
|
+
const detail = store.getConvoyDetails(c.id)
|
|
82
81
|
if (detail) {
|
|
83
|
-
totalTasks += detail.tasks.length
|
|
84
82
|
writeFileSync(
|
|
85
|
-
resolve(outputDir, 'convoys',
|
|
83
|
+
resolve(outputDir, 'convoys', c.id + '.json'),
|
|
86
84
|
JSON.stringify(detail, null, 2),
|
|
87
85
|
'utf8',
|
|
88
86
|
)
|
|
87
|
+
detailCount++
|
|
89
88
|
}
|
|
90
89
|
}
|
|
91
90
|
|
|
92
|
-
console.log(`ETL complete: ${allConvoys.length} convoys
|
|
91
|
+
console.log(`ETL complete: ${allConvoys.length} convoys summarized, ${detailCount} detail files generated.`)
|
|
93
92
|
|
|
94
|
-
|
|
95
|
-
const eventsSource = options.eventsPath
|
|
96
|
-
? resolve(process.cwd(), options.eventsPath)
|
|
97
|
-
: resolve(process.cwd(), '.opencastle', 'logs', 'events.ndjson')
|
|
98
|
-
if (existsSync(eventsSource)) {
|
|
99
|
-
copyFileSync(eventsSource, resolve(outputDir, 'events.ndjson'))
|
|
100
|
-
} else {
|
|
101
|
-
writeFileSync(resolve(outputDir, 'events.ndjson'), '', 'utf8')
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Copy pipelines log (optional, write empty if absent)
|
|
105
|
-
const pipelinesSource = resolve(process.cwd(), '.opencastle', 'logs', 'pipelines.ndjson')
|
|
106
|
-
if (existsSync(pipelinesSource)) {
|
|
107
|
-
copyFileSync(pipelinesSource, resolve(outputDir, 'pipelines.ndjson'))
|
|
108
|
-
} else {
|
|
109
|
-
writeFileSync(resolve(outputDir, 'pipelines.ndjson'), '', 'utf8')
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return { convoyCount: allConvoys.length, taskCount: totalTasks }
|
|
93
|
+
return { convoyCount: allConvoys.length }
|
|
113
94
|
} finally {
|
|
114
95
|
store.close()
|
|
115
96
|
}
|
|
116
97
|
}
|
|
117
98
|
|
|
118
|
-
function parseArgs(): { db?: string; out?: string
|
|
99
|
+
function parseArgs(): { db?: string; out?: string } {
|
|
119
100
|
const args = process.argv.slice(2)
|
|
120
101
|
const result: Record<string, string> = {}
|
|
121
102
|
for (let i = 0; i < args.length; i++) {
|
|
122
103
|
const a = args[i]
|
|
123
104
|
if (a === '--db' && args[i+1]) { result.db = args[++i] }
|
|
124
105
|
else if (a === '--out' && args[i+1]) { result.out = args[++i] }
|
|
125
|
-
else if (a === '--events' && args[i+1]) { result.events = args[++i] }
|
|
126
106
|
}
|
|
127
107
|
return result
|
|
128
108
|
}
|
|
@@ -135,7 +115,7 @@ if (isMain) {
|
|
|
135
115
|
const parsed = parseArgs()
|
|
136
116
|
const dbPath = parsed.db != null ? resolve(process.cwd(), parsed.db) : resolve(process.cwd(), '.opencastle', 'convoy.db')
|
|
137
117
|
const outputDir = parsed.out != null ? resolve(process.cwd(), parsed.out) : resolve(__dirname, '..', 'public', 'data')
|
|
138
|
-
runEtl({ dbPath, outputDir
|
|
118
|
+
runEtl({ dbPath, outputDir }).catch((err: unknown) => {
|
|
139
119
|
console.error('ETL failed:', (err as Error).message)
|
|
140
120
|
process.exit(1)
|
|
141
121
|
})
|