@shepai/cli 1.121.0-pr391.c78e14b → 1.122.0-pr392.ff1c944

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 (142) hide show
  1. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +1 -1
  2. package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +94 -27
  3. package/dist/tsconfig.build.tsbuildinfo +1 -1
  4. package/package.json +1 -1
  5. package/web/.next/BUILD_ID +1 -1
  6. package/web/.next/build-manifest.json +2 -2
  7. package/web/.next/fallback-build-manifest.json +2 -2
  8. package/web/.next/prerender-manifest.json +3 -3
  9. package/web/.next/required-server-files.js +2 -2
  10. package/web/.next/required-server-files.json +2 -2
  11. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
  12. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  13. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  14. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  15. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  16. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  17. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
  18. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  19. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  20. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  21. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  22. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  23. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
  24. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  25. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  26. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  27. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  28. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  29. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
  30. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  31. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  32. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
  33. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  34. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  35. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  36. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  37. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  38. package/web/.next/server/app/_global-error.html +2 -2
  39. package/web/.next/server/app/_global-error.rsc +1 -1
  40. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  41. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  42. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  43. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  44. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  45. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  46. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  47. package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
  48. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  49. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  50. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  51. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  53. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  54. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  55. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  57. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  58. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  59. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +1 -1
  60. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -1
  61. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +1 -1
  62. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -1
  63. package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
  64. package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js +1 -1
  65. package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js.map +1 -1
  66. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +1 -1
  67. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +1 -1
  68. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  69. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  70. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  71. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  72. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  73. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  74. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +2 -2
  75. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js +1 -1
  76. package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js.map +1 -1
  77. package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +2 -2
  78. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +2 -2
  79. package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js +1 -1
  80. package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js.map +1 -1
  81. package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js +1 -1
  82. package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js.map +1 -1
  83. package/web/.next/server/chunks/ssr/[root-of-the-server]__f646b99a._.js +3 -0
  84. package/web/.next/server/chunks/ssr/[root-of-the-server]__f646b99a._.js.map +1 -0
  85. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +1 -1
  86. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +1 -1
  87. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  88. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  89. package/web/.next/server/chunks/ssr/{_f7380711._.js → _1ced87ef._.js} +2 -2
  90. package/web/.next/server/chunks/ssr/{_f7380711._.js.map → _1ced87ef._.js.map} +1 -1
  91. package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
  92. package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
  93. package/web/.next/server/chunks/ssr/_affb27a3._.js +3 -0
  94. package/web/.next/server/chunks/ssr/{_c56ec6a7._.js.map → _affb27a3._.js.map} +1 -1
  95. package/web/.next/server/chunks/ssr/_cb942e20._.js +3 -0
  96. package/web/.next/server/chunks/ssr/_cb942e20._.js.map +1 -0
  97. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  98. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  99. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  100. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  101. package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js +2 -2
  102. package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js.map +1 -1
  103. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +1 -1
  104. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -1
  105. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  106. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  107. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  108. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  109. package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js +2 -2
  110. package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js.map +1 -1
  111. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  112. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  113. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  114. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  115. package/web/.next/server/pages/500.html +2 -2
  116. package/web/.next/server/server-reference-manifest.js +1 -1
  117. package/web/.next/server/server-reference-manifest.json +34 -34
  118. package/web/.next/static/chunks/04b2108495415052.js +1 -0
  119. package/web/.next/static/chunks/3911a7175044e784.js +1 -0
  120. package/web/.next/static/chunks/574116ea7de4c18d.js +1 -0
  121. package/web/.next/static/chunks/{7fbb2a18e0290c04.js → 5c4ada27bc57d0a4.js} +1 -1
  122. package/web/.next/static/chunks/68c5260cce07b4de.js +1 -0
  123. package/web/.next/static/chunks/{946fb1bc0a185497.js → 780f705bfe91f7fc.js} +1 -1
  124. package/web/.next/static/chunks/991df1233214b238.css +1 -0
  125. package/web/.next/static/chunks/{13cfe539c3614462.js → a0d1d6263db19600.js} +1 -1
  126. package/web/.next/static/chunks/{84afd37bdafaebd2.js → aa9c03b455fc4a49.js} +1 -1
  127. package/web/.next/static/chunks/{e4e8be03b609cbb9.js → aee3590a26cac4f3.js} +1 -1
  128. package/web/.next/static/chunks/{069b25904188166a.js → cce8416ed0cbc011.js} +2 -2
  129. package/web/.next/static/chunks/{55ba4f5f2c14bc6d.js → f27126bcef6cbaa9.js} +1 -1
  130. package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js +0 -3
  131. package/web/.next/server/chunks/ssr/[root-of-the-server]__9f155c0e._.js.map +0 -1
  132. package/web/.next/server/chunks/ssr/_bab62fc0._.js +0 -3
  133. package/web/.next/server/chunks/ssr/_bab62fc0._.js.map +0 -1
  134. package/web/.next/server/chunks/ssr/_c56ec6a7._.js +0 -3
  135. package/web/.next/static/chunks/0d2af96e64960ef5.css +0 -1
  136. package/web/.next/static/chunks/3fa5bb266a4efd0b.js +0 -1
  137. package/web/.next/static/chunks/4562ee849ea13c3a.js +0 -1
  138. package/web/.next/static/chunks/6bf868f1f2c9932a.js +0 -1
  139. package/web/.next/static/chunks/794e13829d777a43.js +0 -1
  140. /package/web/.next/static/{KhUL5DyMrZ1T6n60ZVbAZ → VBPTE7xcWBAoQkxtk58nb}/_buildManifest.js +0 -0
  141. /package/web/.next/static/{KhUL5DyMrZ1T6n60ZVbAZ → VBPTE7xcWBAoQkxtk58nb}/_clientMiddlewareManifest.json +0 -0
  142. /package/web/.next/static/{KhUL5DyMrZ1T6n60ZVbAZ → VBPTE7xcWBAoQkxtk58nb}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"activity-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,MAAM,yCAAyC,CAAC;AA4DjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC7C;AA6BD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EAAE,EAC1B,QAAQ,CAAC,EAAE,qBAAqB,EAAE,GACjC,iBAAiB,EAAE,CAgErB;AAMD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,2CAqE3F"}
1
+ {"version":3,"file":"activity-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,MAAM,yCAAyC,CAAC;AAmEjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC7C;AAmED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EAAE,EAC1B,QAAQ,CAAC,EAAE,qBAAqB,EAAE,GACjC,iBAAiB,EAAE,CAgErB;AA6BD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,gBAAgB,2CAqE3F"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useState, useEffect, useRef } from 'react';
4
- import { Loader2, AlertCircle, Clock, Zap, DollarSign } from 'lucide-react';
4
+ import { Loader2, AlertCircle, Clock, Zap, DollarSign, Play, RotateCcw, CheckCircle2, XCircle, Square, Ban, MessageSquare, Timer, } from 'lucide-react';
5
5
  import { InlineAttachments } from '../../common/inline-attachments/index.js';
6
6
  import { formatDuration } from '../../../lib/format-duration.js';
7
7
  /**
@@ -51,6 +51,13 @@ function formatTokens(count) {
51
51
  return `${(count / 1_000).toFixed(1)}K`;
52
52
  return String(count);
53
53
  }
54
+ /** Format a timestamp to a short local time string (e.g. "10:05:30 AM"). */
55
+ function formatTimestamp(value) {
56
+ const d = value instanceof Date ? value : new Date(String(value));
57
+ if (Number.isNaN(d.getTime()))
58
+ return '';
59
+ return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
60
+ }
54
61
  /** Format a USD cost with appropriate precision. */
55
62
  function formatCost(usd) {
56
63
  if (usd >= 1)
@@ -68,13 +75,48 @@ const NODE_TO_PHASE = {
68
75
  merge: 'Merging',
69
76
  };
70
77
  const LIFECYCLE_EVENTS = {
71
- 'run:started': { label: 'started', colorClass: 'text-blue-600' },
72
- 'run:resumed': { label: 'resumed', colorClass: 'text-blue-600' },
73
- 'run:completed': { label: 'completed', colorClass: 'text-emerald-600' },
74
- 'run:failed': { label: 'failed', colorClass: 'text-red-600' },
75
- 'run:stopped': { label: 'stopped', colorClass: 'text-amber-600' },
76
- 'run:crashed': { label: 'crashed', colorClass: 'text-red-600' },
77
- 'run:rejected': { label: 'rejected', colorClass: 'text-orange-600' },
78
+ 'run:started': {
79
+ label: 'started',
80
+ colorClass: 'text-blue-600',
81
+ bgClass: 'bg-blue-50 dark:bg-blue-950/30',
82
+ icon: Play,
83
+ },
84
+ 'run:resumed': {
85
+ label: 'resumed',
86
+ colorClass: 'text-blue-600',
87
+ bgClass: 'bg-blue-50 dark:bg-blue-950/30',
88
+ icon: RotateCcw,
89
+ },
90
+ 'run:completed': {
91
+ label: 'completed',
92
+ colorClass: 'text-emerald-600',
93
+ bgClass: 'bg-emerald-50 dark:bg-emerald-950/30',
94
+ icon: CheckCircle2,
95
+ },
96
+ 'run:failed': {
97
+ label: 'failed',
98
+ colorClass: 'text-red-600',
99
+ bgClass: 'bg-red-50 dark:bg-red-950/30',
100
+ icon: XCircle,
101
+ },
102
+ 'run:stopped': {
103
+ label: 'stopped',
104
+ colorClass: 'text-amber-600',
105
+ bgClass: 'bg-amber-50 dark:bg-amber-950/30',
106
+ icon: Square,
107
+ },
108
+ 'run:crashed': {
109
+ label: 'crashed',
110
+ colorClass: 'text-red-600',
111
+ bgClass: 'bg-red-50 dark:bg-red-950/30',
112
+ icon: XCircle,
113
+ },
114
+ 'run:rejected': {
115
+ label: 'rejected',
116
+ colorClass: 'text-orange-600',
117
+ bgClass: 'bg-orange-50 dark:bg-orange-950/30',
118
+ icon: Ban,
119
+ },
78
120
  };
79
121
  function isLifecycleEvent(phase) {
80
122
  return phase.startsWith('run:');
@@ -146,6 +188,26 @@ export function buildLifecycleTimeline(timings, feedback) {
146
188
  }
147
189
  return iterations;
148
190
  }
191
+ /** Determine the outcome status of an iteration */
192
+ function getIterationOutcome(iteration) {
193
+ const lastLifecycle = [...iteration.timings].reverse().find((t) => isLifecycleEvent(t.phase));
194
+ if (!lastLifecycle)
195
+ return null;
196
+ switch (lastLifecycle.phase) {
197
+ case 'run:rejected':
198
+ return { label: 'Rejected', colorClass: 'text-orange-600', dotClass: 'bg-orange-500' };
199
+ case 'run:completed':
200
+ return { label: 'Completed', colorClass: 'text-emerald-600', dotClass: 'bg-emerald-500' };
201
+ case 'run:failed':
202
+ return { label: 'Failed', colorClass: 'text-red-600', dotClass: 'bg-red-500' };
203
+ case 'run:crashed':
204
+ return { label: 'Crashed', colorClass: 'text-red-600', dotClass: 'bg-red-500' };
205
+ case 'run:stopped':
206
+ return { label: 'Stopped', colorClass: 'text-amber-600', dotClass: 'bg-amber-500' };
207
+ default:
208
+ return null;
209
+ }
210
+ }
149
211
  /* ---------------------------------------------------------------------------
150
212
  * Component
151
213
  * ------------------------------------------------------------------------- */
@@ -155,10 +217,10 @@ export function ActivityTab({ timings, loading, error, rejectionFeedback }) {
155
217
  return (_jsx("div", { "data-testid": "activity-tab-loading", className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
156
218
  }
157
219
  if (error) {
158
- return (_jsxs("div", { className: "flex items-center gap-2 p-4 text-sm text-red-600", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0" }), _jsx("span", { children: error })] }));
220
+ return (_jsxs("div", { className: "flex items-center gap-2 p-4 text-base text-red-600", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0" }), _jsx("span", { children: error })] }));
159
221
  }
160
222
  if (!timings || timings.length === 0) {
161
- return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [_jsx(Clock, { className: "text-muted-foreground h-8 w-8" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "No activity recorded yet" })] }));
223
+ return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [_jsx(Clock, { className: "text-muted-foreground h-8 w-8" }), _jsx("p", { className: "text-muted-foreground text-base", children: "No activity recorded yet" })] }));
162
224
  }
163
225
  const nodeTimings = timings.filter((t) => !isLifecycleEvent(t.phase));
164
226
  const maxDurationMs = Math.max(...nodeTimings.map((t) => getEffectiveDuration(t, now)), ...nodeTimings.map((t) => t.approvalWaitMs ?? 0), 0);
@@ -169,35 +231,36 @@ export function ActivityTab({ timings, loading, error, rejectionFeedback }) {
169
231
  const totalInputTokens = nodeTimings.reduce((sum, t) => sum + (t.inputTokens ?? 0), 0);
170
232
  const totalOutputTokens = nodeTimings.reduce((sum, t) => sum + (t.outputTokens ?? 0), 0);
171
233
  const totalCostUsd = nodeTimings.reduce((sum, t) => sum + (t.costUsd ?? 0), 0);
172
- return (_jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsx("div", { "data-testid": "activity-timings", className: "flex flex-col gap-3", children: iterations.map((iteration) => (_jsx(IterationGroup, { iteration: iteration, showHeader: hasMultipleIterations, maxDurationMs: maxDurationMs, now: now }, iteration.number))) }), totalExecMs > 0 ? (_jsx(SummaryTotals, { totalExecMs: totalExecMs, totalWaitMs: totalWaitMs, totalInputTokens: totalInputTokens, totalOutputTokens: totalOutputTokens, totalCostUsd: totalCostUsd })) : null] }));
234
+ return (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { "data-testid": "activity-timings", className: "flex flex-col gap-3", children: iterations.map((iteration) => (_jsx(IterationGroup, { iteration: iteration, showHeader: hasMultipleIterations, maxDurationMs: maxDurationMs, now: now }, iteration.number))) }), totalExecMs > 0 ? (_jsx(SummaryTotals, { totalExecMs: totalExecMs, totalWaitMs: totalWaitMs, totalInputTokens: totalInputTokens, totalOutputTokens: totalOutputTokens, totalCostUsd: totalCostUsd })) : null] }));
173
235
  }
174
236
  /* ---------------------------------------------------------------------------
175
237
  * Iteration group — one cycle of work
176
238
  * ------------------------------------------------------------------------- */
177
239
  function IterationGroup({ iteration, showHeader, maxDurationMs, now, }) {
178
- return (_jsxs("div", { "data-testid": `iteration-${iteration.number}`, className: "flex flex-col gap-1.5", children: [showHeader ? (_jsxs("div", { className: "text-muted-foreground text-xs font-medium", children: ["Iteration ", iteration.number] })) : null, iteration.timings.map((t) => {
179
- if (isLifecycleEvent(t.phase)) {
180
- // For run:rejected, the message comes from the iteration, not a separate map
181
- const isRejection = t.phase === 'run:rejected';
182
- return (_jsx(LifecycleEventRow, { timing: t, message: isRejection ? iteration.rejectionMessage : undefined, attachments: isRejection ? iteration.rejectionAttachments : undefined }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
183
- }
184
- return (_jsx(NodeTimingRow, { timing: t, maxDurationMs: maxDurationMs, now: now }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
185
- })] }));
240
+ const outcome = getIterationOutcome(iteration);
241
+ return (_jsxs("div", { "data-testid": `iteration-${iteration.number}`, className: "border-border/50 bg-card/50 flex flex-col overflow-hidden rounded-lg border", children: [showHeader ? (_jsxs("div", { className: "bg-muted/30 border-border/50 flex items-center justify-between border-b px-3 py-1.5", children: [_jsxs("span", { className: "text-muted-foreground text-sm font-semibold tracking-wide", children: ["Iteration ", iteration.number] }), outcome ? (_jsxs("span", { className: `flex items-center gap-1 text-xs font-medium ${outcome.colorClass}`, children: [_jsx("span", { className: `inline-block h-1.5 w-1.5 rounded-full ${outcome.dotClass}` }), outcome.label] })) : null] })) : null, _jsxs("div", { className: "relative flex flex-col", children: [_jsx("div", { className: "bg-border/60 absolute top-4 bottom-4 left-[21.5px] w-px" }), iteration.timings.map((t, idx) => {
242
+ if (isLifecycleEvent(t.phase)) {
243
+ const isRejection = t.phase === 'run:rejected';
244
+ return (_jsx(LifecycleEventRow, { timing: t, message: isRejection ? iteration.rejectionMessage : undefined, attachments: isRejection ? iteration.rejectionAttachments : undefined, isFirst: idx === 0, isLast: idx === iteration.timings.length - 1 }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
245
+ }
246
+ return (_jsx(NodeTimingRow, { timing: t, maxDurationMs: maxDurationMs, now: now }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
247
+ })] })] }));
186
248
  }
187
249
  /* ---------------------------------------------------------------------------
188
250
  * Row components
189
251
  * ------------------------------------------------------------------------- */
190
- function LifecycleEventRow({ timing, message, attachments, }) {
252
+ function LifecycleEventRow({ timing, message, attachments, isFirst, isLast, }) {
191
253
  const event = LIFECYCLE_EVENTS[timing.phase];
192
254
  if (!event)
193
255
  return null;
194
256
  const hasAttachments = attachments && attachments.length > 0;
195
- return (_jsxs("div", { className: `text-xs ${event.colorClass}`, children: [_jsx("span", { children: event.label }), message ? (_jsxs("span", { "data-testid": "rejection-feedback-text", className: "text-muted-foreground ml-2 font-normal italic", children: ["\u2014 ", message] })) : null, hasAttachments ? (_jsx("div", { "data-testid": "rejection-feedback-attachments", className: "mt-1.5 ml-2", children: _jsx(InlineAttachments, { text: "", attachmentPaths: attachments }) })) : null] }));
257
+ const Icon = event.icon;
258
+ return (_jsxs("div", { className: `relative flex flex-col gap-1 px-3 ${isFirst ? 'pt-2' : 'pt-1'} ${isLast ? 'pb-2' : 'pb-1'}`, children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: `relative z-10 flex h-5 w-5 shrink-0 items-center justify-center rounded-full ${event.bgClass}`, children: _jsx(Icon, { className: `h-3 w-3 ${event.colorClass}` }) }), _jsx("span", { className: `text-sm font-medium ${event.colorClass}`, children: event.label }), timing.startedAt &&
259
+ !(typeof timing.startedAt === 'string' && timing.startedAt.startsWith('synthetic')) ? (_jsx("span", { className: "text-muted-foreground/60 ml-auto text-xs tabular-nums", children: formatTimestamp(String(timing.startedAt)) })) : null] }), message ? (_jsxs("div", { className: "ml-[26px] flex items-start gap-1.5 rounded-md bg-orange-50/50 px-2 py-1.5 dark:bg-orange-950/20", children: [_jsx(MessageSquare, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-orange-400" }), _jsxs("span", { "data-testid": "rejection-feedback-text", className: "text-muted-foreground text-xs leading-relaxed italic", children: ["\u2014 ", message] })] })) : null, hasAttachments ? (_jsx("div", { "data-testid": "rejection-feedback-attachments", className: "ml-[26px]", children: _jsx(InlineAttachments, { text: "", attachmentPaths: attachments }) })) : null] }));
196
260
  }
197
261
  function NodeTimingRow({ timing, maxDurationMs, now, }) {
198
262
  const suffix = timing.phase.includes(':') ? timing.phase.split(':')[1] : null;
199
263
  const isSubPhase = suffix !== null;
200
- // Distinguish implementation sub-phases (phase-1, phase-2) from rejection retries (2, 3)
201
264
  const isImplPhase = suffix?.startsWith('phase-') ?? false;
202
265
  const label = isImplPhase
203
266
  ? `Phase ${suffix.replace('phase-', '')}`
@@ -217,17 +280,21 @@ function NodeTimingRow({ timing, maxDurationMs, now, }) {
217
280
  const totalTokens = timing.inputTokens != null || timing.outputTokens != null
218
281
  ? (timing.inputTokens ?? 0) + (timing.outputTokens ?? 0)
219
282
  : null;
220
- return (_jsxs("div", { className: isSubPhase ? 'flex flex-col gap-1 pl-6' : 'flex flex-col gap-1', children: [_jsxs("div", { "data-testid": `timing-bar-${timing.phase}`, className: "flex items-center gap-2", children: [_jsx("span", { className: `text-muted-foreground shrink-0 text-xs ${isSubPhase ? 'w-18' : 'w-24'}`, children: label }), _jsx("div", { className: `bg-muted min-w-0 flex-1 overflow-hidden rounded-full ${isSubPhase ? 'h-2.5' : 'h-3'}`, children: _jsx("div", { className: `h-full rounded-full ${barColorClass}${isRunning ? 'animate-pulse' : ''}`, style: { width: `${Math.min(barPercent, 100)}%` } }) }), _jsx("span", { className: "text-muted-foreground w-10 shrink-0 text-right text-xs tabular-nums", children: formatDuration(durationMs) }), _jsx("span", { className: "text-muted-foreground w-12 shrink-0 text-right text-[10px] tabular-nums", children: totalTokens != null && totalTokens > 0 ? (_jsxs("span", { className: "inline-flex items-center gap-0.5", children: [_jsx(Zap, { className: "h-2 w-2 opacity-50" }), formatTokens(totalTokens)] })) : null }), _jsx("span", { className: "text-muted-foreground w-14 shrink-0 text-right text-[10px] tabular-nums", children: timing.costUsd != null && timing.costUsd > 0 ? (_jsxs("span", { className: "inline-flex items-center gap-0.5", children: [_jsx(DollarSign, { className: "h-2 w-2 opacity-50" }), formatCost(timing.costUsd)] })) : null })] }), timing.approvalWaitMs != null && timing.approvalWaitMs > 0 ? (_jsx(ApprovalWaitRow, { timing: timing, maxDurationMs: maxDurationMs })) : null] }));
283
+ return (_jsxs("div", { className: `relative flex flex-col gap-0.5 px-3 py-1.5 ${isSubPhase ? 'ml-4' : ''}`, children: [_jsxs("div", { "data-testid": `timing-bar-${timing.phase}`, className: "flex items-center gap-2", children: [_jsx("div", { className: "relative z-10 flex h-5 w-5 shrink-0 items-center justify-center", children: _jsx("div", { className: `rounded-full ${isRunning ? 'h-3 w-3 animate-pulse' : 'h-2.5 w-2.5'} ${isRunning
284
+ ? 'bg-blue-500'
285
+ : timing.completedAt
286
+ ? 'bg-emerald-500'
287
+ : 'bg-muted-foreground/30'}` }) }), _jsx("span", { className: `w-28 shrink-0 truncate text-sm font-medium ${isSubPhase ? 'text-muted-foreground' : 'text-foreground/80'}`, children: label }), _jsx("div", { className: `bg-muted min-w-0 flex-1 overflow-hidden rounded-full ${isSubPhase ? 'h-1.5' : 'h-2'}`, children: _jsx("div", { className: `h-full rounded-full transition-all duration-300 ${barColorClass}${isRunning ? 'animate-pulse' : ''}`, style: { width: `${Math.min(barPercent, 100)}%` } }) }), _jsx("span", { className: "text-muted-foreground w-14 shrink-0 text-right text-sm font-medium tabular-nums", children: formatDuration(durationMs) })] }), _jsxs("div", { className: "ml-[28px] flex items-center gap-3 text-xs", children: [timing.startedAt ? (_jsx("span", { className: "text-muted-foreground/60 tabular-nums", children: formatTimestamp(timing.startedAt) })) : null, totalTokens != null && totalTokens > 0 ? (_jsxs("span", { className: "text-muted-foreground/70 inline-flex items-center gap-0.5", children: [_jsx(Zap, { className: "h-3 w-3 opacity-50" }), formatTokens(totalTokens)] })) : null, timing.costUsd != null && timing.costUsd > 0 ? (_jsxs("span", { className: "text-muted-foreground/70 inline-flex items-center gap-0.5", children: [_jsx(DollarSign, { className: "h-3 w-3 opacity-50" }), formatCost(timing.costUsd)] })) : null] }), timing.approvalWaitMs != null && timing.approvalWaitMs > 0 ? (_jsx(ApprovalWaitRow, { timing: timing, maxDurationMs: maxDurationMs })) : null] }));
221
288
  }
222
289
  function ApprovalWaitRow({ timing, maxDurationMs, }) {
223
290
  const waitMs = timing.approvalWaitMs ?? 0;
224
291
  const barPercent = maxDurationMs > 0 ? Math.max(2, (waitMs / maxDurationMs) * 100) : 2;
225
- return (_jsxs("div", { "data-testid": `approval-wait-${timing.phase}`, className: "flex items-center gap-2 pl-4", children: [_jsx("span", { className: "text-muted-foreground w-20 shrink-0 text-xs", children: "approval" }), _jsx("div", { className: "bg-muted h-2.5 min-w-0 flex-1 overflow-hidden rounded-full", children: _jsx("div", { className: "h-full rounded-full bg-amber-500", style: { width: `${Math.min(barPercent, 100)}%` } }) }), _jsx("span", { className: "text-muted-foreground w-10 shrink-0 text-right text-xs tabular-nums", children: formatDuration(waitMs) }), _jsx("span", { className: "w-12 shrink-0" }), _jsx("span", { className: "w-14 shrink-0" })] }));
292
+ return (_jsxs("div", { "data-testid": `approval-wait-${timing.phase}`, className: "ml-[26px] flex items-center gap-2 rounded-md bg-amber-50/50 px-1.5 py-1 dark:bg-amber-950/20", children: [_jsx(Timer, { className: "h-3.5 w-3.5 shrink-0 text-amber-500" }), _jsx("span", { className: "text-muted-foreground w-16 shrink-0 text-xs", children: "approval" }), _jsx("div", { className: "bg-muted h-1.5 min-w-0 flex-1 overflow-hidden rounded-full", children: _jsx("div", { className: "h-full rounded-full bg-amber-500", style: { width: `${Math.min(barPercent, 100)}%` } }) }), _jsx("span", { className: "text-muted-foreground w-14 shrink-0 text-right text-xs tabular-nums", children: formatDuration(waitMs) })] }));
226
293
  }
227
294
  function SummaryTotals({ totalExecMs, totalWaitMs, totalInputTokens, totalOutputTokens, totalCostUsd, }) {
228
295
  const totalTokens = totalInputTokens + totalOutputTokens;
229
- return (_jsxs("div", { "data-testid": "activity-summary", className: "border-border flex flex-col gap-1.5 border-t pt-3", children: [_jsx(SummaryRow, { label: "Total execution", value: formatDuration(totalExecMs) }), totalWaitMs > 0 ? (_jsxs(_Fragment, { children: [_jsx(SummaryRow, { label: "Total wait", value: formatDuration(totalWaitMs) }), _jsx(SummaryRow, { label: "Total wall-clock", value: formatDuration(totalExecMs + totalWaitMs) })] })) : null, totalTokens > 0 ? (_jsx(SummaryRow, { label: "Total tokens", value: `${formatTokens(totalTokens)} (${formatTokens(totalInputTokens)} in · ${formatTokens(totalOutputTokens)} out)` })) : null, totalCostUsd > 0 ? _jsx(SummaryRow, { label: "Total cost", value: formatCost(totalCostUsd) }) : null] }));
296
+ return (_jsxs("div", { "data-testid": "activity-summary", className: "border-border bg-card/30 flex flex-col gap-2 rounded-lg border p-3", children: [_jsx("div", { className: "text-muted-foreground mb-0.5 text-xs font-semibold tracking-wider uppercase", children: "Summary" }), _jsxs("div", { className: "grid grid-cols-2 gap-x-4 gap-y-2", children: [_jsx(SummaryItem, { icon: Clock, label: "Total execution", value: formatDuration(totalExecMs) }), totalWaitMs > 0 ? (_jsxs(_Fragment, { children: [_jsx(SummaryItem, { icon: Timer, label: "Total wait", value: formatDuration(totalWaitMs) }), _jsx(SummaryItem, { icon: Clock, label: "Total wall-clock", value: formatDuration(totalExecMs + totalWaitMs), className: "col-span-2" })] })) : null, totalTokens > 0 ? (_jsx(SummaryItem, { icon: Zap, label: "Total tokens", value: `${formatTokens(totalTokens)} (${formatTokens(totalInputTokens)} in · ${formatTokens(totalOutputTokens)} out)`, className: "col-span-2" })) : null, totalCostUsd > 0 ? (_jsx(SummaryItem, { icon: DollarSign, label: "Total cost", value: formatCost(totalCostUsd) })) : null] })] }));
230
297
  }
231
- function SummaryRow({ label, value }) {
232
- return (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: label }), _jsx("span", { className: "text-xs font-medium", children: value })] }));
298
+ function SummaryItem({ icon: Icon, label, value, className = '', }) {
299
+ return (_jsxs("div", { className: `flex items-center justify-between ${className}`, children: [_jsxs("span", { className: "text-muted-foreground flex items-center gap-1.5 text-sm", children: [_jsx(Icon, { className: "h-3.5 w-3.5 opacity-50" }), _jsx("span", { className: "font-medium", children: label })] }), _jsx("span", { className: "text-sm font-semibold tabular-nums", children: value })] }));
233
300
  }