opencastle 0.32.5 → 0.32.7

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 (109) hide show
  1. package/README.md +13 -3
  2. package/bin/cli.mjs +2 -0
  3. package/dist/cli/convoy/engine.d.ts.map +1 -1
  4. package/dist/cli/convoy/engine.js +79 -4
  5. package/dist/cli/convoy/engine.js.map +1 -1
  6. package/dist/cli/convoy/engine.test.js +11 -9
  7. package/dist/cli/convoy/engine.test.js.map +1 -1
  8. package/dist/dashboard/scripts/etl.js +17 -2
  9. package/dist/dashboard/scripts/etl.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/cli/convoy/engine.test.ts +11 -9
  12. package/src/cli/convoy/engine.ts +78 -4
  13. package/src/dashboard/dist/_astro/index.6xXNs4L2.css +1 -0
  14. package/src/dashboard/dist/data/convoy-list.json +27 -13
  15. package/src/dashboard/dist/data/convoys/demo-api-v2.json +16 -10
  16. package/src/dashboard/dist/data/convoys/demo-auth-revamp.json +25 -15
  17. package/src/dashboard/dist/data/convoys/demo-dashboard-ui.json +35 -21
  18. package/src/dashboard/dist/data/convoys/demo-data-pipeline.json +17 -11
  19. package/src/dashboard/dist/data/convoys/demo-deploy-ci.json +8 -4
  20. package/src/dashboard/dist/data/convoys/demo-docs-update.json +13 -9
  21. package/src/dashboard/dist/data/convoys/demo-perf-opt.json +22 -14
  22. package/src/dashboard/dist/data/overall-stats.json +36 -2
  23. package/src/dashboard/dist/index.html +149 -93
  24. package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
  25. package/src/dashboard/public/data/convoy-list.json +27 -13
  26. package/src/dashboard/public/data/convoys/demo-api-v2.json +16 -10
  27. package/src/dashboard/public/data/convoys/demo-auth-revamp.json +25 -15
  28. package/src/dashboard/public/data/convoys/demo-dashboard-ui.json +35 -21
  29. package/src/dashboard/public/data/convoys/demo-data-pipeline.json +17 -11
  30. package/src/dashboard/public/data/convoys/demo-deploy-ci.json +8 -4
  31. package/src/dashboard/public/data/convoys/demo-docs-update.json +13 -9
  32. package/src/dashboard/public/data/convoys/demo-perf-opt.json +22 -14
  33. package/src/dashboard/public/data/overall-stats.json +36 -2
  34. package/src/dashboard/scripts/etl.ts +15 -3
  35. package/src/dashboard/scripts/generate-demo-db.ts +42 -34
  36. package/src/dashboard/src/pages/index.astro +159 -112
  37. package/src/dashboard/src/styles/dashboard.css +58 -3
  38. package/src/orchestrator/agents/api-designer.agent.md +25 -34
  39. package/src/orchestrator/agents/architect.agent.md +40 -84
  40. package/src/orchestrator/agents/content-engineer.agent.md +29 -31
  41. package/src/orchestrator/agents/copywriter.agent.md +35 -60
  42. package/src/orchestrator/agents/data-expert.agent.md +24 -30
  43. package/src/orchestrator/agents/database-engineer.agent.md +26 -31
  44. package/src/orchestrator/agents/developer.agent.md +32 -34
  45. package/src/orchestrator/agents/devops-expert.agent.md +31 -26
  46. package/src/orchestrator/agents/documentation-writer.agent.md +29 -29
  47. package/src/orchestrator/agents/performance-expert.agent.md +36 -33
  48. package/src/orchestrator/agents/release-manager.agent.md +25 -34
  49. package/src/orchestrator/agents/researcher.agent.md +41 -95
  50. package/src/orchestrator/agents/reviewer.agent.md +24 -34
  51. package/src/orchestrator/agents/security-expert.agent.md +35 -39
  52. package/src/orchestrator/agents/seo-specialist.agent.md +25 -32
  53. package/src/orchestrator/agents/session-guard.agent.md +20 -79
  54. package/src/orchestrator/agents/team-lead.agent.md +50 -254
  55. package/src/orchestrator/agents/testing-expert.agent.md +37 -49
  56. package/src/orchestrator/agents/ui-ux-expert.agent.md +33 -39
  57. package/src/orchestrator/customizations/KNOWN-ISSUES.md +0 -1
  58. package/src/orchestrator/customizations/agents/skill-matrix.json +12 -0
  59. package/src/orchestrator/instructions/general.instructions.md +24 -84
  60. package/src/orchestrator/plugins/astro/SKILL.md +23 -179
  61. package/src/orchestrator/plugins/convex/SKILL.md +38 -12
  62. package/src/orchestrator/plugins/netlify/SKILL.md +17 -13
  63. package/src/orchestrator/plugins/nextjs/SKILL.md +55 -261
  64. package/src/orchestrator/plugins/nx/SKILL.md +20 -72
  65. package/src/orchestrator/plugins/playwright/SKILL.md +5 -17
  66. package/src/orchestrator/plugins/slack/SKILL.md +28 -190
  67. package/src/orchestrator/plugins/teams/SKILL.md +10 -140
  68. package/src/orchestrator/plugins/vitest/SKILL.md +2 -2
  69. package/src/orchestrator/prompts/bug-fix.prompt.md +25 -63
  70. package/src/orchestrator/prompts/implement-feature.prompt.md +29 -66
  71. package/src/orchestrator/prompts/quick-refinement.prompt.md +31 -66
  72. package/src/orchestrator/skills/accessibility-standards/SKILL.md +50 -105
  73. package/src/orchestrator/skills/agent-hooks/SKILL.md +60 -110
  74. package/src/orchestrator/skills/agent-memory/SKILL.md +44 -93
  75. package/src/orchestrator/skills/api-patterns/SKILL.md +20 -68
  76. package/src/orchestrator/skills/code-commenting/SKILL.md +49 -101
  77. package/src/orchestrator/skills/context-map/SKILL.md +47 -88
  78. package/src/orchestrator/skills/data-engineering/SKILL.md +27 -74
  79. package/src/orchestrator/skills/decomposition/SKILL.md +50 -98
  80. package/src/orchestrator/skills/deployment-infrastructure/SKILL.md +44 -107
  81. package/src/orchestrator/skills/documentation-standards/SKILL.md +28 -89
  82. package/src/orchestrator/skills/fast-review/SKILL.md +51 -276
  83. package/src/orchestrator/skills/frontend-design/SKILL.md +53 -163
  84. package/src/orchestrator/skills/git-workflow/SKILL.md +18 -54
  85. package/src/orchestrator/skills/memory-merger/SKILL.md +51 -88
  86. package/src/orchestrator/skills/observability-logging/SKILL.md +29 -75
  87. package/src/orchestrator/skills/orchestration-protocols/SKILL.md +58 -117
  88. package/src/orchestrator/skills/panel-majority-vote/SKILL.md +65 -140
  89. package/src/orchestrator/skills/performance-optimization/SKILL.md +21 -85
  90. package/src/orchestrator/skills/project-consistency/SKILL.md +62 -281
  91. package/src/orchestrator/skills/react-development/SKILL.md +38 -86
  92. package/src/orchestrator/skills/security-hardening/SKILL.md +40 -84
  93. package/src/orchestrator/skills/self-improvement/SKILL.md +26 -60
  94. package/src/orchestrator/skills/seo-patterns/SKILL.md +40 -105
  95. package/src/orchestrator/skills/session-checkpoints/SKILL.md +26 -68
  96. package/src/orchestrator/skills/team-lead-reference/SKILL.md +66 -206
  97. package/src/orchestrator/skills/testing-workflow/SKILL.md +42 -112
  98. package/src/orchestrator/skills/validation-gates/SKILL.md +39 -170
  99. package/src/orchestrator/snippets/base-output-contract.md +14 -0
  100. package/src/orchestrator/snippets/discovered-issues-policy.md +15 -0
  101. package/src/orchestrator/snippets/logging-mandatory.md +11 -0
  102. package/src/orchestrator/snippets/never-expose-secrets.md +22 -0
  103. package/src/dashboard/dist/_astro/index.wyN9vmjZ.css +0 -1
  104. package/src/dashboard/dist/data/convoys/demo-convoy-1.json +0 -111
  105. package/src/dashboard/dist/data/convoys/demo-convoy-2.json +0 -72
  106. package/src/dashboard/dist/data/pipelines.ndjson +0 -5285
  107. package/src/dashboard/public/data/convoys/demo-convoy-1.json +0 -111
  108. package/src/dashboard/public/data/convoys/demo-convoy-2.json +0 -72
  109. package/src/dashboard/public/data/pipelines.ndjson +0 -5285
@@ -51,7 +51,7 @@
51
51
  "name": ".github/workflows/ci.yml",
52
52
  "type": "file",
53
53
  "task_id": "ci-t1",
54
- "created_at": "2026-03-12T22:26:01.389Z"
54
+ "created_at": "2026-03-18T01:18:30.529Z"
55
55
  }
56
56
  ],
57
57
  "has_more_events": false,
@@ -69,7 +69,9 @@
69
69
  {
70
70
  "type": "task_started",
71
71
  "task_id": "ci-t2",
72
- "data": {"mechanism": "background"},
72
+ "data": {
73
+ "mechanism": "background"
74
+ },
73
75
  "created_at": "2026-03-11T08:15:00.000Z"
74
76
  },
75
77
  {
@@ -81,7 +83,9 @@
81
83
  {
82
84
  "type": "task_started",
83
85
  "task_id": "ci-t1",
84
- "data": {"mechanism": "sub-agent"},
86
+ "data": {
87
+ "mechanism": "sub-agent"
88
+ },
85
89
  "created_at": "2026-03-11T08:00:05.000Z"
86
90
  }
87
91
  ],
@@ -96,7 +100,7 @@
96
100
  "started_at": "2026-03-11T08:00:05.000Z",
97
101
  "finished_at": "2026-03-11T08:14:00.000Z",
98
102
  "total_tokens": 6400,
99
- "cost_usd": 0.64,
103
+ "cost_usd": 0.03456,
100
104
  "review_level": null,
101
105
  "review_verdict": null,
102
106
  "review_tokens": null,
@@ -7,7 +7,7 @@
7
7
  "finished_at": "2026-02-28T15:22:00.000Z",
8
8
  "branch": "docs/update-march",
9
9
  "total_tokens": 14800,
10
- "total_cost_usd": 1.48
10
+ "total_cost_usd": 0.0296
11
11
  },
12
12
  "taskSummary": {
13
13
  "total": 3,
@@ -42,21 +42,21 @@
42
42
  "name": "docs/ARCHITECTURE.md",
43
43
  "type": "file",
44
44
  "task_id": "docs-t1",
45
- "created_at": "2026-03-12T22:26:01.388Z"
45
+ "created_at": "2026-03-18T01:18:30.529Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-docs-update-docs-README-md",
49
49
  "name": "docs/README.md",
50
50
  "type": "file",
51
51
  "task_id": "docs-t1",
52
- "created_at": "2026-03-12T22:26:01.388Z"
52
+ "created_at": "2026-03-18T01:18:30.529Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-docs-update-docs-api-reference-json",
56
56
  "name": "docs/api-reference.json",
57
57
  "type": "json",
58
58
  "task_id": "docs-t2",
59
- "created_at": "2026-03-12T22:26:01.389Z"
59
+ "created_at": "2026-03-18T01:18:30.529Z"
60
60
  }
61
61
  ],
62
62
  "has_more_events": false,
@@ -70,7 +70,9 @@
70
70
  {
71
71
  "type": "task_started",
72
72
  "task_id": "docs-t2",
73
- "data": {"mechanism": "sub-agent"},
73
+ "data": {
74
+ "mechanism": "background"
75
+ },
74
76
  "created_at": "2026-02-28T15:15:00.000Z"
75
77
  },
76
78
  {
@@ -82,7 +84,9 @@
82
84
  {
83
85
  "type": "task_started",
84
86
  "task_id": "docs-t1",
85
- "data": {"mechanism": "sub-agent"},
87
+ "data": {
88
+ "mechanism": "sub-agent"
89
+ },
86
90
  "created_at": "2026-02-28T15:00:05.000Z"
87
91
  }
88
92
  ],
@@ -97,7 +101,7 @@
97
101
  "started_at": "2026-02-28T15:00:05.000Z",
98
102
  "finished_at": "2026-02-28T15:14:00.000Z",
99
103
  "total_tokens": 8200,
100
- "cost_usd": 0.82,
104
+ "cost_usd": 0.011807999999999999,
101
105
  "review_level": null,
102
106
  "review_verdict": null,
103
107
  "review_tokens": null,
@@ -118,7 +122,7 @@
118
122
  "started_at": "2026-02-28T15:15:00.000Z",
119
123
  "finished_at": "2026-02-28T15:21:00.000Z",
120
124
  "total_tokens": 6600,
121
- "cost_usd": 0.66,
125
+ "cost_usd": 0.009504,
122
126
  "review_level": null,
123
127
  "review_verdict": null,
124
128
  "review_tokens": null,
@@ -139,7 +143,7 @@
139
143
  "started_at": "2026-02-28T15:17:00.000Z",
140
144
  "finished_at": "2026-02-28T15:21:00.000Z",
141
145
  "total_tokens": 800,
142
- "cost_usd": 0.08,
146
+ "cost_usd": 0.001152,
143
147
  "review_level": "fast",
144
148
  "review_verdict": "pass",
145
149
  "review_tokens": 800,
@@ -7,7 +7,7 @@
7
7
  "finished_at": "2026-02-17T11:02:00.000Z",
8
8
  "branch": "perf/core-web-vitals",
9
9
  "total_tokens": 37200,
10
- "total_cost_usd": 3.72
10
+ "total_cost_usd": 0.2976
11
11
  },
12
12
  "taskSummary": {
13
13
  "total": 5,
@@ -42,28 +42,28 @@
42
42
  "name": "reports/bundle-analysis.json",
43
43
  "type": "json",
44
44
  "task_id": "perf-t1",
45
- "created_at": "2026-03-12T22:26:01.388Z"
45
+ "created_at": "2026-03-18T01:18:30.529Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-perf-opt-reports-web-vitals-improvement-md",
49
49
  "name": "reports/web-vitals-improvement.md",
50
50
  "type": "summary",
51
51
  "task_id": "perf-t4",
52
- "created_at": "2026-03-12T22:26:01.388Z"
52
+ "created_at": "2026-03-18T01:18:30.529Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-perf-opt-src-charts-index-ts",
56
56
  "name": "src/charts/index.ts",
57
57
  "type": "file",
58
58
  "task_id": "perf-t2",
59
- "created_at": "2026-03-12T22:26:01.388Z"
59
+ "created_at": "2026-03-18T01:18:30.529Z"
60
60
  },
61
61
  {
62
62
  "id": "artifact-demo-perf-opt-src-utils-image-loader-ts",
63
63
  "name": "src/utils/image-loader.ts",
64
64
  "type": "file",
65
65
  "task_id": "perf-t3",
66
- "created_at": "2026-03-12T22:26:01.388Z"
66
+ "created_at": "2026-03-18T01:18:30.529Z"
67
67
  }
68
68
  ],
69
69
  "has_more_events": false,
@@ -77,7 +77,9 @@
77
77
  {
78
78
  "type": "task_started",
79
79
  "task_id": "perf-t4",
80
- "data": {"mechanism": "sub-agent"},
80
+ "data": {
81
+ "mechanism": "sub-agent"
82
+ },
81
83
  "created_at": "2026-02-17T10:31:00.000Z"
82
84
  },
83
85
  {
@@ -89,7 +91,9 @@
89
91
  {
90
92
  "type": "task_started",
91
93
  "task_id": "perf-t3",
92
- "data": {"mechanism": "background"},
94
+ "data": {
95
+ "mechanism": "background"
96
+ },
93
97
  "created_at": "2026-02-17T10:14:00.000Z"
94
98
  },
95
99
  {
@@ -101,7 +105,9 @@
101
105
  {
102
106
  "type": "task_started",
103
107
  "task_id": "perf-t2",
104
- "data": {"mechanism": "background"},
108
+ "data": {
109
+ "mechanism": "background"
110
+ },
105
111
  "created_at": "2026-02-17T10:14:00.000Z"
106
112
  },
107
113
  {
@@ -113,7 +119,9 @@
113
119
  {
114
120
  "type": "task_started",
115
121
  "task_id": "perf-t1",
116
- "data": {"mechanism": "sub-agent"},
122
+ "data": {
123
+ "mechanism": "sub-agent"
124
+ },
117
125
  "created_at": "2026-02-17T10:00:05.000Z"
118
126
  }
119
127
  ],
@@ -128,7 +136,7 @@
128
136
  "started_at": "2026-02-17T10:00:05.000Z",
129
137
  "finished_at": "2026-02-17T10:13:00.000Z",
130
138
  "total_tokens": 8900,
131
- "cost_usd": 0.89,
139
+ "cost_usd": 0.048060000000000005,
132
140
  "review_level": null,
133
141
  "review_verdict": null,
134
142
  "review_tokens": null,
@@ -149,7 +157,7 @@
149
157
  "started_at": "2026-02-17T10:14:00.000Z",
150
158
  "finished_at": "2026-02-17T10:30:00.000Z",
151
159
  "total_tokens": 11200,
152
- "cost_usd": 1.12,
160
+ "cost_usd": 0.06048,
153
161
  "review_level": null,
154
162
  "review_verdict": null,
155
163
  "review_tokens": null,
@@ -170,7 +178,7 @@
170
178
  "started_at": "2026-02-17T10:14:00.000Z",
171
179
  "finished_at": "2026-02-17T10:27:00.000Z",
172
180
  "total_tokens": 9600,
173
- "cost_usd": 0.96,
181
+ "cost_usd": 0.05184,
174
182
  "review_level": null,
175
183
  "review_verdict": null,
176
184
  "review_tokens": null,
@@ -191,7 +199,7 @@
191
199
  "started_at": "2026-02-17T10:31:00.000Z",
192
200
  "finished_at": "2026-02-17T10:44:00.000Z",
193
201
  "total_tokens": 7500,
194
- "cost_usd": 0.75,
202
+ "cost_usd": 0.0405,
195
203
  "review_level": null,
196
204
  "review_verdict": null,
197
205
  "review_tokens": null,
@@ -212,7 +220,7 @@
212
220
  "started_at": "2026-02-17T10:45:00.000Z",
213
221
  "finished_at": "2026-02-17T10:52:00.000Z",
214
222
  "total_tokens": 1200,
215
- "cost_usd": 0.12,
223
+ "cost_usd": 0.001728,
216
224
  "review_level": "fast",
217
225
  "review_verdict": "pass",
218
226
  "review_tokens": 1200,
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "tokenCostTotals": {
15
15
  "total_tokens": 226750,
16
- "total_cost_usd": 22.67
16
+ "total_cost_usd": 2.8241
17
17
  },
18
18
  "topAgents": [
19
19
  {
@@ -75,5 +75,39 @@
75
75
  "count": 1
76
76
  }
77
77
  ]
78
- }
78
+ },
79
+ "taskTotals": {
80
+ "totalTasks": 30,
81
+ "totalRetries": 5
82
+ },
83
+ "activityTimeline": [
84
+ {
85
+ "date": "2026-02-03",
86
+ "count": 1
87
+ },
88
+ {
89
+ "date": "2026-02-07",
90
+ "count": 1
91
+ },
92
+ {
93
+ "date": "2026-02-12",
94
+ "count": 1
95
+ },
96
+ {
97
+ "date": "2026-02-17",
98
+ "count": 1
99
+ },
100
+ {
101
+ "date": "2026-02-22",
102
+ "count": 1
103
+ },
104
+ {
105
+ "date": "2026-02-28",
106
+ "count": 1
107
+ },
108
+ {
109
+ "date": "2026-03-11",
110
+ "count": 1
111
+ }
112
+ ]
79
113
  }
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
1
+ import { existsSync, mkdirSync, writeFileSync, copyFileSync } from 'node:fs'
2
2
  import { resolve, dirname } from 'node:path'
3
3
  import { fileURLToPath } from 'node:url'
4
4
 
@@ -128,13 +128,14 @@ export async function runEtl(options: EtlOptions): Promise<EtlResult> {
128
128
  }
129
129
  }
130
130
 
131
- function parseArgs(): { db?: string; out?: string } {
131
+ function parseArgs(): { db?: string; out?: string; events?: string } {
132
132
  const args = process.argv.slice(2)
133
133
  const result: Record<string, string> = {}
134
134
  for (let i = 0; i < args.length; i++) {
135
135
  const a = args[i]
136
136
  if (a === '--db' && args[i+1]) { result.db = args[++i] }
137
137
  else if (a === '--out' && args[i+1]) { result.out = args[++i] }
138
+ else if (a === '--events' && args[i+1]) { result.events = args[++i] }
138
139
  }
139
140
  return result
140
141
  }
@@ -147,7 +148,18 @@ if (isMain) {
147
148
  const parsed = parseArgs()
148
149
  const dbPath = parsed.db != null ? resolve(process.cwd(), parsed.db) : resolve(process.cwd(), '.opencastle', 'convoy.db')
149
150
  const outputDir = parsed.out != null ? resolve(process.cwd(), parsed.out) : resolve(__dirname, '..', 'public', 'data')
150
- runEtl({ dbPath, outputDir }).catch((err: unknown) => {
151
+ runEtl({ dbPath, outputDir }).then(() => {
152
+ if (parsed.events) {
153
+ const eventsPath = resolve(process.cwd(), parsed.events)
154
+ const dest = resolve(outputDir, 'events.ndjson')
155
+ if (existsSync(eventsPath)) {
156
+ copyFileSync(eventsPath, dest)
157
+ console.log(`Events copied: ${eventsPath} → ${dest}`)
158
+ } else {
159
+ console.warn(`⚠ Events file not found: ${eventsPath}`)
160
+ }
161
+ }
162
+ }).catch((err: unknown) => {
151
163
  console.error('ETL failed:', (err as Error).message)
152
164
  process.exit(1)
153
165
  })
@@ -2,6 +2,7 @@ import { resolve, dirname } from 'node:path'
2
2
  import { mkdirSync, writeFileSync } from 'node:fs'
3
3
  import { fileURLToPath } from 'node:url'
4
4
  import { createConvoyStore } from '../../cli/convoy/store.js'
5
+ import { calculateCost } from '../../cli/convoy/pricing.js'
5
6
 
6
7
  // ---------------------------------------------------------------------------
7
8
  // Helpers
@@ -19,6 +20,13 @@ function getMechanism(phase: number, agent: string): string {
19
20
  return 'background'
20
21
  }
21
22
 
23
+ /** Estimate cost using canonical pricing. Demo data only has total tokens, so assume 80/20 input:output split. */
24
+ function calcCost(tokens: number, model: string): number {
25
+ const input = Math.round(tokens * 0.8)
26
+ const output = tokens - input
27
+ return calculateCost(model, input, output) ?? 0
28
+ }
29
+
22
30
  // ---------------------------------------------------------------------------
23
31
  // Demo timestamps – spread over 40 days (2026-02-01 → 2026-03-12)
24
32
  // ---------------------------------------------------------------------------
@@ -48,13 +56,13 @@ export async function createDemoDb(outPath: string, eventsOutPath?: string): Pro
48
56
  // ── Convoy 1: Auth Revamp – DONE ─────────────────────────────────────
49
57
  const C1 = dayTs(2, 9)
50
58
  store.insertConvoy({ id: 'demo-auth-revamp', name: 'Auth System Revamp', spec_hash: 'h1', status: 'done', branch: 'feat/auth-v2', created_at: C1, spec_yaml: 'name: auth-revamp', pipeline_id: 'demo-pipeline-1' })
51
- store.updateConvoyStatus('demo-auth-revamp', 'done', { started_at: C1, finished_at: iso(C1, min(47)), total_tokens: 42850, total_cost_usd: 4.28 })
59
+ store.updateConvoyStatus('demo-auth-revamp', 'done', { started_at: C1, finished_at: iso(C1, min(47)), total_tokens: 42850, total_cost_usd: 0.5696 })
52
60
  const authTasks = [
53
- { id: 'auth-t1', phase: 1, prompt: 'Design OAuth2 token refresh architecture', agent: 'Architect', status: 'done' as const, retries: 0, tokens: 8400, cost: 0.84, start: iso(C1, sec(5)), end: iso(C1, min(9)) },
54
- { id: 'auth-t2', phase: 2, prompt: 'Implement JWT middleware with refresh rotation', agent: 'Developer', status: 'done' as const, retries: 1, tokens: 12600, cost: 1.26, start: iso(C1, min(10)), end: iso(C1, min(24)) },
55
- { id: 'auth-t3', phase: 2, prompt: 'Add RLS policies for session tokens', agent: 'Security Expert', status: 'done' as const, retries: 0, tokens: 9200, cost: 0.92, start: iso(C1, min(10)), end: iso(C1, min(20)) },
56
- { id: 'auth-t4', phase: 3, prompt: 'Write auth integration tests', agent: 'Testing Expert', status: 'done' as const, retries: 0, tokens: 8900, cost: 0.89, start: iso(C1, min(25)), end: iso(C1, min(37)) },
57
- { id: 'auth-t5', phase: 4, prompt: 'QA gate – security review', agent: 'Reviewer', status: 'done' as const, retries: 0, tokens: 3750, cost: 0.37, start: iso(C1, min(38)), end: iso(C1, min(46)) },
61
+ { id: 'auth-t1', phase: 1, prompt: 'Design OAuth2 token refresh architecture', agent: 'Architect', status: 'done' as const, retries: 0, tokens: 8400, cost: calcCost(8400, 'claude-opus-4-6'), start: iso(C1, sec(5)), end: iso(C1, min(9)) },
62
+ { id: 'auth-t2', phase: 2, prompt: 'Implement JWT middleware with refresh rotation', agent: 'Developer', status: 'done' as const, retries: 1, tokens: 12600, cost: calcCost(12600, 'claude-sonnet-4-6'), start: iso(C1, min(10)), end: iso(C1, min(24)) },
63
+ { id: 'auth-t3', phase: 2, prompt: 'Add RLS policies for session tokens', agent: 'Security Expert', status: 'done' as const, retries: 0, tokens: 9200, cost: calcCost(9200, 'claude-sonnet-4-6'), start: iso(C1, min(10)), end: iso(C1, min(20)) },
64
+ { id: 'auth-t4', phase: 3, prompt: 'Write auth integration tests', agent: 'Testing Expert', status: 'done' as const, retries: 0, tokens: 8900, cost: calcCost(8900, 'claude-sonnet-4-6'), start: iso(C1, min(25)), end: iso(C1, min(37)) },
65
+ { id: 'auth-t5', phase: 4, prompt: 'QA gate – security review', agent: 'Reviewer', status: 'done' as const, retries: 0, tokens: 3750, cost: calcCost(3750, 'claude-sonnet-4-6'), start: iso(C1, min(38)), end: iso(C1, min(46)) },
58
66
  ]
59
67
  for (const t of authTasks) {
60
68
  store.insertTask({ id: t.id, convoy_id: 'demo-auth-revamp', phase: t.phase, prompt: t.prompt, agent: t.agent, adapter: 'vscode', model: t.agent === 'Architect' ? 'claude-opus-4-6' : 'claude-sonnet-4-6', timeout_ms: 120000, status: t.status, retries: t.retries, max_retries: 3, files: null, depends_on: null, gates: null, outputs: JSON.stringify({ result: 'done' }), inputs: null })
@@ -66,15 +74,15 @@ export async function createDemoDb(outPath: string, eventsOutPath?: string): Pro
66
74
  // ── Convoy 2: Dashboard UI – DONE ────────────────────────────────────
67
75
  const C2 = dayTs(6, 14)
68
76
  store.insertConvoy({ id: 'demo-dashboard-ui', name: 'Observability Dashboard UI', spec_hash: 'h2', status: 'done', branch: 'feat/dashboard-v2', created_at: C2, spec_yaml: 'name: dashboard-ui', pipeline_id: 'demo-pipeline-1' })
69
- store.updateConvoyStatus('demo-dashboard-ui', 'done', { started_at: C2, finished_at: iso(C2, min(98)), total_tokens: 78400, total_cost_usd: 7.84 })
77
+ store.updateConvoyStatus('demo-dashboard-ui', 'done', { started_at: C2, finished_at: iso(C2, min(98)), total_tokens: 78400, total_cost_usd: 1.4993 })
70
78
  const uiTasks = [
71
- { id: 'ui-t1', phase: 1, prompt: 'Design dark-theme component system', agent: 'UI/UX Expert', status: 'done' as const, retries: 0, tokens: 14200, cost: 1.42, start: iso(C2, sec(5)), end: iso(C2, min(19)) },
72
- { id: 'ui-t2', phase: 1, prompt: 'Implement KPI card components', agent: 'Developer', status: 'done' as const, retries: 0, tokens: 11800, cost: 1.18, start: iso(C2, sec(5)), end: iso(C2, min(16)) },
73
- { id: 'ui-t3', phase: 2, prompt: 'Build SVG donut charts and bar charts', agent: 'Developer', status: 'done' as const, retries: 1, tokens: 13500, cost: 1.35, start: iso(C2, min(20)), end: iso(C2, min(44)) },
74
- { id: 'ui-t4', phase: 2, prompt: 'Write dashboard CSS animations', agent: 'UI/UX Expert', status: 'done' as const, retries: 0, tokens: 9400, cost: 0.94, start: iso(C2, min(20)), end: iso(C2, min(38)) },
75
- { id: 'ui-t5', phase: 3, prompt: 'Accessibility audit and ARIA labels', agent: 'UI/UX Expert', status: 'done' as const, retries: 0, tokens: 8700, cost: 0.87, start: iso(C2, min(45)), end: iso(C2, min(58)) },
76
- { id: 'ui-t6', phase: 3, prompt: 'Cross-browser visual regression tests', agent: 'Testing Expert', status: 'done' as const, retries: 0, tokens: 11200, cost: 1.12, start: iso(C2, min(45)), end: iso(C2, min(62)) },
77
- { id: 'ui-t7', phase: 4, prompt: 'QA panel – design review', agent: 'Reviewer', status: 'done' as const, retries: 0, tokens: 9600, cost: 0.96, start: iso(C2, min(63)), end: iso(C2, min(97)) },
79
+ { id: 'ui-t1', phase: 1, prompt: 'Design dark-theme component system', agent: 'UI/UX Expert', status: 'done' as const, retries: 0, tokens: 14200, cost: calcCost(14200, 'claude-opus-4-6'), start: iso(C2, sec(5)), end: iso(C2, min(19)) },
80
+ { id: 'ui-t2', phase: 1, prompt: 'Implement KPI card components', agent: 'Developer', status: 'done' as const, retries: 0, tokens: 11800, cost: calcCost(11800, 'claude-sonnet-4-6'), start: iso(C2, sec(5)), end: iso(C2, min(16)) },
81
+ { id: 'ui-t3', phase: 2, prompt: 'Build SVG donut charts and bar charts', agent: 'Developer', status: 'done' as const, retries: 1, tokens: 13500, cost: calcCost(13500, 'claude-sonnet-4-6'), start: iso(C2, min(20)), end: iso(C2, min(44)) },
82
+ { id: 'ui-t4', phase: 2, prompt: 'Write dashboard CSS animations', agent: 'UI/UX Expert', status: 'done' as const, retries: 0, tokens: 9400, cost: calcCost(9400, 'claude-opus-4-6'), start: iso(C2, min(20)), end: iso(C2, min(38)) },
83
+ { id: 'ui-t5', phase: 3, prompt: 'Accessibility audit and ARIA labels', agent: 'UI/UX Expert', status: 'done' as const, retries: 0, tokens: 8700, cost: calcCost(8700, 'claude-opus-4-6'), start: iso(C2, min(45)), end: iso(C2, min(58)) },
84
+ { id: 'ui-t6', phase: 3, prompt: 'Cross-browser visual regression tests', agent: 'Testing Expert', status: 'done' as const, retries: 0, tokens: 11200, cost: calcCost(11200, 'claude-sonnet-4-6'), start: iso(C2, min(45)), end: iso(C2, min(62)) },
85
+ { id: 'ui-t7', phase: 4, prompt: 'QA panel – design review', agent: 'Reviewer', status: 'done' as const, retries: 0, tokens: 9600, cost: calcCost(9600, 'claude-sonnet-4-6'), start: iso(C2, min(63)), end: iso(C2, min(97)) },
78
86
  ]
79
87
  for (const t of uiTasks) {
80
88
  store.insertTask({ id: t.id, convoy_id: 'demo-dashboard-ui', phase: t.phase, prompt: t.prompt, agent: t.agent, adapter: 'vscode', model: t.agent === 'UI/UX Expert' ? 'claude-opus-4-6' : 'claude-sonnet-4-6', timeout_ms: 120000, status: t.status, retries: t.retries, max_retries: 3, files: null, depends_on: null, gates: null, outputs: JSON.stringify({ result: 'done' }), inputs: null })
@@ -86,11 +94,11 @@ export async function createDemoDb(outPath: string, eventsOutPath?: string): Pro
86
94
  // ── Convoy 3: API v2 – GATE_FAILED ──────────────────────────────────
87
95
  const C3 = dayTs(11, 16)
88
96
  store.insertConvoy({ id: 'demo-api-v2', name: 'REST API v2 Migration', spec_hash: 'h3', status: 'gate_failed', branch: 'feat/api-v2', created_at: C3, spec_yaml: 'name: api-v2' })
89
- store.updateConvoyStatus('demo-api-v2', 'gate_failed', { started_at: C3, finished_at: iso(C3, min(28)), total_tokens: 24600, total_cost_usd: 2.46 })
97
+ store.updateConvoyStatus('demo-api-v2', 'gate_failed', { started_at: C3, finished_at: iso(C3, min(28)), total_tokens: 24600, total_cost_usd: 0.1968 })
90
98
  const apiTasks = [
91
- { id: 'api-t1', phase: 1, prompt: 'Design RESTful v2 route contracts', agent: 'API Designer', status: 'done' as const, eventType: 'task_done', retries: 0, tokens: 7200, cost: 0.72, start: iso(C3, sec(5)), end: iso(C3, min(11)) },
92
- { id: 'api-t2', phase: 2, prompt: 'Implement rate limiting middleware', agent: 'Developer', status: 'done' as const, eventType: 'task_done', retries: 2, tokens: 11400, cost: 1.14, start: iso(C3, min(12)), end: iso(C3, min(23)) },
93
- { id: 'api-t3', phase: 3, prompt: 'Security gate – injection vulnerability scan', agent: 'Security Expert', status: 'gate_failed' as const, eventType: 'task_gate_failed', retries: 0, tokens: 6000, cost: 0.60, start: iso(C3, min(24)), end: iso(C3, min(27)) },
99
+ { id: 'api-t1', phase: 1, prompt: 'Design RESTful v2 route contracts', agent: 'API Designer', status: 'done' as const, eventType: 'task_done', retries: 0, tokens: 7200, cost: calcCost(7200, 'claude-sonnet-4-6'), start: iso(C3, sec(5)), end: iso(C3, min(11)) },
100
+ { id: 'api-t2', phase: 2, prompt: 'Implement rate limiting middleware', agent: 'Developer', status: 'done' as const, eventType: 'task_done', retries: 2, tokens: 11400, cost: calcCost(11400, 'claude-sonnet-4-6'), start: iso(C3, min(12)), end: iso(C3, min(23)) },
101
+ { id: 'api-t3', phase: 3, prompt: 'Security gate – injection vulnerability scan', agent: 'Security Expert', status: 'gate_failed' as const, eventType: 'task_gate_failed', retries: 0, tokens: 6000, cost: calcCost(6000, 'claude-sonnet-4-6'), start: iso(C3, min(24)), end: iso(C3, min(27)) },
94
102
  ]
95
103
  for (const t of apiTasks) {
96
104
  store.insertTask({ id: t.id, convoy_id: 'demo-api-v2', phase: t.phase, prompt: t.prompt, agent: t.agent, adapter: 'vscode', model: 'claude-sonnet-4-6', timeout_ms: 120000, status: t.status, retries: t.retries, max_retries: 3, files: null, depends_on: null, gates: null, outputs: t.status === 'gate_failed' ? JSON.stringify({ gate_failure: 'SQL injection risk detected in query builder' }) : JSON.stringify({ result: 'done' }), inputs: null })
@@ -102,12 +110,12 @@ export async function createDemoDb(outPath: string, eventsOutPath?: string): Pro
102
110
  // ── Convoy 4: Performance Optimization – DONE ────────────────────────
103
111
  const C4 = dayTs(16, 10)
104
112
  store.insertConvoy({ id: 'demo-perf-opt', name: 'Frontend Performance Boost', spec_hash: 'h4', status: 'done', branch: 'perf/core-web-vitals', created_at: C4, spec_yaml: 'name: perf-opt' })
105
- store.updateConvoyStatus('demo-perf-opt', 'done', { started_at: C4, finished_at: iso(C4, min(62)), total_tokens: 37200, total_cost_usd: 3.72 })
113
+ store.updateConvoyStatus('demo-perf-opt', 'done', { started_at: C4, finished_at: iso(C4, min(62)), total_tokens: 37200, total_cost_usd: 0.2976 })
106
114
  const perfTasks = [
107
- { id: 'perf-t1', phase: 1, prompt: 'Profile bundle and identify bottlenecks', agent: 'Performance Expert', status: 'done' as const, retries: 0, tokens: 8900, cost: 0.89, start: iso(C4, sec(5)), end: iso(C4, min(13)) },
108
- { id: 'perf-t2', phase: 2, prompt: 'Code-split heavy chart library', agent: 'Developer', status: 'done' as const, retries: 0, tokens: 11200, cost: 1.12, start: iso(C4, min(14)), end: iso(C4, min(30)) },
109
- { id: 'perf-t3', phase: 2, prompt: 'Implement image lazy-loading and AVIF conversion', agent: 'Developer', status: 'done' as const, retries: 0, tokens: 9600, cost: 0.96, start: iso(C4, min(14)), end: iso(C4, min(27)) },
110
- { id: 'perf-t4', phase: 3, prompt: 'Validate Core Web Vitals improvements', agent: 'Performance Expert', status: 'done' as const, retries: 0, tokens: 7500, cost: 0.75, start: iso(C4, min(31)), end: iso(C4, min(44)) },
115
+ { id: 'perf-t1', phase: 1, prompt: 'Profile bundle and identify bottlenecks', agent: 'Performance Expert', status: 'done' as const, retries: 0, tokens: 8900, cost: calcCost(8900, 'claude-sonnet-4-6'), start: iso(C4, sec(5)), end: iso(C4, min(13)) },
116
+ { id: 'perf-t2', phase: 2, prompt: 'Code-split heavy chart library', agent: 'Developer', status: 'done' as const, retries: 0, tokens: 11200, cost: calcCost(11200, 'claude-sonnet-4-6'), start: iso(C4, min(14)), end: iso(C4, min(30)) },
117
+ { id: 'perf-t3', phase: 2, prompt: 'Implement image lazy-loading and AVIF conversion', agent: 'Developer', status: 'done' as const, retries: 0, tokens: 9600, cost: calcCost(9600, 'claude-sonnet-4-6'), start: iso(C4, min(14)), end: iso(C4, min(27)) },
118
+ { id: 'perf-t4', phase: 3, prompt: 'Validate Core Web Vitals improvements', agent: 'Performance Expert', status: 'done' as const, retries: 0, tokens: 7500, cost: calcCost(7500, 'claude-sonnet-4-6'), start: iso(C4, min(31)), end: iso(C4, min(44)) },
111
119
  ]
112
120
  for (const t of perfTasks) {
113
121
  store.insertTask({ id: t.id, convoy_id: 'demo-perf-opt', phase: t.phase, prompt: t.prompt, agent: t.agent, adapter: 'vscode', model: 'claude-sonnet-4-6', timeout_ms: 120000, status: t.status, retries: t.retries, max_retries: 3, files: null, depends_on: null, gates: null, outputs: JSON.stringify({ result: 'done' }), inputs: null })
@@ -119,11 +127,11 @@ export async function createDemoDb(outPath: string, eventsOutPath?: string): Pro
119
127
  // ── Convoy 5: Data Pipeline – DONE ────────────────────────────────────
120
128
  const C5 = dayTs(21, 13)
121
129
  store.insertConvoy({ id: 'demo-data-pipeline', name: 'Analytics ETL Pipeline', spec_hash: 'h5', status: 'done', branch: 'feat/etl-v2', created_at: C5, spec_yaml: 'name: data-pipeline' })
122
- store.updateConvoyStatus('demo-data-pipeline', 'done', { started_at: C5, finished_at: iso(C5, min(38)), total_tokens: 28900, total_cost_usd: 2.89 })
130
+ store.updateConvoyStatus('demo-data-pipeline', 'done', { started_at: C5, finished_at: iso(C5, min(38)), total_tokens: 28900, total_cost_usd: 0.2312 })
123
131
  const etlTasks = [
124
- { id: 'etl-t1', phase: 1, prompt: 'Design ndjson processing schema', agent: 'Data Expert', status: 'done' as const, retries: 0, tokens: 7800, cost: 0.78, start: iso(C5, sec(5)), end: iso(C5, min(11)) },
125
- { id: 'etl-t2', phase: 2, prompt: 'Implement incremental ETL with deduplication', agent: 'Data Expert', status: 'done' as const, retries: 1, tokens: 12400, cost: 1.24, start: iso(C5, min(12)), end: iso(C5, min(30)) },
126
- { id: 'etl-t3', phase: 3, prompt: 'Write ETL test suite', agent: 'Testing Expert', status: 'done' as const, retries: 0, tokens: 8700, cost: 0.87, start: iso(C5, min(31)), end: iso(C5, min(37)) },
132
+ { id: 'etl-t1', phase: 1, prompt: 'Design ndjson processing schema', agent: 'Data Expert', status: 'done' as const, retries: 0, tokens: 7800, cost: calcCost(7800, 'claude-sonnet-4-6'), start: iso(C5, sec(5)), end: iso(C5, min(11)) },
133
+ { id: 'etl-t2', phase: 2, prompt: 'Implement incremental ETL with deduplication', agent: 'Data Expert', status: 'done' as const, retries: 1, tokens: 12400, cost: calcCost(12400, 'claude-sonnet-4-6'), start: iso(C5, min(12)), end: iso(C5, min(30)) },
134
+ { id: 'etl-t3', phase: 3, prompt: 'Write ETL test suite', agent: 'Testing Expert', status: 'done' as const, retries: 0, tokens: 8700, cost: calcCost(8700, 'claude-sonnet-4-6'), start: iso(C5, min(31)), end: iso(C5, min(37)) },
127
135
  ]
128
136
  for (const t of etlTasks) {
129
137
  store.insertTask({ id: t.id, convoy_id: 'demo-data-pipeline', phase: t.phase, prompt: t.prompt, agent: t.agent, adapter: 'vscode', model: 'claude-sonnet-4-6', timeout_ms: 120000, status: t.status, retries: t.retries, max_retries: 3, files: null, depends_on: null, gates: null, outputs: JSON.stringify({ result: 'done' }), inputs: null })
@@ -137,7 +145,7 @@ export async function createDemoDb(outPath: string, eventsOutPath?: string): Pro
137
145
  store.insertConvoy({ id: 'demo-deploy-ci', name: 'CI/CD Pipeline Setup', spec_hash: 'h6', status: 'running', branch: 'feat/ci-cd', created_at: C6, spec_yaml: 'name: deploy-ci' })
138
146
  store.updateConvoyStatus('demo-deploy-ci', 'running', { started_at: C6 })
139
147
  const ciTasks = [
140
- { id: 'ci-t1', phase: 1, prompt: 'Design GitHub Actions workflow matrix', agent: 'DevOps Expert', status: 'done' as const, running: false, retries: 0, tokens: 6400, cost: 0.64, start: iso(C6, sec(5)), end: iso(C6, min(14)) },
148
+ { id: 'ci-t1', phase: 1, prompt: 'Design GitHub Actions workflow matrix', agent: 'DevOps Expert', status: 'done' as const, running: false, retries: 0, tokens: 6400, cost: calcCost(6400, 'claude-sonnet-4-6'), start: iso(C6, sec(5)), end: iso(C6, min(14)) },
141
149
  { id: 'ci-t2', phase: 2, prompt: 'Configure nx affected build caching', agent: 'DevOps Expert', status: 'running' as const, running: true, retries: 0, tokens: 0, cost: 0, start: iso(C6, min(15)), end: '' },
142
150
  { id: 'ci-t3', phase: 2, prompt: 'Set up staging environment deployment', agent: 'DevOps Expert', status: 'pending' as const, running: false, retries: 0, tokens: 0, cost: 0, start: '', end: '' },
143
151
  ]
@@ -156,10 +164,10 @@ export async function createDemoDb(outPath: string, eventsOutPath?: string): Pro
156
164
  // ── Convoy 7: Docs Update – DONE ────────────────────────────────────
157
165
  const C7 = dayTs(27, 15)
158
166
  store.insertConvoy({ id: 'demo-docs-update', name: 'Documentation Refresh', spec_hash: 'h7', status: 'done', branch: 'docs/update-march', created_at: C7, spec_yaml: 'name: docs-update' })
159
- store.updateConvoyStatus('demo-docs-update', 'done', { started_at: C7, finished_at: iso(C7, min(22)), total_tokens: 14800, total_cost_usd: 1.48 })
167
+ store.updateConvoyStatus('demo-docs-update', 'done', { started_at: C7, finished_at: iso(C7, min(22)), total_tokens: 14800, total_cost_usd: 0.0296 })
160
168
  const docTasks = [
161
- { id: 'docs-t1', phase: 1, prompt: 'Update README and ARCHITECTURE docs', agent: 'Documentation Writer', status: 'done' as const, retries: 0, tokens: 8200, cost: 0.82, start: iso(C7, sec(5)), end: iso(C7, min(14)) },
162
- { id: 'docs-t2', phase: 2, prompt: 'Generate API reference from source', agent: 'Documentation Writer', status: 'done' as const, retries: 0, tokens: 6600, cost: 0.66, start: iso(C7, min(15)), end: iso(C7, min(21)) },
169
+ { id: 'docs-t1', phase: 1, prompt: 'Update README and ARCHITECTURE docs', agent: 'Documentation Writer', status: 'done' as const, retries: 0, tokens: 8200, cost: calcCost(8200, 'claude-haiku-3-5'), start: iso(C7, sec(5)), end: iso(C7, min(14)) },
170
+ { id: 'docs-t2', phase: 2, prompt: 'Generate API reference from source', agent: 'Documentation Writer', status: 'done' as const, retries: 0, tokens: 6600, cost: calcCost(6600, 'claude-haiku-3-5'), start: iso(C7, min(15)), end: iso(C7, min(21)) },
163
171
  ]
164
172
  for (const t of docTasks) {
165
173
  store.insertTask({ id: t.id, convoy_id: 'demo-docs-update', phase: t.phase, prompt: t.prompt, agent: t.agent, adapter: 'vscode', model: 'claude-haiku-3-5', timeout_ms: 120000, status: t.status, retries: t.retries, max_retries: 3, files: null, depends_on: null, gates: null, outputs: JSON.stringify({ result: 'done' }), inputs: null })
@@ -186,21 +194,21 @@ export async function createDemoDb(outPath: string, eventsOutPath?: string): Pro
186
194
  })
187
195
  // Perf Opt: add reviewer task + fast review pass
188
196
  store.insertTask({ id: 'perf-t5', convoy_id: 'demo-perf-opt', phase: 4, prompt: 'Fast review – performance changes', agent: 'Reviewer', adapter: 'vscode', model: 'claude-haiku-3-5', timeout_ms: 60000, status: 'done', retries: 0, max_retries: 3, files: null, depends_on: null, gates: null })
189
- store.updateTaskStatus('perf-t5', 'demo-perf-opt', 'done', { started_at: iso(C4, min(45)), finished_at: iso(C4, min(52)), total_tokens: 1200, cost_usd: 0.12 })
197
+ store.updateTaskStatus('perf-t5', 'demo-perf-opt', 'done', { started_at: iso(C4, min(45)), finished_at: iso(C4, min(52)), total_tokens: 1200, cost_usd: calcCost(1200, 'claude-haiku-3-5') })
190
198
  store.updateTaskReview('perf-t5', 'demo-perf-opt', {
191
199
  review_level: 'fast', review_verdict: 'pass',
192
200
  review_tokens: 1200, review_model: 'claude-haiku-3-5', panel_attempts: 0,
193
201
  })
194
202
  // Data Pipeline: add reviewer task + fast review pass
195
203
  store.insertTask({ id: 'etl-t4', convoy_id: 'demo-data-pipeline', phase: 4, prompt: 'Fast review – ETL pipeline', agent: 'Reviewer', adapter: 'vscode', model: 'claude-haiku-3-5', timeout_ms: 60000, status: 'done', retries: 0, max_retries: 3, files: null, depends_on: null, gates: null })
196
- store.updateTaskStatus('etl-t4', 'demo-data-pipeline', 'done', { started_at: iso(C5, min(32)), finished_at: iso(C5, min(37)), total_tokens: 900, cost_usd: 0.09 })
204
+ store.updateTaskStatus('etl-t4', 'demo-data-pipeline', 'done', { started_at: iso(C5, min(32)), finished_at: iso(C5, min(37)), total_tokens: 900, cost_usd: calcCost(900, 'claude-haiku-3-5') })
197
205
  store.updateTaskReview('etl-t4', 'demo-data-pipeline', {
198
206
  review_level: 'fast', review_verdict: 'pass',
199
207
  review_tokens: 900, review_model: 'claude-haiku-3-5', panel_attempts: 0,
200
208
  })
201
209
  // Docs Update: add reviewer task + fast review pass
202
210
  store.insertTask({ id: 'docs-t3', convoy_id: 'demo-docs-update', phase: 3, prompt: 'Fast review – documentation changes', agent: 'Reviewer', adapter: 'vscode', model: 'claude-haiku-3-5', timeout_ms: 60000, status: 'done', retries: 0, max_retries: 3, files: null, depends_on: null, gates: null })
203
- store.updateTaskStatus('docs-t3', 'demo-docs-update', 'done', { started_at: iso(C7, min(17)), finished_at: iso(C7, min(21)), total_tokens: 800, cost_usd: 0.08 })
211
+ store.updateTaskStatus('docs-t3', 'demo-docs-update', 'done', { started_at: iso(C7, min(17)), finished_at: iso(C7, min(21)), total_tokens: 800, cost_usd: calcCost(800, 'claude-haiku-3-5') })
204
212
  store.updateTaskReview('docs-t3', 'demo-docs-update', {
205
213
  review_level: 'fast', review_verdict: 'pass',
206
214
  review_tokens: 800, review_model: 'claude-haiku-3-5', panel_attempts: 0,