opencastle 0.33.7 → 0.33.9

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 (70) hide show
  1. package/dist/cli/baselines.d.ts.map +1 -1
  2. package/dist/cli/baselines.js +12 -0
  3. package/dist/cli/baselines.js.map +1 -1
  4. package/dist/cli/convoy/events.d.ts +10 -5
  5. package/dist/cli/convoy/events.d.ts.map +1 -1
  6. package/dist/cli/convoy/events.js.map +1 -1
  7. package/dist/cli/convoy/events.test.js +9 -7
  8. package/dist/cli/convoy/events.test.js.map +1 -1
  9. package/dist/cli/convoy/types.d.ts +25 -0
  10. package/dist/cli/convoy/types.d.ts.map +1 -1
  11. package/dist/cli/convoy/types.js +3 -0
  12. package/dist/cli/convoy/types.js.map +1 -1
  13. package/dist/cli/dashboard.d.ts.map +1 -1
  14. package/dist/cli/dashboard.js +8 -0
  15. package/dist/cli/dashboard.js.map +1 -1
  16. package/dist/cli/insights.d.ts.map +1 -1
  17. package/dist/cli/insights.js +4 -0
  18. package/dist/cli/insights.js.map +1 -1
  19. package/dist/cli/lesson.d.ts.map +1 -1
  20. package/dist/cli/lesson.js +32 -0
  21. package/dist/cli/lesson.js.map +1 -1
  22. package/dist/cli/log.d.ts.map +1 -1
  23. package/dist/cli/log.js +14 -1
  24. package/dist/cli/log.js.map +1 -1
  25. package/dist/cli/package.d.ts.map +1 -1
  26. package/dist/cli/package.js +8 -0
  27. package/dist/cli/package.js.map +1 -1
  28. package/dist/cli/pipeline.js +5 -2
  29. package/dist/cli/pipeline.js.map +1 -1
  30. package/dist/cli/plan.d.ts.map +1 -1
  31. package/dist/cli/plan.js +29 -1
  32. package/dist/cli/plan.js.map +1 -1
  33. package/dist/cli/run/adapters/copilot.d.ts.map +1 -1
  34. package/dist/cli/run/adapters/copilot.js +1 -3
  35. package/dist/cli/run/adapters/copilot.js.map +1 -1
  36. package/dist/cli/run/adapters/copilot.test.js +12 -0
  37. package/dist/cli/run/adapters/copilot.test.js.map +1 -1
  38. package/dist/cli/run.d.ts.map +1 -1
  39. package/dist/cli/run.js +29 -1
  40. package/dist/cli/run.js.map +1 -1
  41. package/package.json +1 -1
  42. package/src/cli/baselines.ts +3 -0
  43. package/src/cli/convoy/events.test.ts +10 -8
  44. package/src/cli/convoy/events.ts +7 -4
  45. package/src/cli/convoy/types.ts +6 -0
  46. package/src/cli/dashboard.ts +2 -0
  47. package/src/cli/insights.ts +1 -0
  48. package/src/cli/lesson.ts +8 -0
  49. package/src/cli/log.ts +5 -1
  50. package/src/cli/package.ts +2 -0
  51. package/src/cli/pipeline.ts +2 -2
  52. package/src/cli/plan.ts +8 -1
  53. package/src/cli/run/adapters/copilot.test.ts +12 -0
  54. package/src/cli/run/adapters/copilot.ts +1 -3
  55. package/src/cli/run.ts +8 -1
  56. package/src/dashboard/dist/data/convoys/demo-api-v2.json +3 -3
  57. package/src/dashboard/dist/data/convoys/demo-auth-revamp.json +10 -10
  58. package/src/dashboard/dist/data/convoys/demo-dashboard-ui.json +12 -12
  59. package/src/dashboard/dist/data/convoys/demo-data-pipeline.json +3 -3
  60. package/src/dashboard/dist/data/convoys/demo-deploy-ci.json +1 -1
  61. package/src/dashboard/dist/data/convoys/demo-docs-update.json +3 -3
  62. package/src/dashboard/dist/data/convoys/demo-perf-opt.json +4 -4
  63. package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
  64. package/src/dashboard/public/data/convoys/demo-api-v2.json +3 -3
  65. package/src/dashboard/public/data/convoys/demo-auth-revamp.json +10 -10
  66. package/src/dashboard/public/data/convoys/demo-dashboard-ui.json +12 -12
  67. package/src/dashboard/public/data/convoys/demo-data-pipeline.json +3 -3
  68. package/src/dashboard/public/data/convoys/demo-deploy-ci.json +1 -1
  69. package/src/dashboard/public/data/convoys/demo-docs-update.json +3 -3
  70. package/src/dashboard/public/data/convoys/demo-perf-opt.json +4 -4
@@ -2,6 +2,7 @@ import { appendFileSync, closeSync, fsyncSync, mkdirSync, openSync, readFileSync
2
2
  import { dirname, join } from 'node:path'
3
3
  import type { ConvoyStore } from './store.js'
4
4
  import { KNOWN_EVENT_TYPES } from './types.js'
5
+ import type { ConvoyEventType } from './types.js'
5
6
  import { validateEventData } from './event-schemas.js'
6
7
 
7
8
  const RESERVED_KEYS = new Set(['_event_id', 'convoy_id', 'task_id', 'worker_id', 'timestamp', 'type'])
@@ -16,11 +17,13 @@ export function ndjsonPathForConvoy(convoyId: string, basePath?: string): string
16
17
  return join(base, '.opencastle', 'logs', 'convoys', `${convoyId}.ndjson`)
17
18
  }
18
19
 
20
+ type ConvoyEmitIds = { convoy_id?: string; task_id?: string; worker_id?: string }
21
+
19
22
  export interface ConvoyEventEmitter {
20
- emit(
21
- type: string,
22
- data?: Record<string, unknown>,
23
- ids?: { convoy_id?: string; task_id?: string; worker_id?: string },
23
+ emit<T extends ConvoyEventType>(
24
+ type: T['type'],
25
+ data?: T extends { data?: infer D } ? D : never,
26
+ ids?: ConvoyEmitIds,
24
27
  ): void
25
28
  close(): void
26
29
  }
@@ -364,6 +364,9 @@ export type ConvoyEventType =
364
364
  | { type: 'tdd_check_passed'; data?: { task_id?: string; new_source_files?: number; existing_test_files?: number } }
365
365
  | { type: 'tdd_check_failed'; data?: { task_id?: string; missing_test_files?: string[]; new_source_files?: number } }
366
366
  | { type: 'tdd_check_skipped'; data?: { task_id?: string; reason?: string; agent?: string } }
367
+ | { type: 'convoy_resumed'; data?: { original_created_at?: string } }
368
+ | { type: 'artifacts_extracted'; data?: { task_id?: string; count?: number; artifacts?: Array<{ filename: string; summary?: string }> } }
369
+ | { type: 'file_partition_conflict'; data?: { conflicts?: Array<{ phase: number; taskA: string; taskB: string; overlapping: string[] }> } }
367
370
 
368
371
  /** All canonical convoy event type strings. Used for runtime validation. */
369
372
  export const KNOWN_EVENT_TYPES: Set<string> = new Set<ConvoyEventType['type']>([
@@ -414,4 +417,7 @@ export const KNOWN_EVENT_TYPES: Set<string> = new Set<ConvoyEventType['type']>([
414
417
  'tdd_check_passed',
415
418
  'tdd_check_failed',
416
419
  'tdd_check_skipped',
420
+ 'convoy_resumed',
421
+ 'artifacts_extracted',
422
+ 'file_partition_conflict',
417
423
  ])
@@ -78,6 +78,7 @@ function parseArgs(args: string[]): DashboardArgs {
78
78
  help = true
79
79
  } else if (args[i] === '--port' && args[i + 1]) {
80
80
  port = parseInt(args[i + 1], 10)
81
+ if (isNaN(port)) { console.error(' ✗ --port requires a valid number'); process.exit(1) }
81
82
  i++
82
83
  } else if (args[i] === '--no-open') {
83
84
  openBrowser = false
@@ -85,6 +86,7 @@ function parseArgs(args: string[]): DashboardArgs {
85
86
  seed = true
86
87
  } else if (args[i] === '--convoy' && args[i + 1]) {
87
88
  convoyId = args[i + 1]
89
+ if (!convoyId.trim()) { console.error(' ✗ --convoy cannot be empty'); process.exit(1) }
88
90
  i++
89
91
  }
90
92
  }
@@ -60,6 +60,7 @@ export default async function insights({ args }: CliContext): Promise<void> {
60
60
  sinceDays = parsed
61
61
  } else if (arg === '--db') {
62
62
  dbOverride = args[++i] ?? null
63
+ if (dbOverride !== null && !dbOverride.trim()) { console.error(' \u2717 --db cannot be empty'); process.exit(1) }
63
64
  }
64
65
  }
65
66
 
package/src/cli/lesson.ts CHANGED
@@ -247,34 +247,42 @@ export default async function lesson({ args }: CliContext): Promise<void> {
247
247
  case '--title':
248
248
  if (i + 1 >= args.length) { console.error(' \u2717 --title requires a value'); process.exit(1) }
249
249
  title = args[++i]
250
+ if (!title.trim()) { console.error(' \u2717 --title cannot be empty'); process.exit(1) }
250
251
  break
251
252
  case '--category':
252
253
  if (i + 1 >= args.length) { console.error(' \u2717 --category requires a value'); process.exit(1) }
253
254
  category = args[++i]
255
+ if (!category.trim()) { console.error(' \u2717 --category cannot be empty'); process.exit(1) }
254
256
  break
255
257
  case '--severity':
256
258
  if (i + 1 >= args.length) { console.error(' \u2717 --severity requires a value'); process.exit(1) }
257
259
  severity = args[++i]
260
+ if (!severity.trim()) { console.error(' \u2717 --severity cannot be empty'); process.exit(1) }
258
261
  break
259
262
  case '--problem':
260
263
  if (i + 1 >= args.length) { console.error(' \u2717 --problem requires a value'); process.exit(1) }
261
264
  problem = args[++i]
265
+ if (!problem.trim()) { console.error(' \u2717 --problem cannot be empty'); process.exit(1) }
262
266
  break
263
267
  case '--wrong':
264
268
  if (i + 1 >= args.length) { console.error(' \u2717 --wrong requires a value'); process.exit(1) }
265
269
  wrong = args[++i]
270
+ if (!wrong.trim()) { console.error(' \u2717 --wrong cannot be empty'); process.exit(1) }
266
271
  break
267
272
  case '--correct':
268
273
  if (i + 1 >= args.length) { console.error(' \u2717 --correct requires a value'); process.exit(1) }
269
274
  correct = args[++i]
275
+ if (!correct.trim()) { console.error(' \u2717 --correct cannot be empty'); process.exit(1) }
270
276
  break
271
277
  case '--why':
272
278
  if (i + 1 >= args.length) { console.error(' \u2717 --why requires a value'); process.exit(1) }
273
279
  why = args[++i]
280
+ if (!why.trim()) { console.error(' \u2717 --why cannot be empty'); process.exit(1) }
274
281
  break
275
282
  case '--customizations-dir':
276
283
  if (i + 1 >= args.length) { console.error(' \u2717 --customizations-dir requires a path'); process.exit(1) }
277
284
  customizationsDir = args[++i]
285
+ if (!customizationsDir.trim()) { console.error(' \u2717 --customizations-dir cannot be empty'); process.exit(1) }
278
286
  break
279
287
  }
280
288
  }
package/src/cli/log.ts CHANGED
@@ -99,10 +99,12 @@ export default async function log({ args }: CliContext): Promise<void> {
99
99
  case '--type':
100
100
  if (i + 1 >= args.length) { console.error(' \u2717 --type requires a value'); process.exit(1) }
101
101
  type = args[++i]
102
+ if (!type.trim()) { console.error(' \u2717 --type cannot be empty'); process.exit(1) }
102
103
  break
103
104
  case '--logs-dir':
104
105
  if (i + 1 >= args.length) { console.error(' \u2717 --logs-dir requires a path'); process.exit(1) }
105
106
  logsDir = args[++i]
107
+ if (!logsDir.trim()) { console.error(' \u2717 --logs-dir cannot be empty'); process.exit(1) }
106
108
  break
107
109
  default:
108
110
  if (arg.startsWith('--')) {
@@ -113,7 +115,9 @@ export default async function log({ args }: CliContext): Promise<void> {
113
115
  if (next === undefined || next.startsWith('--')) {
114
116
  fields[key] = true
115
117
  } else {
116
- fields[key] = coerceValue(key, args[++i])
118
+ const raw = args[++i]
119
+ if (!raw.trim()) { console.error(` \u2717 --${key} cannot be empty`); process.exit(1) }
120
+ fields[key] = coerceValue(key, raw)
117
121
  }
118
122
  }
119
123
  }
@@ -37,8 +37,10 @@ export function parseArgs(args: string[]): PackageArgs {
37
37
  opts.dryRun = true
38
38
  } else if ((arg === '--platform' || arg === '-p') && args[i + 1]) {
39
39
  opts.platform = args[++i]
40
+ if (!opts.platform.trim()) { console.error(' ✗ --platform cannot be empty'); process.exit(1) }
40
41
  } else if ((arg === '--output' || arg === '-o') && args[i + 1]) {
41
42
  opts.output = args[++i]
43
+ if (!opts.output.trim()) { console.error(' ✗ --output cannot be empty'); process.exit(1) }
42
44
  }
43
45
  }
44
46
  return opts
@@ -356,6 +356,7 @@ function parseArgs(args: string[]): PipelineOptions {
356
356
  case '-t':
357
357
  if (i + 1 >= args.length) { console.error(' ✗ --text requires a value'); process.exit(1) }
358
358
  opts.text = args[++i]
359
+ if (!opts.text.trim()) { console.error(' ✗ --text cannot be empty'); process.exit(1) }
359
360
  break
360
361
  case '--prd':
361
362
  if (i + 1 >= args.length) { console.error(' ✗ --prd requires a path'); process.exit(1) }
@@ -389,8 +390,7 @@ function parseArgs(args: string[]): PipelineOptions {
389
390
  opts.skipValidation = true
390
391
  break
391
392
  default:
392
- console.error(` ✗ Unknown option: ${arg}`)
393
- console.log(HELP)
393
+ console.error(` ✗ Unknown option: ${arg}. Run with --help to see available options.`)
394
394
  process.exit(1)
395
395
  }
396
396
  }
package/src/cli/plan.ts CHANGED
@@ -536,33 +536,40 @@ function parseArgs(args: string[]): PlanOptions {
536
536
  case '-f':
537
537
  if (i + 1 >= args.length) { console.error(' ✗ --file requires a path'); process.exit(1) }
538
538
  opts.file = args[++i]
539
+ if (!opts.file.trim()) { console.error(' ✗ --file cannot be empty'); process.exit(1) }
539
540
  break
540
541
  case '--text':
541
542
  case '-t':
542
543
  if (i + 1 >= args.length) { console.error(' ✗ --text requires a value'); process.exit(1) }
543
544
  opts.text = args[++i]
545
+ if (!opts.text.trim()) { console.error(' ✗ --text cannot be empty'); process.exit(1) }
544
546
  break
545
547
  case '--template':
546
548
  if (i + 1 >= args.length) { console.error(' ✗ --template requires a name'); process.exit(1) }
547
549
  opts.template = args[++i]
550
+ if (!opts.template.trim()) { console.error(' ✗ --template cannot be empty'); process.exit(1) }
548
551
  break
549
552
  case '--context':
550
553
  if (i + 1 >= args.length) { console.error(' ✗ --context requires a path'); process.exit(1) }
551
554
  opts.context = args[++i]
555
+ if (!opts.context.trim()) { console.error(' ✗ --context cannot be empty'); process.exit(1) }
552
556
  break
553
557
  case '--context-text':
554
558
  if (i + 1 >= args.length) { console.error(' ✗ --context-text requires a value'); process.exit(1) }
555
559
  opts.contextText = args[++i]
560
+ if (!opts.contextText.trim()) { console.error(' ✗ --context-text cannot be empty'); process.exit(1) }
556
561
  break
557
562
  case '--output':
558
563
  case '-o':
559
564
  if (i + 1 >= args.length) { console.error(' ✗ --output requires a path'); process.exit(1) }
560
565
  opts.output = args[++i]
566
+ if (!opts.output.trim()) { console.error(' ✗ --output cannot be empty'); process.exit(1) }
561
567
  break
562
568
  case '--adapter':
563
569
  case '-a':
564
570
  if (i + 1 >= args.length) { console.error(' ✗ --adapter requires a name'); process.exit(1) }
565
571
  opts.adapter = args[++i]
572
+ if (!opts.adapter.trim()) { console.error(' ✗ --adapter cannot be empty'); process.exit(1) }
566
573
  break
567
574
  case '--verbose':
568
575
  opts.verbose = true
@@ -572,7 +579,7 @@ function parseArgs(args: string[]): PlanOptions {
572
579
  opts.dryRun = true
573
580
  break
574
581
  default:
575
- console.error(` ✗ Unknown option: ${arg}`)
582
+ console.error(` ✗ Unknown option: ${arg}. Run with --help to see available options.`)
576
583
  console.log(HELP)
577
584
  process.exit(1)
578
585
  }
@@ -196,6 +196,18 @@ describe('copilot adapter — CLI mode', () => {
196
196
  expect(capturedArgs).not.toContain('--approve-mcps')
197
197
  })
198
198
 
199
+ it('does NOT pass --max-turns to the copilot process', async () => {
200
+ const capturedArgs: string[] = []
201
+ mockSpawn.mockImplementation((cmd: string, args: string[]) => {
202
+ if (cmd === 'which') return makeMockProc(0, '')
203
+ capturedArgs.push(...args)
204
+ return makeMockProc(0, '{}')
205
+ })
206
+ const { execute } = await import('./copilot.js')
207
+ await execute(makeTask(), { cwd: tmpDir })
208
+ expect(capturedArgs).not.toContain('--max-turns')
209
+ })
210
+
199
211
  it('maps mcpServers with url and config into mcp.json', async () => {
200
212
  let capturedContent: string | null = null
201
213
  mockSpawn.mockImplementation((cmd: string) => {
@@ -135,7 +135,7 @@ function killSdk(task: Task): void {
135
135
 
136
136
  // --- CLI implementation ---
137
137
  async function executeViaCli(task: Task, options: ExecuteOptions = {}): Promise<ExecuteResult> {
138
- // CLI supports --output-format json, --max-turns, and respects cwd
138
+ // CLI supports --output-format json and respects cwd
139
139
  let prompt = `You are a ${task.agent}. ${task.prompt}`
140
140
  if (task.files && task.files.length > 0) {
141
141
  prompt += `\n\nOnly modify files under: ${task.files.join(', ')}`
@@ -145,8 +145,6 @@ async function executeViaCli(task: Task, options: ExecuteOptions = {}): Promise<
145
145
  prompt,
146
146
  '--output-format',
147
147
  'json',
148
- '--max-turns',
149
- '50',
150
148
  ]
151
149
  const cwd = options?.cwd ?? process.cwd()
152
150
  const mcpJsonPath = join(cwd, 'mcp.json')
package/src/cli/run.ts CHANGED
@@ -88,6 +88,7 @@ function parseArgs(args: string[]): RunOptions {
88
88
  case '-f':
89
89
  if (i + 1 >= args.length) { console.error(' \u2717 --file requires a path'); process.exit(1) }
90
90
  opts.file = args[++i]
91
+ if (!opts.file.trim()) { console.error(' ✗ --file cannot be empty'); process.exit(1) }
91
92
  break
92
93
  case '--dryRun':
93
94
  case '--dry-run':
@@ -108,10 +109,12 @@ function parseArgs(args: string[]): RunOptions {
108
109
  case '-a':
109
110
  if (i + 1 >= args.length) { console.error(' \u2717 --adapter requires a name'); process.exit(1) }
110
111
  opts.adapter = args[++i]
112
+ if (!opts.adapter.trim()) { console.error(' ✗ --adapter cannot be empty'); process.exit(1) }
111
113
  break
112
114
  case '--report-dir':
113
115
  if (i + 1 >= args.length) { console.error(' \u2717 --report-dir requires a path'); process.exit(1) }
114
116
  opts.reportDir = args[++i]
117
+ if (!opts.reportDir.trim()) { console.error(' ✗ --report-dir cannot be empty'); process.exit(1) }
115
118
  break
116
119
  case '--verbose':
117
120
  opts.verbose = true
@@ -142,14 +145,17 @@ function parseArgs(args: string[]): RunOptions {
142
145
  case '--resolution':
143
146
  if (i + 1 >= args.length) { console.error(' ✗ --resolution requires text'); process.exit(1) }
144
147
  opts.dlqResolveText = args[++i]
148
+ if (!opts.dlqResolveText.trim()) { console.error(' ✗ --resolution cannot be empty'); process.exit(1) }
145
149
  break
146
150
  case '--convoy':
147
151
  if (i + 1 >= args.length) { console.error(' ✗ --convoy requires an ID'); process.exit(1) }
148
152
  opts.dlqConvoyFilter = args[++i]
153
+ if (!opts.dlqConvoyFilter.trim()) { console.error(' ✗ --convoy cannot be empty'); process.exit(1) }
149
154
  break
150
155
  case '--formula':
151
156
  if (i + 1 >= args.length) { console.error(' ✗ --formula requires a path'); process.exit(1) }
152
157
  opts.formula = args[++i]
158
+ if (!opts.formula.trim()) { console.error(' ✗ --formula cannot be empty'); process.exit(1) }
153
159
  break
154
160
  case '--set': {
155
161
  if (i + 1 >= args.length) { console.error(' ✗ --set requires key=value'); process.exit(1) }
@@ -168,12 +174,13 @@ function parseArgs(args: string[]): RunOptions {
168
174
  case '--watch-config':
169
175
  if (i + 1 >= args.length) { console.error(' ✗ --watch-config requires a path'); process.exit(1) }
170
176
  opts.watchConfig = args[++i]
177
+ if (!opts.watchConfig.trim()) { console.error(' ✗ --watch-config cannot be empty'); process.exit(1) }
171
178
  break
172
179
  case '--clear-scratchpad':
173
180
  opts.clearScratchpad = true
174
181
  break
175
182
  default:
176
- console.error(` ✗ Unknown option: ${arg}`)
183
+ console.error(` ✗ Unknown option: ${arg}. Run with --help to see available options.`)
177
184
  console.log(HELP)
178
185
  process.exit(1)
179
186
  }
@@ -51,21 +51,21 @@
51
51
  "name": "docs/api-v2-contract.json",
52
52
  "type": "json",
53
53
  "task_id": "api-t1",
54
- "created_at": "2026-04-07T12:58:13.324Z"
54
+ "created_at": "2026-04-07T18:13:57.255Z"
55
55
  },
56
56
  {
57
57
  "id": "artifact-demo-api-v2-reports-security-gate-failure-md",
58
58
  "name": "reports/security-gate-failure.md",
59
59
  "type": "summary",
60
60
  "task_id": "api-t3",
61
- "created_at": "2026-04-07T12:58:13.324Z"
61
+ "created_at": "2026-04-07T18:13:57.255Z"
62
62
  },
63
63
  {
64
64
  "id": "artifact-demo-api-v2-src-api-rate-limiter-ts",
65
65
  "name": "src/api/rate-limiter.ts",
66
66
  "type": "file",
67
67
  "task_id": "api-t2",
68
- "created_at": "2026-04-07T12:58:13.324Z"
68
+ "created_at": "2026-04-07T18:13:57.255Z"
69
69
  }
70
70
  ],
71
71
  "has_more_events": false,
@@ -42,28 +42,28 @@
42
42
  "name": "libs/auth/src/jwt-middleware.ts",
43
43
  "type": "file",
44
44
  "task_id": "auth-t2",
45
- "created_at": "2026-04-07T12:58:13.323Z"
45
+ "created_at": "2026-04-07T18:13:57.254Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-auth-revamp-libs-auth-src-rls-policies-sql",
49
49
  "name": "libs/auth/src/rls-policies.sql",
50
50
  "type": "file",
51
51
  "task_id": "auth-t3",
52
- "created_at": "2026-04-07T12:58:13.323Z"
53
- },
54
- {
55
- "id": "artifact-demo-auth-revamp-tests-auth-integration-test-ts",
56
- "name": "tests/auth/integration.test.ts",
57
- "type": "file",
58
- "task_id": "auth-t4",
59
- "created_at": "2026-04-07T12:58:13.323Z"
52
+ "created_at": "2026-04-07T18:13:57.254Z"
60
53
  },
61
54
  {
62
55
  "id": "artifact-demo-auth-revamp-reports-auth-review-summary-md",
63
56
  "name": "reports/auth-review-summary.md",
64
57
  "type": "summary",
65
58
  "task_id": "auth-t5",
66
- "created_at": "2026-04-07T12:58:13.324Z"
59
+ "created_at": "2026-04-07T18:13:57.254Z"
60
+ },
61
+ {
62
+ "id": "artifact-demo-auth-revamp-tests-auth-integration-test-ts",
63
+ "name": "tests/auth/integration.test.ts",
64
+ "type": "file",
65
+ "task_id": "auth-t4",
66
+ "created_at": "2026-04-07T18:13:57.254Z"
67
67
  }
68
68
  ],
69
69
  "has_more_events": false,
@@ -46,47 +46,47 @@
46
46
  ],
47
47
  "artifact_count": 6,
48
48
  "artifacts": [
49
- {
50
- "id": "artifact-demo-dashboard-ui-reports-panel-review-dashboard-md",
51
- "name": "reports/panel-review-dashboard.md",
52
- "type": "summary",
53
- "task_id": "ui-t7",
54
- "created_at": "2026-04-07T12:58:13.324Z"
55
- },
56
49
  {
57
50
  "id": "artifact-demo-dashboard-ui-reports-visual-regression-json",
58
51
  "name": "reports/visual-regression.json",
59
52
  "type": "json",
60
53
  "task_id": "ui-t6",
61
- "created_at": "2026-04-07T12:58:13.324Z"
54
+ "created_at": "2026-04-07T18:13:57.254Z"
62
55
  },
63
56
  {
64
57
  "id": "artifact-demo-dashboard-ui-src-components-DonutChart-tsx",
65
58
  "name": "src/components/DonutChart.tsx",
66
59
  "type": "file",
67
60
  "task_id": "ui-t3",
68
- "created_at": "2026-04-07T12:58:13.324Z"
61
+ "created_at": "2026-04-07T18:13:57.254Z"
69
62
  },
70
63
  {
71
64
  "id": "artifact-demo-dashboard-ui-src-components-KpiCard-tsx",
72
65
  "name": "src/components/KpiCard.tsx",
73
66
  "type": "file",
74
67
  "task_id": "ui-t2",
75
- "created_at": "2026-04-07T12:58:13.324Z"
68
+ "created_at": "2026-04-07T18:13:57.254Z"
76
69
  },
77
70
  {
78
71
  "id": "artifact-demo-dashboard-ui-src-components-design-tokens-ts",
79
72
  "name": "src/components/design-tokens.ts",
80
73
  "type": "file",
81
74
  "task_id": "ui-t1",
82
- "created_at": "2026-04-07T12:58:13.324Z"
75
+ "created_at": "2026-04-07T18:13:57.254Z"
83
76
  },
84
77
  {
85
78
  "id": "artifact-demo-dashboard-ui-src-styles-animations-css",
86
79
  "name": "src/styles/animations.css",
87
80
  "type": "file",
88
81
  "task_id": "ui-t4",
89
- "created_at": "2026-04-07T12:58:13.324Z"
82
+ "created_at": "2026-04-07T18:13:57.254Z"
83
+ },
84
+ {
85
+ "id": "artifact-demo-dashboard-ui-reports-panel-review-dashboard-md",
86
+ "name": "reports/panel-review-dashboard.md",
87
+ "type": "summary",
88
+ "task_id": "ui-t7",
89
+ "created_at": "2026-04-07T18:13:57.255Z"
90
90
  }
91
91
  ],
92
92
  "has_more_events": false,
@@ -42,21 +42,21 @@
42
42
  "name": "src/etl/pipeline.ts",
43
43
  "type": "file",
44
44
  "task_id": "etl-t2",
45
- "created_at": "2026-04-07T12:58:13.325Z"
45
+ "created_at": "2026-04-07T18:13:57.255Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-data-pipeline-src-etl-schema-ts",
49
49
  "name": "src/etl/schema.ts",
50
50
  "type": "file",
51
51
  "task_id": "etl-t1",
52
- "created_at": "2026-04-07T12:58:13.325Z"
52
+ "created_at": "2026-04-07T18:13:57.255Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-data-pipeline-tests-etl-pipeline-test-ts",
56
56
  "name": "tests/etl/pipeline.test.ts",
57
57
  "type": "file",
58
58
  "task_id": "etl-t3",
59
- "created_at": "2026-04-07T12:58:13.325Z"
59
+ "created_at": "2026-04-07T18:13:57.255Z"
60
60
  }
61
61
  ],
62
62
  "has_more_events": false,
@@ -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-04-07T12:58:13.325Z"
54
+ "created_at": "2026-04-07T18:13:57.256Z"
55
55
  }
56
56
  ],
57
57
  "has_more_events": false,
@@ -42,21 +42,21 @@
42
42
  "name": "docs/ARCHITECTURE.md",
43
43
  "type": "file",
44
44
  "task_id": "docs-t1",
45
- "created_at": "2026-04-07T12:58:13.325Z"
45
+ "created_at": "2026-04-07T18:13:57.256Z"
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-04-07T12:58:13.325Z"
52
+ "created_at": "2026-04-07T18:13:57.256Z"
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-04-07T12:58:13.325Z"
59
+ "created_at": "2026-04-07T18:13:57.256Z"
60
60
  }
61
61
  ],
62
62
  "has_more_events": false,
@@ -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-04-07T12:58:13.324Z"
45
+ "created_at": "2026-04-07T18:13:57.255Z"
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-04-07T12:58:13.325Z"
52
+ "created_at": "2026-04-07T18:13:57.255Z"
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-04-07T12:58:13.325Z"
59
+ "created_at": "2026-04-07T18:13:57.255Z"
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-04-07T12:58:13.325Z"
66
+ "created_at": "2026-04-07T18:13:57.255Z"
67
67
  }
68
68
  ],
69
69
  "has_more_events": false,
@@ -1,25 +1,25 @@
1
1
  {
2
- "hash": "f20511bf",
2
+ "hash": "f3e695ca",
3
3
  "configHash": "30f8ea04",
4
- "lockfileHash": "99386d9e",
5
- "browserHash": "3f60118f",
4
+ "lockfileHash": "63d12489",
5
+ "browserHash": "e7c6fa88",
6
6
  "optimized": {
7
7
  "astro > cssesc": {
8
8
  "src": "../../../../../node_modules/cssesc/cssesc.js",
9
9
  "file": "astro___cssesc.js",
10
- "fileHash": "9ccfbc6b",
10
+ "fileHash": "2f5b696b",
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": "fb8ff67e",
16
+ "fileHash": "b9c79683",
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": "8efd94a5",
22
+ "fileHash": "73366578",
23
23
  "needsInterop": true
24
24
  }
25
25
  },
@@ -51,21 +51,21 @@
51
51
  "name": "docs/api-v2-contract.json",
52
52
  "type": "json",
53
53
  "task_id": "api-t1",
54
- "created_at": "2026-04-07T12:58:13.324Z"
54
+ "created_at": "2026-04-07T18:13:57.255Z"
55
55
  },
56
56
  {
57
57
  "id": "artifact-demo-api-v2-reports-security-gate-failure-md",
58
58
  "name": "reports/security-gate-failure.md",
59
59
  "type": "summary",
60
60
  "task_id": "api-t3",
61
- "created_at": "2026-04-07T12:58:13.324Z"
61
+ "created_at": "2026-04-07T18:13:57.255Z"
62
62
  },
63
63
  {
64
64
  "id": "artifact-demo-api-v2-src-api-rate-limiter-ts",
65
65
  "name": "src/api/rate-limiter.ts",
66
66
  "type": "file",
67
67
  "task_id": "api-t2",
68
- "created_at": "2026-04-07T12:58:13.324Z"
68
+ "created_at": "2026-04-07T18:13:57.255Z"
69
69
  }
70
70
  ],
71
71
  "has_more_events": false,
@@ -42,28 +42,28 @@
42
42
  "name": "libs/auth/src/jwt-middleware.ts",
43
43
  "type": "file",
44
44
  "task_id": "auth-t2",
45
- "created_at": "2026-04-07T12:58:13.323Z"
45
+ "created_at": "2026-04-07T18:13:57.254Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-auth-revamp-libs-auth-src-rls-policies-sql",
49
49
  "name": "libs/auth/src/rls-policies.sql",
50
50
  "type": "file",
51
51
  "task_id": "auth-t3",
52
- "created_at": "2026-04-07T12:58:13.323Z"
53
- },
54
- {
55
- "id": "artifact-demo-auth-revamp-tests-auth-integration-test-ts",
56
- "name": "tests/auth/integration.test.ts",
57
- "type": "file",
58
- "task_id": "auth-t4",
59
- "created_at": "2026-04-07T12:58:13.323Z"
52
+ "created_at": "2026-04-07T18:13:57.254Z"
60
53
  },
61
54
  {
62
55
  "id": "artifact-demo-auth-revamp-reports-auth-review-summary-md",
63
56
  "name": "reports/auth-review-summary.md",
64
57
  "type": "summary",
65
58
  "task_id": "auth-t5",
66
- "created_at": "2026-04-07T12:58:13.324Z"
59
+ "created_at": "2026-04-07T18:13:57.254Z"
60
+ },
61
+ {
62
+ "id": "artifact-demo-auth-revamp-tests-auth-integration-test-ts",
63
+ "name": "tests/auth/integration.test.ts",
64
+ "type": "file",
65
+ "task_id": "auth-t4",
66
+ "created_at": "2026-04-07T18:13:57.254Z"
67
67
  }
68
68
  ],
69
69
  "has_more_events": false,