opencastle 0.28.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +12 -3
  2. package/dist/cli/convoy/engine.d.ts.map +1 -1
  3. package/dist/cli/convoy/engine.js +1 -10
  4. package/dist/cli/convoy/engine.js.map +1 -1
  5. package/dist/cli/convoy/engine.test.js +1 -0
  6. package/dist/cli/convoy/engine.test.js.map +1 -1
  7. package/dist/cli/convoy/export.d.ts +1 -3
  8. package/dist/cli/convoy/export.d.ts.map +1 -1
  9. package/dist/cli/convoy/export.js +9 -88
  10. package/dist/cli/convoy/export.js.map +1 -1
  11. package/dist/cli/convoy/export.test.js +7 -186
  12. package/dist/cli/convoy/export.test.js.map +1 -1
  13. package/dist/cli/convoy/pipeline.d.ts.map +1 -1
  14. package/dist/cli/convoy/pipeline.js +0 -21
  15. package/dist/cli/convoy/pipeline.js.map +1 -1
  16. package/dist/cli/convoy/pipeline.test.js +0 -21
  17. package/dist/cli/convoy/pipeline.test.js.map +1 -1
  18. package/dist/cli/dashboard.d.ts.map +1 -1
  19. package/dist/cli/dashboard.js +32 -8
  20. package/dist/cli/dashboard.js.map +1 -1
  21. package/dist/cli/destroy.d.ts.map +1 -1
  22. package/dist/cli/destroy.js +13 -0
  23. package/dist/cli/destroy.js.map +1 -1
  24. package/dist/cli/dispute.d.ts +3 -0
  25. package/dist/cli/dispute.d.ts.map +1 -0
  26. package/dist/cli/dispute.js +25 -0
  27. package/dist/cli/dispute.js.map +1 -0
  28. package/dist/cli/doctor.d.ts +1 -1
  29. package/dist/cli/doctor.d.ts.map +1 -1
  30. package/dist/cli/doctor.js +14 -1
  31. package/dist/cli/doctor.js.map +1 -1
  32. package/dist/cli/eject.d.ts.map +1 -1
  33. package/dist/cli/eject.js +14 -0
  34. package/dist/cli/eject.js.map +1 -1
  35. package/dist/cli/init.d.ts.map +1 -1
  36. package/dist/cli/init.js +14 -0
  37. package/dist/cli/init.js.map +1 -1
  38. package/dist/cli/log.d.ts +0 -11
  39. package/dist/cli/log.d.ts.map +1 -1
  40. package/dist/cli/log.js +2 -114
  41. package/dist/cli/log.js.map +1 -1
  42. package/dist/cli/pipeline.d.ts +17 -0
  43. package/dist/cli/pipeline.d.ts.map +1 -1
  44. package/dist/cli/pipeline.js +259 -24
  45. package/dist/cli/pipeline.js.map +1 -1
  46. package/dist/cli/pipeline.test.d.ts +2 -0
  47. package/dist/cli/pipeline.test.d.ts.map +1 -0
  48. package/dist/cli/pipeline.test.js +178 -0
  49. package/dist/cli/pipeline.test.js.map +1 -0
  50. package/dist/cli/run.js +2 -2
  51. package/dist/cli/run.js.map +1 -1
  52. package/dist/cli/update.d.ts.map +1 -1
  53. package/dist/cli/update.js +16 -0
  54. package/dist/cli/update.js.map +1 -1
  55. package/dist/cli/watch.d.ts.map +1 -1
  56. package/dist/cli/watch.js +1 -3
  57. package/dist/cli/watch.js.map +1 -1
  58. package/package.json +1 -1
  59. package/src/cli/convoy/engine.test.ts +1 -0
  60. package/src/cli/convoy/engine.ts +1 -4
  61. package/src/cli/convoy/export.test.ts +7 -224
  62. package/src/cli/convoy/export.ts +10 -106
  63. package/src/cli/convoy/pipeline.test.ts +0 -25
  64. package/src/cli/convoy/pipeline.ts +0 -19
  65. package/src/cli/dashboard.ts +33 -8
  66. package/src/cli/destroy.ts +15 -0
  67. package/src/cli/dispute.ts +28 -0
  68. package/src/cli/doctor.ts +16 -1
  69. package/src/cli/eject.ts +16 -0
  70. package/src/cli/init.ts +16 -0
  71. package/src/cli/log.ts +2 -120
  72. package/src/cli/pipeline.test.ts +191 -0
  73. package/src/cli/pipeline.ts +326 -26
  74. package/src/cli/run.ts +2 -2
  75. package/src/cli/update.ts +18 -0
  76. package/src/cli/watch.ts +1 -3
  77. package/src/dashboard/dist/_astro/index.Je1YjU_y.css +1 -0
  78. package/src/dashboard/dist/index.html +537 -1394
  79. package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
  80. package/src/dashboard/scripts/etl.test.ts +4 -62
  81. package/src/dashboard/scripts/etl.ts +13 -33
  82. package/src/dashboard/src/pages/index.astro +684 -1624
  83. package/src/dashboard/src/styles/dashboard.css +473 -7
  84. package/src/orchestrator/agents/team-lead.agent.md +13 -0
  85. package/src/orchestrator/prompts/brainstorm.prompt.md +1 -0
  86. package/src/orchestrator/prompts/fix-prd.prompt.md +58 -0
  87. package/src/orchestrator/prompts/generate-convoy.prompt.md +30 -0
  88. package/src/orchestrator/prompts/generate-prd.prompt.md +38 -0
  89. package/dist/cli/convoy/log-merge.test.d.ts +0 -2
  90. package/dist/cli/convoy/log-merge.test.d.ts.map +0 -1
  91. package/dist/cli/convoy/log-merge.test.js +0 -147
  92. package/dist/cli/convoy/log-merge.test.js.map +0 -1
  93. package/src/cli/convoy/log-merge.test.ts +0 -179
  94. package/src/dashboard/dist/_astro/index.6L3_HsPT.css +0 -1
@@ -275,7 +275,6 @@ body {
275
275
  background: var(--bg-secondary);
276
276
  border: 1px solid var(--border-color);
277
277
  border-radius: 12px;
278
- overflow: hidden;
279
278
  transition: border-color var(--transition-fast);
280
279
  }
281
280
 
@@ -1880,15 +1879,18 @@ body {
1880
1879
  bottom: 100%;
1881
1880
  left: 50%;
1882
1881
  transform: translateX(-50%);
1883
- padding: 0.375rem 0.625rem;
1882
+ padding: 0.5rem 0.875rem;
1884
1883
  background: var(--bg-primary);
1885
1884
  border: 1px solid rgba(255, 255, 255, 0.12);
1886
1885
  border-radius: 6px;
1887
- font-size: 0.75rem;
1886
+ font-size: 0.8125rem;
1888
1887
  color: var(--text-primary);
1889
- max-width: 280px;
1888
+ max-width: 420px;
1889
+ min-width: 180px;
1890
1890
  white-space: normal;
1891
1891
  text-align: left;
1892
+ line-height: 1.5;
1893
+ word-break: break-word;
1892
1894
  z-index: 100;
1893
1895
  pointer-events: none;
1894
1896
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
@@ -1906,15 +1908,18 @@ body {
1906
1908
  bottom: 100%;
1907
1909
  left: 50%;
1908
1910
  transform: translateX(-50%);
1909
- padding: 0.375rem 0.625rem;
1911
+ padding: 0.5rem 0.875rem;
1910
1912
  background: var(--bg-primary);
1911
1913
  border: 1px solid rgba(255, 255, 255, 0.12);
1912
1914
  border-radius: 6px;
1913
- font-size: 0.75rem;
1915
+ font-size: 0.8125rem;
1914
1916
  color: var(--text-primary);
1915
- max-width: 280px;
1917
+ max-width: 420px;
1918
+ min-width: 180px;
1916
1919
  white-space: normal;
1917
1920
  text-align: left;
1921
+ line-height: 1.5;
1922
+ word-break: break-word;
1918
1923
  z-index: 100;
1919
1924
  pointer-events: none;
1920
1925
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
@@ -2269,3 +2274,464 @@ body {
2269
2274
  margin-bottom: 0.5rem;
2270
2275
  font-style: italic;
2271
2276
  }
2277
+
2278
+ /* ── View Management ───────────────────────────────────── */
2279
+ .view-home,
2280
+ .view-convoy-detail {
2281
+ display: flex;
2282
+ flex-direction: column;
2283
+ gap: 20px;
2284
+ }
2285
+
2286
+ [data-view-hidden] {
2287
+ display: none !important;
2288
+ }
2289
+
2290
+ /* ── Breadcrumbs ───────────────────────────────────────── */
2291
+ .breadcrumbs {
2292
+ display: flex;
2293
+ align-items: center;
2294
+ gap: 6px;
2295
+ font-size: 0.8125rem;
2296
+ color: var(--text-tertiary);
2297
+ flex-wrap: wrap;
2298
+ padding: 0;
2299
+ margin-bottom: -8px;
2300
+ }
2301
+
2302
+ .breadcrumbs__link {
2303
+ color: var(--text-secondary);
2304
+ text-decoration: none;
2305
+ transition: color var(--transition-fast);
2306
+ border-bottom: 1px solid transparent;
2307
+ }
2308
+
2309
+ .breadcrumbs__link:hover {
2310
+ color: var(--text-accent);
2311
+ border-bottom-color: rgba(167, 139, 250, 0.4);
2312
+ }
2313
+
2314
+ .breadcrumbs__link:focus-visible {
2315
+ outline: 2px solid var(--accent-blue);
2316
+ outline-offset: 2px;
2317
+ border-radius: 2px;
2318
+ }
2319
+
2320
+ .breadcrumbs__separator {
2321
+ color: var(--text-tertiary);
2322
+ opacity: 0.5;
2323
+ user-select: none;
2324
+ font-size: 0.75rem;
2325
+ }
2326
+
2327
+ .breadcrumbs__current {
2328
+ color: var(--text-accent);
2329
+ font-weight: 500;
2330
+ max-width: 320px;
2331
+ overflow: hidden;
2332
+ text-overflow: ellipsis;
2333
+ white-space: nowrap;
2334
+ }
2335
+
2336
+ /* ── Convoy List Section ───────────────────────────────── */
2337
+ .convoy-list-section {
2338
+ background: var(--bg-secondary);
2339
+ border: 1px solid var(--border-color);
2340
+ border-radius: 12px;
2341
+ transition: border-color var(--transition-fast);
2342
+ }
2343
+
2344
+ .convoy-list-section:hover {
2345
+ border-color: rgba(255, 255, 255, 0.1);
2346
+ }
2347
+
2348
+ .convoy-list-section__header {
2349
+ padding: 20px 24px 12px;
2350
+ border-bottom: 1px solid var(--border-color);
2351
+ }
2352
+
2353
+ .convoy-list-section__header h2,
2354
+ .convoy-list-section__header .convoy-list-section__title {
2355
+ font-size: 0.9375rem;
2356
+ font-weight: 600;
2357
+ color: var(--text-primary);
2358
+ margin: 0;
2359
+ }
2360
+
2361
+ .convoy-list-section__desc {
2362
+ font-size: 0.75rem;
2363
+ color: var(--text-tertiary);
2364
+ margin-top: 2px;
2365
+ }
2366
+
2367
+ /* ── Convoy List Filters ─────────────────────────────── */
2368
+ .convoy-list-filters {
2369
+ display: flex;
2370
+ flex-wrap: wrap;
2371
+ gap: 10px;
2372
+ align-items: flex-end;
2373
+ padding: 14px 24px;
2374
+ background: rgba(255, 255, 255, 0.01);
2375
+ border-bottom: 1px solid var(--border-color);
2376
+ }
2377
+
2378
+ .convoy-list-filters__group {
2379
+ display: flex;
2380
+ flex-direction: column;
2381
+ gap: 4px;
2382
+ }
2383
+
2384
+ .convoy-list-filters__group label {
2385
+ font-size: 0.6875rem;
2386
+ font-weight: 500;
2387
+ color: var(--text-tertiary);
2388
+ text-transform: uppercase;
2389
+ letter-spacing: 0.05em;
2390
+ }
2391
+
2392
+ .convoy-list-filters__input,
2393
+ .convoy-list-filters__select,
2394
+ .convoy-list-filters__date {
2395
+ height: 34px;
2396
+ padding: 0 10px;
2397
+ font-size: 0.8125rem;
2398
+ color: var(--text-primary);
2399
+ background: var(--bg-tertiary);
2400
+ border: 1px solid var(--border-color);
2401
+ border-radius: 8px;
2402
+ outline: none;
2403
+ font-family: inherit;
2404
+ transition: border-color var(--transition-fast);
2405
+ color-scheme: dark;
2406
+ }
2407
+
2408
+ .convoy-list-filters__input:focus,
2409
+ .convoy-list-filters__select:focus,
2410
+ .convoy-list-filters__date:focus {
2411
+ border-color: var(--border-accent);
2412
+ }
2413
+
2414
+ .convoy-list-filters__input {
2415
+ width: 180px;
2416
+ }
2417
+
2418
+ .convoy-list-filters__date {
2419
+ width: 150px;
2420
+ }
2421
+
2422
+ .convoy-list-filters__select {
2423
+ min-width: 140px;
2424
+ cursor: pointer;
2425
+ appearance: none;
2426
+ -webkit-appearance: none;
2427
+ background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%235a5a6e' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
2428
+ background-repeat: no-repeat;
2429
+ background-position: right 10px center;
2430
+ padding-right: 28px;
2431
+ }
2432
+
2433
+ .convoy-list-filters__reset {
2434
+ height: 34px;
2435
+ padding: 0 14px;
2436
+ font-size: 0.75rem;
2437
+ font-weight: 500;
2438
+ font-family: inherit;
2439
+ color: var(--text-secondary);
2440
+ background: rgba(255, 255, 255, 0.06);
2441
+ border: none;
2442
+ border-radius: 8px;
2443
+ cursor: pointer;
2444
+ transition: background var(--transition-fast), color var(--transition-fast);
2445
+ align-self: flex-end;
2446
+ white-space: nowrap;
2447
+ }
2448
+
2449
+ .convoy-list-filters__reset:hover {
2450
+ background: rgba(255, 255, 255, 0.10);
2451
+ color: var(--text-primary);
2452
+ }
2453
+
2454
+ .convoy-list-filters__reset:focus-visible {
2455
+ outline: 2px solid var(--accent-blue);
2456
+ outline-offset: 2px;
2457
+ }
2458
+
2459
+ /* ── Convoy List Table ───────────────────────────────── */
2460
+ .convoy-list-table {
2461
+ width: 100%;
2462
+ border-collapse: collapse;
2463
+ font-size: 0.8125rem;
2464
+ }
2465
+
2466
+ .convoy-list-table thead {
2467
+ position: sticky;
2468
+ top: 0;
2469
+ }
2470
+
2471
+ .convoy-list-table th {
2472
+ padding: 10px 16px;
2473
+ font-size: 0.6875rem;
2474
+ font-weight: 600;
2475
+ color: var(--text-tertiary);
2476
+ text-align: left;
2477
+ text-transform: uppercase;
2478
+ letter-spacing: 0.06em;
2479
+ background: var(--bg-tertiary);
2480
+ border-bottom: 1px solid var(--border-color);
2481
+ white-space: nowrap;
2482
+ }
2483
+
2484
+ .convoy-list-table td {
2485
+ padding: 10px 16px;
2486
+ color: var(--text-secondary);
2487
+ border-bottom: 1px solid rgba(255, 255, 255, 0.03);
2488
+ white-space: nowrap;
2489
+ }
2490
+
2491
+ .convoy-list-table tr {
2492
+ cursor: pointer;
2493
+ transition: background var(--transition-fast);
2494
+ }
2495
+
2496
+ .convoy-list-table tbody tr:hover td {
2497
+ background: rgba(167, 139, 250, 0.05);
2498
+ color: var(--text-primary);
2499
+ }
2500
+
2501
+ .convoy-list-table tbody tr:hover td:first-child {
2502
+ color: var(--text-accent);
2503
+ }
2504
+
2505
+ .convoy-list-table .td-convoy-name {
2506
+ font-weight: 600;
2507
+ color: var(--text-primary);
2508
+ max-width: 240px;
2509
+ overflow: hidden;
2510
+ text-overflow: ellipsis;
2511
+ }
2512
+
2513
+ /* ── Convoy List Empty ───────────────────────────────── */
2514
+ .convoy-list-empty {
2515
+ display: flex;
2516
+ flex-direction: column;
2517
+ align-items: center;
2518
+ justify-content: center;
2519
+ gap: 10px;
2520
+ padding: 48px 24px;
2521
+ text-align: center;
2522
+ color: var(--text-tertiary);
2523
+ }
2524
+
2525
+ .convoy-list-empty__icon {
2526
+ font-size: 2rem;
2527
+ opacity: 0.35;
2528
+ }
2529
+
2530
+ .convoy-list-empty__text {
2531
+ font-size: 0.875rem;
2532
+ color: var(--text-tertiary);
2533
+ max-width: 300px;
2534
+ line-height: 1.5;
2535
+ }
2536
+
2537
+ /* ── Convoy Detail Hero ──────────────────────────────── */
2538
+ .convoy-detail-hero {
2539
+ display: flex;
2540
+ flex-direction: column;
2541
+ gap: 12px;
2542
+ padding: 24px;
2543
+ background: var(--bg-secondary);
2544
+ border: 1px solid var(--border-color);
2545
+ border-radius: 12px;
2546
+ position: relative;
2547
+ }
2548
+
2549
+ .convoy-detail-hero::before {
2550
+ content: '';
2551
+ position: absolute;
2552
+ top: 0;
2553
+ left: 0;
2554
+ right: 0;
2555
+ height: 2px;
2556
+ background: var(--gradient-accent);
2557
+ opacity: 0.6;
2558
+ pointer-events: none;
2559
+ }
2560
+
2561
+ .convoy-detail-hero__top {
2562
+ display: flex;
2563
+ align-items: center;
2564
+ gap: 14px;
2565
+ flex-wrap: wrap;
2566
+ }
2567
+
2568
+ .convoy-detail-hero__title {
2569
+ font-size: 1.5rem;
2570
+ font-weight: 700;
2571
+ color: var(--text-primary);
2572
+ letter-spacing: -0.02em;
2573
+ line-height: 1.25;
2574
+ margin: 0;
2575
+ }
2576
+
2577
+ .convoy-detail-hero__status {
2578
+ flex-shrink: 0;
2579
+ }
2580
+
2581
+ .convoy-detail-hero__status .status-badge {
2582
+ padding: 0.25rem 0.875rem;
2583
+ font-size: 0.75rem;
2584
+ border-radius: 8px;
2585
+ }
2586
+
2587
+ .convoy-detail-hero__meta {
2588
+ display: flex;
2589
+ flex-wrap: wrap;
2590
+ gap: 20px;
2591
+ padding-top: 4px;
2592
+ border-top: 1px solid var(--border-color);
2593
+ }
2594
+
2595
+ .convoy-detail-hero__meta-item {
2596
+ display: flex;
2597
+ flex-direction: column;
2598
+ gap: 2px;
2599
+ }
2600
+
2601
+ .convoy-detail-hero__meta-label {
2602
+ font-size: 0.6875rem;
2603
+ font-weight: 500;
2604
+ color: var(--text-tertiary);
2605
+ text-transform: uppercase;
2606
+ letter-spacing: 0.05em;
2607
+ }
2608
+
2609
+ .convoy-detail-hero__meta-value {
2610
+ font-size: 0.875rem;
2611
+ color: var(--text-secondary);
2612
+ font-variant-numeric: tabular-nums;
2613
+ }
2614
+
2615
+ /* ── Task Row Enhancement ────────────────────────────── */
2616
+ .task-row--clickable {
2617
+ cursor: pointer;
2618
+ transition: background var(--transition-fast);
2619
+ }
2620
+
2621
+ .task-row--clickable:hover td {
2622
+ background: rgba(167, 139, 250, 0.04);
2623
+ }
2624
+
2625
+ .task-row--clickable td:first-child {
2626
+ position: relative;
2627
+ }
2628
+
2629
+ .task-row--clickable td:first-child::before {
2630
+ content: '';
2631
+ position: absolute;
2632
+ left: 0;
2633
+ top: 0;
2634
+ bottom: 0;
2635
+ width: 2px;
2636
+ background: transparent;
2637
+ transition: background var(--transition-fast);
2638
+ }
2639
+
2640
+ .task-row--clickable:hover td:first-child::before {
2641
+ background: var(--border-accent);
2642
+ }
2643
+
2644
+ .task-detail-expand {
2645
+ background: var(--bg-tertiary);
2646
+ border-bottom: 1px solid var(--border-color);
2647
+ }
2648
+
2649
+ .task-detail-expand__inner {
2650
+ padding: 16px 20px;
2651
+ }
2652
+
2653
+ .task-detail-expand__grid {
2654
+ display: grid;
2655
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
2656
+ gap: 12px 24px;
2657
+ }
2658
+
2659
+ .task-detail-expand__field {
2660
+ display: flex;
2661
+ flex-direction: column;
2662
+ gap: 3px;
2663
+ }
2664
+
2665
+ .task-detail-expand__label {
2666
+ font-size: 0.6875rem;
2667
+ font-weight: 600;
2668
+ text-transform: uppercase;
2669
+ letter-spacing: 0.05em;
2670
+ color: var(--text-tertiary);
2671
+ }
2672
+
2673
+ .task-detail-expand__value {
2674
+ font-size: 0.8125rem;
2675
+ color: var(--text-secondary);
2676
+ word-break: break-word;
2677
+ font-variant-numeric: tabular-nums;
2678
+ }
2679
+
2680
+ .task-detail-expand__value code {
2681
+ font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
2682
+ font-size: 0.75rem;
2683
+ background: rgba(255, 255, 255, 0.06);
2684
+ padding: 1px 6px;
2685
+ border-radius: 4px;
2686
+ color: var(--text-accent);
2687
+ }
2688
+
2689
+ /* ── Responsive: Convoy List Filters ────────────────── */
2690
+ @media (max-width: 768px) {
2691
+ .convoy-list-filters {
2692
+ padding: 12px 16px;
2693
+ gap: 8px;
2694
+ }
2695
+
2696
+ .convoy-list-filters__input,
2697
+ .convoy-list-filters__select,
2698
+ .convoy-list-filters__date {
2699
+ width: 100%;
2700
+ min-width: unset;
2701
+ }
2702
+
2703
+ .convoy-list-filters__group {
2704
+ flex: 1 1 calc(50% - 4px);
2705
+ }
2706
+
2707
+ .convoy-list-filters__reset {
2708
+ flex: 1 1 100%;
2709
+ width: 100%;
2710
+ }
2711
+
2712
+ .convoy-list-section__header {
2713
+ padding: 16px 16px 12px;
2714
+ }
2715
+ }
2716
+
2717
+ @media (max-width: 480px) {
2718
+ .convoy-list-filters__group {
2719
+ flex: 1 1 100%;
2720
+ }
2721
+
2722
+ .convoy-detail-hero__title {
2723
+ font-size: 1.25rem;
2724
+ }
2725
+
2726
+ .convoy-detail-hero {
2727
+ padding: 16px;
2728
+ }
2729
+
2730
+ .task-detail-expand__grid {
2731
+ grid-template-columns: 1fr;
2732
+ }
2733
+
2734
+ .breadcrumbs__current {
2735
+ max-width: 180px;
2736
+ }
2737
+ }
@@ -109,6 +109,19 @@ When calling `runSubagent`, always specify which custom agent to use by name: *"
109
109
 
110
110
  **After each sub-agent returns**, log the delegation record before doing anything else (before review, before verification). This is a **⛔ hard gate** — do NOT proceed to review or any other action until the delegation is logged. Use the **observability-logging** skill's delegation record command (`--mechanism sub-agent`).
111
111
 
112
+ ### Empty Output Handling
113
+
114
+ If a sub-agent returns empty, minimal, or off-topic output:
115
+
116
+ 1. **Never fall back to writing content yourself** — Rule #1 still applies
117
+ 2. **Retry with an explicit prompt** — Restate the objective with:
118
+ - Exact deliverables expected (e.g., "Return the full revised text, not a summary")
119
+ - The Output Contract from the agent's definition (paste it into the prompt)
120
+ - An example of what good output looks like
121
+ 3. **Escalate the model** — If the Economy-tier agent fails twice, re-delegate to a Standard-tier agent (e.g., use Developer or UI/UX Expert for content tasks that require codebase context)
122
+ 4. **Log the failure** — Even if retry succeeds, log the empty-output attempt as a delegation with `outcome: failed` and `failure_reason: empty_output`
123
+ 5. **Max 3 attempts** — After 3 empty returns → DLQ the task to `.opencastle/AGENT-FAILURES.md`
124
+
112
125
  > **`model` and `tier` must come from the agent registry** — not the Team Lead's own model. Look up the agent in [agent-registry.md](../.opencastle/agents/agent-registry.md) and use their assigned model and tier. For example, delegating to Developer → `"model":"claude-sonnet-4-6","tier":"quality"`, not the Team Lead's `claude-opus-4-6`.
113
126
 
114
127
  ### Background Agents — Delegate Session
@@ -38,6 +38,7 @@ Research before proposing. Gather data, don't guess:
38
38
  2. **Check documentation** — read `.opencastle/project.instructions.md`, `.opencastle/project/decisions.md`, `.opencastle/KNOWN-ISSUES.md` for constraints
39
39
  3. **Check lessons learned** — read `.opencastle/LESSONS-LEARNED.md` for pitfalls in this area
40
40
  4. **Identify affected layers** — which apps, libs, data stores, and third-party services are involved?
41
+ 5. **Research unknown topics** — if the request involves a real-world person, place, organization, or topic you don't have confident knowledge about, **search the internet** using any available web search or fetch tools (e.g. `fetch_webpage`, web search MCP, or similar) to gather accurate facts. Never fabricate content about real-world subjects.
41
42
 
42
43
  ### 3. Generate Alternatives
43
44
 
@@ -0,0 +1,58 @@
1
+ ---
2
+ description: 'Fix validation errors in a PRD. Goal is the broken PRD markdown; context is the error list from the validation step.'
3
+ agent: 'Team Lead (OpenCastle)'
4
+ output: prd
5
+ ---
6
+
7
+ <!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the .opencastle/ directory instead. -->
8
+
9
+ # Fix PRD
10
+
11
+ You are the Team Lead. The PRD below failed validation. Fix **every reported issue** and output a complete, corrected PRD.
12
+
13
+ ## Failing PRD
14
+
15
+ {{goal}}
16
+
17
+ ## Validation Errors
18
+
19
+ {{context}}
20
+
21
+ ---
22
+
23
+ ## Fix Instructions
24
+
25
+ 1. Read every reported issue before making changes.
26
+ 2. Fix **all** reported issues — do not partially fix.
27
+ 3. Do not change the intent, goals, or scope of the feature. Only fix what the validator flagged.
28
+ 4. Preserve all content that is not part of the reported issues.
29
+
30
+ ### Common Fix Patterns
31
+
32
+ **Missing sections**
33
+ - Add the missing section with concrete, specific content — not placeholder text
34
+ - If the section needs real data you cannot infer, write a reasonable default and mark with `<!-- TODO: verify -->`
35
+
36
+ **Vague acceptance criteria**
37
+ - Replace subjective language ("looks good", "feels responsive") with measurable conditions ("renders within 200ms", "meets WCAG 2.2 AA contrast ratio")
38
+ - Replace modal verbs ("should", "might", "could") with definitive language ("must", "will")
39
+
40
+ **Broad implementation scope**
41
+ - Replace broad paths (`src/`, `the frontend`) with specific file names or subdirectory names
42
+ - Remove glob patterns (`*`, `**`) from scope tables — use actual directory or file names
43
+
44
+ **File partition conflicts**
45
+ - If two parallel workstreams claim the same file, move one to a later phase with explicit dependency
46
+ - Or split the file's responsibilities across the two workstreams so each touches distinct files
47
+
48
+ **Missing dependency declarations**
49
+ - Add `depends on: Phase N` to phases that require output from earlier phases
50
+
51
+ **Placeholder text**
52
+ - Replace template filler ("2–3 sentences about…", "Description here") with real content derived from the feature description
53
+
54
+ ---
55
+
56
+ ## Output
57
+
58
+ Return the **complete corrected PRD** as raw Markdown starting with the `#` heading. Do not wrap the output in a code fence. Do not add explanatory prose before or after the PRD.
@@ -151,6 +151,13 @@ Enables continuous re-execution triggered by file changes, cron, or git push.
151
151
  | `cron` | `schedule` (5-field cron) | Re-run on cron schedule |
152
152
  | `git-push` | `branch` | Re-run when new commits are pushed |
153
153
 
154
+ ### Content Research Rule
155
+
156
+ When writing task `prompt` fields that involve creating content about real-world people, places, organizations, or topics — **include an explicit instruction in the prompt** telling the agent to search the internet first using any available web search or fetch tools (e.g. `fetch_webpage`, web search MCP). Agents must never fabricate bios, descriptions, histories, statistics, or any factual claims. If web search is unavailable, the prompt should instruct the agent to use placeholder text clearly marked as `[NEEDS RESEARCH]` rather than inventing content.
157
+
158
+ Example prompt suffix to include when content research is needed:
159
+ > "Before writing any content about [topic], search the internet for accurate information. Do not make up facts, descriptions, or biographical details. Use verified sources only."
160
+
154
161
  ### Task Fields
155
162
 
156
163
  | Field | Type | Required | Default | Description |
@@ -302,6 +309,29 @@ For complex tasks, consider using `steps` to break the prompt into sequential su
302
309
  >
303
310
  > **Strong prompt:** "Write unit tests for `libs/auth/src/server.ts` covering token refresh, expiry edge cases, and invalid signatures. Place tests in `libs/auth/src/__tests__/server.test.ts`. Follow the existing test conventions. Achieve ≥ 95 % coverage for `server.ts`. Run the project's test command with coverage and fix any failures."
304
311
 
312
+ ### Chain Mode (Subset Generation)
313
+
314
+ When the `{{context}}` field contains a JSON object with `"mode": "chain_subset"`, you are generating ONE convoy spec that is part of a larger convoy chain. The context will look like:
315
+
316
+ ```json
317
+ {
318
+ "mode": "chain_subset",
319
+ "group_name": "database-setup",
320
+ "group_description": "Schema changes and migrations",
321
+ "group_phases": [1],
322
+ "depends_on_groups": [],
323
+ "total_groups": 3,
324
+ "group_index": 1
325
+ }
326
+ ```
327
+
328
+ When this context is present:
329
+ - **Only** generate tasks for the phases listed in `group_phases`. Do not include tasks from other phases.
330
+ - Use `version: 1` — this spec is a single convoy, not a pipeline.
331
+ - Derive the convoy `name` from `group_name` (e.g., "Database Setup").
332
+ - Derive the `branch` from the PRD's feature name, but it will be overridden by the pipeline anyway.
333
+ - Keep all other conventions (prompts, files, gates, etc.) the same as for single-spec generation.
334
+
305
335
  ### 6. Validate Before Outputting
306
336
 
307
337
  Before presenting the YAML, mentally verify:
@@ -20,6 +20,12 @@ You are the Team Lead. Convert the feature request below into a structured Produ
20
20
 
21
21
  ---
22
22
 
23
+ ## Research Before Writing
24
+
25
+ If the feature request involves a specific person, place, organization, topic, or any real-world subject you are not confident you have accurate knowledge about — **you MUST search the internet first** using any available web search or fetch tools (e.g. `fetch_webpage`, web search MCP, or similar). Use the search results to gather accurate facts, names, dates, descriptions, and other details.
26
+
27
+ **Never fabricate or hallucinate content** about real-world subjects. If you cannot verify a claim through web search, state what is unknown rather than inventing plausible-sounding text. This applies to all content: bios, descriptions, histories, statistics, quotes, and any factual claims.
28
+
23
29
  ## Required PRD Structure
24
30
 
25
31
  Produce the PRD in Markdown using **exactly** the sections below. Do not skip or merge sections. Do not wrap the output in a code fence — output raw Markdown starting directly with the `#` heading.
@@ -118,3 +124,35 @@ Measurable, binary checks that confirm the feature is shippable:
118
124
  - **[Open question]**: [What needs to be decided before implementation can start]
119
125
 
120
126
  If there are no risks or open questions, write "None identified."
127
+
128
+ ## Complexity Assessment
129
+
130
+ Produce a fenced JSON block with the following fields. This is consumed programmatically by the pipeline to decide whether to generate a single convoy spec or a convoy chain.
131
+
132
+ ```json
133
+ {
134
+ "total_tasks": 12,
135
+ "total_phases": 4,
136
+ "domains": ["database", "api", "frontend", "testing"],
137
+ "estimated_duration_minutes": 120,
138
+ "complexity": "low",
139
+ "recommended_strategy": "single",
140
+ "chain_rationale": "",
141
+ "convoy_groups": [
142
+ {
143
+ "name": "full-implementation",
144
+ "description": "All phases in a single convoy",
145
+ "phases": [1, 2, 3, 4],
146
+ "depends_on": []
147
+ }
148
+ ]
149
+ }
150
+ ```
151
+
152
+ **Strategy decision rules:**
153
+ - Use `"single"` when: total tasks ≤ 8, or total phases ≤ 3, or all tasks are tightly coupled with heavy cross-phase file sharing.
154
+ - Use `"chain"` when: total tasks > 8 AND total phases > 3 AND domains have natural boundaries (e.g., database changes are independent from frontend components from test suites) — AND splitting would improve failure isolation, observability, or retry granularity.
155
+ - When `"single"`: provide exactly one convoy group covering all phases.
156
+ - When `"chain"`: provide 2–4 convoy groups with explicit `depends_on` order. Each group should cover a coherent domain boundary.
157
+ - `complexity` values: `"low"` (1–4 tasks), `"medium"` (5–8 tasks), `"high"` (9+ tasks).
158
+ - `chain_rationale` is only filled when `recommended_strategy` is `"chain"` — explain WHY splitting benefits this specific feature.
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=log-merge.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"log-merge.test.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/log-merge.test.ts"],"names":[],"mappings":""}