@memberjunction/ng-conversations 6.2.0-edge.3 → 6.2.0-edge.5

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 (318) hide show
  1. package/README.md +33 -7
  2. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  3. package/dist/lib/components/collection/collection-view.component.js +1 -0
  4. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  5. package/dist/lib/components/composer/ai-composer.component.d.ts +14 -2
  6. package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
  7. package/dist/lib/components/composer/ai-composer.component.js +35 -4
  8. package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
  9. package/dist/lib/components/conversation/conversation-agent-picker.component.d.ts +1 -1
  10. package/dist/lib/components/conversation/conversation-agent-picker.component.js +3 -3
  11. package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
  12. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +651 -53
  13. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  14. package/dist/lib/components/conversation/conversation-chat-area.component.js +3002 -661
  15. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  16. package/dist/lib/components/conversation/forks-popover.component.d.ts +37 -0
  17. package/dist/lib/components/conversation/forks-popover.component.d.ts.map +1 -0
  18. package/dist/lib/components/conversation/forks-popover.component.js +164 -0
  19. package/dist/lib/components/conversation/forks-popover.component.js.map +1 -0
  20. package/dist/lib/components/export/export-modal.component.d.ts +7 -2
  21. package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
  22. package/dist/lib/components/export/export-modal.component.js +16 -3
  23. package/dist/lib/components/export/export-modal.component.js.map +1 -1
  24. package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
  25. package/dist/lib/components/message/conversation-message-rating.component.js +11 -9
  26. package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
  27. package/dist/lib/components/message/message-input.component.d.ts +96 -11
  28. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  29. package/dist/lib/components/message/message-input.component.js +253 -112
  30. package/dist/lib/components/message/message-input.component.js.map +1 -1
  31. package/dist/lib/components/message/message-item.component.d.ts +304 -16
  32. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  33. package/dist/lib/components/message/message-item.component.js +2029 -363
  34. package/dist/lib/components/message/message-item.component.js.map +1 -1
  35. package/dist/lib/components/message/message-list.component.d.ts +101 -22
  36. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  37. package/dist/lib/components/message/message-list.component.js +326 -55
  38. package/dist/lib/components/message/message-list.component.js.map +1 -1
  39. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts +34 -0
  40. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts.map +1 -0
  41. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js +75 -0
  42. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js.map +1 -0
  43. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts +80 -0
  44. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts.map +1 -0
  45. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js +202 -0
  46. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js.map +1 -0
  47. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts +45 -0
  48. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts.map +1 -0
  49. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js +123 -0
  50. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js.map +1 -0
  51. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts +90 -0
  52. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts.map +1 -0
  53. package/dist/lib/components/realtime/capture/realtime-capture-channel.js +223 -0
  54. package/dist/lib/components/realtime/capture/realtime-capture-channel.js.map +1 -0
  55. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts +98 -0
  56. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts.map +1 -0
  57. package/dist/lib/components/realtime/capture/realtime-capture-model.js +161 -0
  58. package/dist/lib/components/realtime/capture/realtime-capture-model.js.map +1 -0
  59. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts +48 -0
  60. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts.map +1 -0
  61. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js +205 -0
  62. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js.map +1 -0
  63. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +19 -2
  64. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
  65. package/dist/lib/components/realtime/channels/client-context-channel.js +83 -9
  66. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
  67. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +30 -9
  68. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
  69. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +78 -14
  70. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
  71. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts +71 -0
  72. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts.map +1 -0
  73. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js +259 -0
  74. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js.map +1 -0
  75. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts +129 -0
  76. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts.map +1 -0
  77. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js +373 -0
  78. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js.map +1 -0
  79. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts +77 -0
  80. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts.map +1 -0
  81. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js +420 -0
  82. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js.map +1 -0
  83. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts +83 -0
  84. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts.map +1 -0
  85. package/dist/lib/components/realtime/interactive-component/component-contract.js +292 -0
  86. package/dist/lib/components/realtime/interactive-component/component-contract.js.map +1 -0
  87. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts +39 -0
  88. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts.map +1 -0
  89. package/dist/lib/components/realtime/interactive-component/component-data-state.js +152 -0
  90. package/dist/lib/components/realtime/interactive-component/component-data-state.js.map +1 -0
  91. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts +109 -0
  92. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts.map +1 -0
  93. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js +146 -0
  94. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js.map +1 -0
  95. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts +19 -0
  96. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts.map +1 -0
  97. package/dist/lib/components/realtime/interactive-component/component-spec-content.js +39 -0
  98. package/dist/lib/components/realtime/interactive-component/component-spec-content.js.map +1 -0
  99. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts +183 -0
  100. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts.map +1 -0
  101. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js +761 -0
  102. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js.map +1 -0
  103. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts +25 -0
  104. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts.map +1 -0
  105. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js +57 -0
  106. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js.map +1 -0
  107. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts +40 -0
  108. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts.map +1 -0
  109. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js +97 -0
  110. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js.map +1 -0
  111. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts +144 -0
  112. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts.map +1 -0
  113. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js +57 -0
  114. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js.map +1 -0
  115. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts +36 -0
  116. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts.map +1 -0
  117. package/dist/lib/components/realtime/interactive-component/react-component-handle.js +55 -0
  118. package/dist/lib/components/realtime/interactive-component/react-component-handle.js.map +1 -0
  119. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts +55 -0
  120. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts.map +1 -0
  121. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js +210 -0
  122. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js.map +1 -0
  123. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts +32 -0
  124. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts.map +1 -0
  125. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js +90 -0
  126. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js.map +1 -0
  127. package/dist/lib/components/realtime/media/media-channel.d.ts +7 -0
  128. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
  129. package/dist/lib/components/realtime/media/media-channel.js +28 -1
  130. package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
  131. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +8 -1
  132. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  133. package/dist/lib/components/realtime/realtime-agent-banner.component.js +89 -71
  134. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  135. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts +21 -0
  136. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts.map +1 -0
  137. package/dist/lib/components/realtime/realtime-agent-orb.component.js +49 -0
  138. package/dist/lib/components/realtime/realtime-agent-orb.component.js.map +1 -0
  139. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +44 -11
  140. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
  141. package/dist/lib/components/realtime/realtime-agent-picker.component.js +162 -50
  142. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  143. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +8 -2
  144. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
  145. package/dist/lib/components/realtime/realtime-audio-visuals.js +14 -18
  146. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
  147. package/dist/lib/components/realtime/realtime-composer.component.d.ts +42 -2
  148. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  149. package/dist/lib/components/realtime/realtime-composer.component.js +137 -102
  150. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  151. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts +71 -0
  152. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts.map +1 -0
  153. package/dist/lib/components/realtime/realtime-perception-chip.component.js +221 -0
  154. package/dist/lib/components/realtime/realtime-perception-chip.component.js.map +1 -0
  155. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +264 -22
  156. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  157. package/dist/lib/components/realtime/realtime-session-overlay.component.js +851 -135
  158. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  159. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts +14 -0
  160. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts.map +1 -0
  161. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js +14 -0
  162. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js.map +1 -0
  163. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts +74 -0
  164. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts.map +1 -0
  165. package/dist/lib/components/realtime/realtime-surface-stage.model.js +171 -0
  166. package/dist/lib/components/realtime/realtime-surface-stage.model.js.map +1 -0
  167. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +71 -13
  168. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  169. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +232 -73
  170. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  171. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +5 -0
  172. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  173. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +8 -0
  174. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  175. package/dist/lib/components/realtime/realtime-ui-config.d.ts +12 -2
  176. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
  177. package/dist/lib/components/realtime/realtime-ui-config.js +5 -1
  178. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
  179. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +10 -1
  180. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
  181. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +42 -2
  182. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
  183. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +20 -3
  184. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -1
  185. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +44 -10
  186. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -1
  187. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +28 -44
  188. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
  189. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +76 -162
  190. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
  191. package/dist/lib/components/search/search-panel.component.d.ts +2 -0
  192. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  193. package/dist/lib/components/search/search-panel.component.js +25 -12
  194. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  195. package/dist/lib/components/sidebar/routines-section.component.js +1 -1
  196. package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
  197. package/dist/lib/components/task/tasks-full-view.component.d.ts +152 -31
  198. package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
  199. package/dist/lib/components/task/tasks-full-view.component.js +2227 -214
  200. package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
  201. package/dist/lib/components/tasks/tasks-dropdown.component.js +4 -4
  202. package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
  203. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +33 -32
  204. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  205. package/dist/lib/components/workspace/conversation-workspace.component.js +72 -88
  206. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  207. package/dist/lib/conversations.module.d.ts +30 -29
  208. package/dist/lib/conversations.module.d.ts.map +1 -1
  209. package/dist/lib/conversations.module.js +27 -5
  210. package/dist/lib/conversations.module.js.map +1 -1
  211. package/dist/lib/events/chat-events.d.ts +25 -0
  212. package/dist/lib/events/chat-events.d.ts.map +1 -1
  213. package/dist/lib/events/chat-events.js +36 -0
  214. package/dist/lib/events/chat-events.js.map +1 -1
  215. package/dist/lib/models/agent-turn.model.d.ts +5 -0
  216. package/dist/lib/models/agent-turn.model.d.ts.map +1 -1
  217. package/dist/lib/models/agent-turn.model.js.map +1 -1
  218. package/dist/lib/services/agent-state.service.d.ts +34 -8
  219. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  220. package/dist/lib/services/agent-state.service.js +90 -37
  221. package/dist/lib/services/agent-state.service.js.map +1 -1
  222. package/dist/lib/services/artifact-state.service.d.ts +0 -9
  223. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  224. package/dist/lib/services/artifact-state.service.js +1 -32
  225. package/dist/lib/services/artifact-state.service.js.map +1 -1
  226. package/dist/lib/services/browser-realtime-media-host.d.ts +19 -7
  227. package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -1
  228. package/dist/lib/services/browser-realtime-media-host.js +21 -72
  229. package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
  230. package/dist/lib/services/conversation-agent.service.d.ts +48 -16
  231. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  232. package/dist/lib/services/conversation-agent.service.js +110 -35
  233. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  234. package/dist/lib/services/conversation-detail-window.store.d.ts +22 -4
  235. package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
  236. package/dist/lib/services/conversation-detail-window.store.js +50 -9
  237. package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
  238. package/dist/lib/services/conversation-naming.d.ts +72 -22
  239. package/dist/lib/services/conversation-naming.d.ts.map +1 -1
  240. package/dist/lib/services/conversation-naming.js +93 -12
  241. package/dist/lib/services/conversation-naming.js.map +1 -1
  242. package/dist/lib/services/conversation-tasks-filter.d.ts +15 -0
  243. package/dist/lib/services/conversation-tasks-filter.d.ts.map +1 -0
  244. package/dist/lib/services/conversation-tasks-filter.js +69 -0
  245. package/dist/lib/services/conversation-tasks-filter.js.map +1 -0
  246. package/dist/lib/services/data-cache.service.d.ts +13 -5
  247. package/dist/lib/services/data-cache.service.d.ts.map +1 -1
  248. package/dist/lib/services/data-cache.service.js +39 -19
  249. package/dist/lib/services/data-cache.service.js.map +1 -1
  250. package/dist/lib/services/export.service.d.ts +26 -9
  251. package/dist/lib/services/export.service.d.ts.map +1 -1
  252. package/dist/lib/services/export.service.js +61 -18
  253. package/dist/lib/services/export.service.js.map +1 -1
  254. package/dist/lib/services/realtime-audio-recorder.d.ts +115 -79
  255. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
  256. package/dist/lib/services/realtime-audio-recorder.js +273 -186
  257. package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
  258. package/dist/lib/services/realtime-pairing.d.ts +10 -5
  259. package/dist/lib/services/realtime-pairing.d.ts.map +1 -1
  260. package/dist/lib/services/realtime-pairing.js +15 -6
  261. package/dist/lib/services/realtime-pairing.js.map +1 -1
  262. package/dist/lib/services/realtime-session.service.d.ts +31 -2
  263. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  264. package/dist/lib/services/realtime-session.service.js +34 -2
  265. package/dist/lib/services/realtime-session.service.js.map +1 -1
  266. package/dist/lib/services/recording/libopus-wasm-binary.d.ts +3 -0
  267. package/dist/lib/services/recording/libopus-wasm-binary.d.ts.map +1 -0
  268. package/dist/lib/services/recording/libopus-wasm-binary.js +489 -0
  269. package/dist/lib/services/recording/libopus-wasm-binary.js.map +1 -0
  270. package/dist/lib/services/recording/libopus-worker-source.d.ts +48 -0
  271. package/dist/lib/services/recording/libopus-worker-source.d.ts.map +1 -0
  272. package/dist/lib/services/recording/libopus-worker-source.js +170 -0
  273. package/dist/lib/services/recording/libopus-worker-source.js.map +1 -0
  274. package/dist/lib/services/recording/linear-resampler.d.ts +45 -0
  275. package/dist/lib/services/recording/linear-resampler.d.ts.map +1 -0
  276. package/dist/lib/services/recording/linear-resampler.js +85 -0
  277. package/dist/lib/services/recording/linear-resampler.js.map +1 -0
  278. package/dist/lib/services/recording/opus-packet-encoder.d.ts +50 -0
  279. package/dist/lib/services/recording/opus-packet-encoder.d.ts.map +1 -0
  280. package/dist/lib/services/recording/opus-packet-encoder.js +41 -0
  281. package/dist/lib/services/recording/opus-packet-encoder.js.map +1 -0
  282. package/dist/lib/services/recording/wasm-opus-encoder.d.ts +86 -0
  283. package/dist/lib/services/recording/wasm-opus-encoder.d.ts.map +1 -0
  284. package/dist/lib/services/recording/wasm-opus-encoder.js +232 -0
  285. package/dist/lib/services/recording/wasm-opus-encoder.js.map +1 -0
  286. package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts +39 -0
  287. package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts.map +1 -0
  288. package/dist/lib/services/recording/webcodecs-opus-encoder.js +101 -0
  289. package/dist/lib/services/recording/webcodecs-opus-encoder.js.map +1 -0
  290. package/dist/lib/services/search.service.d.ts +7 -2
  291. package/dist/lib/services/search.service.d.ts.map +1 -1
  292. package/dist/lib/services/search.service.js +16 -20
  293. package/dist/lib/services/search.service.js.map +1 -1
  294. package/dist/lib/utils/conversation-branching.d.ts +4 -0
  295. package/dist/lib/utils/conversation-branching.d.ts.map +1 -0
  296. package/dist/lib/utils/conversation-branching.js +5 -0
  297. package/dist/lib/utils/conversation-branching.js.map +1 -0
  298. package/dist/lib/utils/conversation-forks.d.ts +315 -0
  299. package/dist/lib/utils/conversation-forks.d.ts.map +1 -0
  300. package/dist/lib/utils/conversation-forks.js +456 -0
  301. package/dist/lib/utils/conversation-forks.js.map +1 -0
  302. package/dist/lib/utils/distinct-artifacts.d.ts +9 -3
  303. package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
  304. package/dist/lib/utils/distinct-artifacts.js +24 -5
  305. package/dist/lib/utils/distinct-artifacts.js.map +1 -1
  306. package/dist/public-api.d.ts +23 -1
  307. package/dist/public-api.d.ts.map +1 -1
  308. package/dist/public-api.js +30 -1
  309. package/dist/public-api.js.map +1 -1
  310. package/package.json +37 -33
  311. package/dist/lib/components/thread/thread-panel.component.d.ts +0 -126
  312. package/dist/lib/components/thread/thread-panel.component.d.ts.map +0 -1
  313. package/dist/lib/components/thread/thread-panel.component.js +0 -440
  314. package/dist/lib/components/thread/thread-panel.component.js.map +0 -1
  315. package/dist/lib/services/realtime-pcm-wav.d.ts +0 -79
  316. package/dist/lib/services/realtime-pcm-wav.d.ts.map +0 -1
  317. package/dist/lib/services/realtime-pcm-wav.js +0 -213
  318. package/dist/lib/services/realtime-pcm-wav.js.map +0 -1
@@ -1,50 +1,766 @@
1
- import { Component, Input, Output, EventEmitter } from '@angular/core';
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectorRef, inject } from '@angular/core';
2
+ import { FormsModule } from '@angular/forms';
2
3
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
4
  import { RunView } from '@memberjunction/core';
4
- import { TaskComponent } from '@memberjunction/ng-tasks';
5
5
  import { AIEngineBase } from '@memberjunction/ai-engine-base';
6
- import { UUIDsEqual } from '@memberjunction/global';
6
+ import { ConversationsRuntime } from '@memberjunction/conversations-runtime';
7
+ import { EscapeSQLString, ExcludeByUUIDs, IndexByUUID, UUIDsEqual, UUIDSet } from '@memberjunction/global';
7
8
  import * as i0 from "@angular/core";
8
- function TasksFullViewComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
9
- const _r1 = i0.ɵɵgetCurrentView();
10
- i0.ɵɵelementStart(0, "mj-task", 3);
11
- i0.ɵɵlistener("taskClicked", function TasksFullViewComponent_Conditional_1_Template_mj_task_taskClicked_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onTaskClick($event)); });
9
+ import * as i1 from "@angular/forms";
10
+ const _forTrack0 = ($index, $item) => $item.id;
11
+ const _forTrack1 = ($index, $item) => $item.RootTaskId;
12
+ const _forTrack2 = ($index, $item) => $item.Task.ID;
13
+ function TasksFullViewComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
14
+ i0.ɵɵelementStart(0, "span", 8);
15
+ i0.ɵɵelement(1, "span", 55);
16
+ i0.ɵɵtext(2);
12
17
  i0.ɵɵelementEnd();
13
18
  } if (rf & 2) {
14
- const ctx_r1 = i0.ɵɵnextContext();
15
- i0.ɵɵproperty("tasks", ctx_r1.filteredTasks)("title", "Tasks")("description", ctx_r1.getDescription())("showHeader", true)("showViewToggle", false)("viewMode", "simple");
19
+ const ctx_r0 = i0.ɵɵnextContext();
20
+ i0.ɵɵadvance(2);
21
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.Kpis.ActiveWorkflows, " Running Live ");
16
22
  } }
17
- function TasksFullViewComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
23
+ function TasksFullViewComponent_Conditional_86_Template(rf, ctx) { if (rf & 1) {
24
+ const _r2 = i0.ɵɵgetCurrentView();
25
+ i0.ɵɵelementStart(0, "button", 56);
26
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_86_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.ClearSearch()); });
27
+ i0.ɵɵelement(1, "i", 57);
28
+ i0.ɵɵelementEnd();
29
+ } }
30
+ function TasksFullViewComponent_Conditional_111_For_6_Template(rf, ctx) { if (rf & 1) {
31
+ i0.ɵɵelementStart(0, "option", 61);
32
+ i0.ɵɵtext(1);
33
+ i0.ɵɵelementEnd();
34
+ } if (rf & 2) {
35
+ const ag_r4 = ctx.$implicit;
36
+ i0.ɵɵproperty("value", ag_r4.id);
37
+ i0.ɵɵadvance();
38
+ i0.ɵɵtextInterpolate2("", ag_r4.name, " (", ag_r4.count, ")");
39
+ } }
40
+ function TasksFullViewComponent_Conditional_111_Template(rf, ctx) { if (rf & 1) {
18
41
  const _r3 = i0.ɵɵgetCurrentView();
19
- i0.ɵɵelementStart(0, "div", 4)(1, "div", 5)(2, "button", 6);
20
- i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.backToTaskList()); });
21
- i0.ɵɵelement(3, "i", 7);
22
- i0.ɵɵelementStart(4, "span");
23
- i0.ɵɵtext(5, "Back to Tasks");
42
+ i0.ɵɵelementStart(0, "div", 48);
43
+ i0.ɵɵelement(1, "i", 58);
44
+ i0.ɵɵelementStart(2, "select", 59);
45
+ i0.ɵɵlistener("ngModelChange", function TasksFullViewComponent_Conditional_111_Template_select_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.SetAgentFilter($event)); });
46
+ i0.ɵɵelementStart(3, "option", 60);
47
+ i0.ɵɵtext(4);
48
+ i0.ɵɵelementEnd();
49
+ i0.ɵɵrepeaterCreate(5, TasksFullViewComponent_Conditional_111_For_6_Template, 2, 3, "option", 61, _forTrack0);
24
50
  i0.ɵɵelementEnd()();
25
- i0.ɵɵelementStart(6, "div", 8);
26
- i0.ɵɵtext(7, "/");
51
+ } if (rf & 2) {
52
+ const ctx_r0 = i0.ɵɵnextContext();
53
+ i0.ɵɵadvance(2);
54
+ i0.ɵɵproperty("ngModel", ctx_r0.SelectedAgentFilter);
55
+ i0.ɵɵadvance(2);
56
+ i0.ɵɵtextInterpolate1("All Specialist Agents (", ctx_r0.AvailableAgents.length, ")");
57
+ i0.ɵɵadvance();
58
+ i0.ɵɵrepeater(ctx_r0.AvailableAgents);
59
+ } }
60
+ function TasksFullViewComponent_Conditional_114_Template(rf, ctx) { if (rf & 1) {
61
+ i0.ɵɵelementStart(0, "div", 51)(1, "div", 62);
62
+ i0.ɵɵelement(2, "i", 63);
27
63
  i0.ɵɵelementEnd();
28
- i0.ɵɵelementStart(8, "span", 9);
29
- i0.ɵɵtext(9);
64
+ i0.ɵɵelementStart(3, "h3");
65
+ i0.ɵɵtext(4, "Loading AI Agent Workflows...");
66
+ i0.ɵɵelementEnd();
67
+ i0.ɵɵelementStart(5, "p");
68
+ i0.ɵɵtext(6, "Fetching orchestrated task graphs, specialist agent steps, and execution telemetry.");
30
69
  i0.ɵɵelementEnd()();
31
- i0.ɵɵelementStart(10, "mj-task", 10);
32
- i0.ɵɵlistener("taskClicked", function TasksFullViewComponent_Conditional_2_Template_mj_task_taskClicked_10_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSubTaskClick($event)); })("openEntityRecord", function TasksFullViewComponent_Conditional_2_Template_mj_task_openEntityRecord_10_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onOpenEntityRecord($event)); });
70
+ } }
71
+ function TasksFullViewComponent_Conditional_115_Conditional_3_Template(rf, ctx) { if (rf & 1) {
72
+ i0.ɵɵelementStart(0, "h3");
73
+ i0.ɵɵtext(1, "No Agent Workflows Recorded Yet");
74
+ i0.ɵɵelementEnd();
75
+ i0.ɵɵelementStart(2, "p");
76
+ i0.ɵɵtext(3, "When Sage or other orchestrator agents launch multi-step task graphs in Chat, their live progress, specialist delegations, and outputs will appear here.");
77
+ i0.ɵɵelementEnd();
78
+ } }
79
+ function TasksFullViewComponent_Conditional_115_Conditional_4_Template(rf, ctx) { if (rf & 1) {
80
+ const _r5 = i0.ɵɵgetCurrentView();
81
+ i0.ɵɵelementStart(0, "h3");
82
+ i0.ɵɵtext(1, "No Workflows Match Your Filters");
83
+ i0.ɵɵelementEnd();
84
+ i0.ɵɵelementStart(2, "p");
85
+ i0.ɵɵtext(3, "Try clearing your search query or switching the status / specialist agent filter.");
86
+ i0.ɵɵelementEnd();
87
+ i0.ɵɵelementStart(4, "button", 64);
88
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_115_Conditional_4_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.ResetAllFilters()); });
89
+ i0.ɵɵelement(5, "i", 65);
90
+ i0.ɵɵelementStart(6, "span");
91
+ i0.ɵɵtext(7, "Reset Filters");
92
+ i0.ɵɵelementEnd()();
93
+ } }
94
+ function TasksFullViewComponent_Conditional_115_Template(rf, ctx) { if (rf & 1) {
95
+ i0.ɵɵelementStart(0, "div", 51)(1, "div", 62);
96
+ i0.ɵɵelement(2, "i", 4);
97
+ i0.ɵɵelementEnd();
98
+ i0.ɵɵconditionalCreate(3, TasksFullViewComponent_Conditional_115_Conditional_3_Template, 4, 0)(4, TasksFullViewComponent_Conditional_115_Conditional_4_Template, 8, 0);
99
+ i0.ɵɵelementEnd();
100
+ } if (rf & 2) {
101
+ const ctx_r0 = i0.ɵɵnextContext();
102
+ i0.ɵɵadvance(3);
103
+ i0.ɵɵconditional(ctx_r0.WorkflowGroups.length === 0 ? 3 : 4);
104
+ } }
105
+ function TasksFullViewComponent_Conditional_116_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
106
+ i0.ɵɵelement(0, "i", 71);
107
+ } }
108
+ function TasksFullViewComponent_Conditional_116_For_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
109
+ i0.ɵɵelement(0, "i", 63);
110
+ } }
111
+ function TasksFullViewComponent_Conditional_116_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
112
+ i0.ɵɵelement(0, "i", 72);
113
+ } }
114
+ function TasksFullViewComponent_Conditional_116_For_2_Conditional_15_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
115
+ i0.ɵɵelement(0, "i", 92);
116
+ } }
117
+ function TasksFullViewComponent_Conditional_116_For_2_Conditional_15_For_2_Template(rf, ctx) { if (rf & 1) {
118
+ const _r8 = i0.ɵɵgetCurrentView();
119
+ i0.ɵɵelementStart(0, "button", 90);
120
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_116_For_2_Conditional_15_For_2_Template_button_click_0_listener($event) { const ag_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.OnAgentChipClicked($event, ag_r9.id)); });
121
+ i0.ɵɵelement(1, "i", 91);
122
+ i0.ɵɵelementStart(2, "span");
123
+ i0.ɵɵtext(3);
33
124
  i0.ɵɵelementEnd()();
125
+ i0.ɵɵconditionalCreate(4, TasksFullViewComponent_Conditional_116_For_2_Conditional_15_For_2_Conditional_4_Template, 1, 0, "i", 92);
34
126
  } if (rf & 2) {
35
- const ctx_r1 = i0.ɵɵnextContext();
36
- i0.ɵɵclassProp("swoosh-in", ctx_r1.showDetailAnimation);
127
+ const ag_r9 = ctx.$implicit;
128
+ const ɵ$index_298_r10 = ctx.$index;
129
+ const ɵ$count_298_r11 = ctx.$count;
130
+ i0.ɵɵproperty("title", i0.ɵɵinterpolate1("Inspect ", ag_r9.name));
131
+ i0.ɵɵadvance(3);
132
+ i0.ɵɵtextInterpolate(ag_r9.name);
133
+ i0.ɵɵadvance();
134
+ i0.ɵɵconditional(!(ɵ$index_298_r10 === ɵ$count_298_r11 - 1) ? 4 : -1);
135
+ } }
136
+ function TasksFullViewComponent_Conditional_116_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
137
+ i0.ɵɵelementStart(0, "div", 78);
138
+ i0.ɵɵrepeaterCreate(1, TasksFullViewComponent_Conditional_116_For_2_Conditional_15_For_2_Template, 5, 4, null, null, _forTrack0);
139
+ i0.ɵɵelementEnd();
140
+ } if (rf & 2) {
141
+ const group_r7 = i0.ɵɵnextContext().$implicit;
142
+ i0.ɵɵadvance();
143
+ i0.ɵɵrepeater(group_r7.AgentPipeline);
144
+ } }
145
+ function TasksFullViewComponent_Conditional_116_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
146
+ i0.ɵɵelementStart(0, "span", 80);
147
+ i0.ɵɵelement(1, "i", 93);
148
+ i0.ɵɵtext(2);
149
+ i0.ɵɵelementEnd();
150
+ } if (rf & 2) {
151
+ const group_r7 = i0.ɵɵnextContext().$implicit;
152
+ i0.ɵɵadvance(2);
153
+ i0.ɵɵtextInterpolate1(" ", group_r7.DurationText, " ");
154
+ } }
155
+ function TasksFullViewComponent_Conditional_116_For_2_Conditional_29_Template(rf, ctx) { if (rf & 1) {
156
+ i0.ɵɵtext(0);
157
+ } if (rf & 2) {
158
+ const group_r7 = i0.ɵɵnextContext().$implicit;
159
+ i0.ɵɵtextInterpolate1(" \u00B7 ", group_r7.SkippedSteps, " skipped ");
160
+ } }
161
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_2_Template(rf, ctx) { if (rf & 1) {
162
+ i0.ɵɵelement(0, "i", 71);
163
+ } }
164
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_3_Template(rf, ctx) { if (rf & 1) {
165
+ i0.ɵɵelement(0, "i", 96);
166
+ } }
167
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_4_Template(rf, ctx) { if (rf & 1) {
168
+ i0.ɵɵelement(0, "i", 97);
169
+ } }
170
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_5_Template(rf, ctx) { if (rf & 1) {
171
+ i0.ɵɵelement(0, "i", 57);
172
+ } }
173
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_6_Template(rf, ctx) { if (rf & 1) {
174
+ i0.ɵɵelementStart(0, "span");
175
+ i0.ɵɵtext(1);
176
+ i0.ɵɵelementEnd();
177
+ } if (rf & 2) {
178
+ const step_r13 = i0.ɵɵnextContext().$implicit;
179
+ i0.ɵɵadvance();
180
+ i0.ɵɵtextInterpolate(step_r13.StepNumber);
181
+ } }
182
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_11_Template(rf, ctx) { if (rf & 1) {
183
+ i0.ɵɵelementStart(0, "span", 101);
184
+ i0.ɵɵelement(1, "i", 91);
185
+ i0.ɵɵtext(2);
186
+ i0.ɵɵelementEnd();
187
+ } if (rf & 2) {
188
+ const step_r13 = i0.ɵɵnextContext().$implicit;
189
+ i0.ɵɵadvance(2);
190
+ i0.ɵɵtextInterpolate1(" ", step_r13.AgentName, " ");
191
+ } }
192
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_12_Template(rf, ctx) { if (rf & 1) {
193
+ i0.ɵɵelementStart(0, "span", 102);
194
+ i0.ɵɵelement(1, "i", 108);
195
+ i0.ɵɵtext(2);
196
+ i0.ɵɵelementEnd();
197
+ } if (rf & 2) {
198
+ const step_r13 = i0.ɵɵnextContext().$implicit;
199
+ i0.ɵɵproperty("title", i0.ɵɵinterpolate1("Waits for: ", step_r13.DependsOnNames.join(", ")));
200
+ i0.ɵɵadvance(2);
201
+ i0.ɵɵtextInterpolate1(" After ", step_r13.DependsOnNames.join(", "), " ");
202
+ } }
203
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_13_Template(rf, ctx) { if (rf & 1) {
204
+ i0.ɵɵelementStart(0, "p", 109);
205
+ i0.ɵɵtext(1);
206
+ i0.ɵɵelementEnd();
207
+ } if (rf & 2) {
208
+ const step_r13 = i0.ɵɵnextContext().$implicit;
209
+ i0.ɵɵclassProp("preview-error", step_r13.IsErrorOutput);
210
+ i0.ɵɵadvance();
211
+ i0.ɵɵtextInterpolate1(" ", step_r13.OutputPreview, " ");
212
+ } }
213
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_15_Template(rf, ctx) { if (rf & 1) {
214
+ i0.ɵɵelementStart(0, "span", 105);
215
+ i0.ɵɵtext(1);
216
+ i0.ɵɵelementEnd();
217
+ } if (rf & 2) {
218
+ const step_r13 = i0.ɵɵnextContext().$implicit;
219
+ i0.ɵɵadvance();
220
+ i0.ɵɵtextInterpolate(step_r13.DurationText);
221
+ } }
222
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_18_Template(rf, ctx) { if (rf & 1) {
223
+ const _r14 = i0.ɵɵgetCurrentView();
224
+ i0.ɵɵelementStart(0, "button", 110);
225
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_18_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r14); const step_r13 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.OnOpenAgentRunClicked($event, step_r13.AgentRunID)); });
226
+ i0.ɵɵelement(1, "i", 111);
227
+ i0.ɵɵelementEnd();
228
+ } }
229
+ function TasksFullViewComponent_Conditional_116_For_2_For_33_Template(rf, ctx) { if (rf & 1) {
230
+ const _r12 = i0.ɵɵgetCurrentView();
231
+ i0.ɵɵelementStart(0, "div", 94);
232
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_116_For_2_For_33_Template_div_click_0_listener($event) { const step_r13 = i0.ɵɵrestoreView(_r12).$implicit; const group_r7 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.InspectWorkflowGroup(group_r7, step_r13, $event)); });
233
+ i0.ɵɵelementStart(1, "div", 95);
234
+ i0.ɵɵconditionalCreate(2, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_2_Template, 1, 0, "i", 71)(3, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_3_Template, 1, 0, "i", 96)(4, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_4_Template, 1, 0, "i", 97)(5, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_5_Template, 1, 0, "i", 57)(6, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_6_Template, 2, 1, "span");
235
+ i0.ɵɵelementEnd();
236
+ i0.ɵɵelementStart(7, "div", 98)(8, "div", 99)(9, "span", 100);
237
+ i0.ɵɵtext(10);
238
+ i0.ɵɵelementEnd();
239
+ i0.ɵɵconditionalCreate(11, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_11_Template, 3, 1, "span", 101);
240
+ i0.ɵɵconditionalCreate(12, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_12_Template, 3, 3, "span", 102);
241
+ i0.ɵɵelementEnd();
242
+ i0.ɵɵconditionalCreate(13, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_13_Template, 2, 3, "p", 103);
243
+ i0.ɵɵelementEnd();
244
+ i0.ɵɵelementStart(14, "div", 104);
245
+ i0.ɵɵconditionalCreate(15, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_15_Template, 2, 1, "span", 105);
246
+ i0.ɵɵelementStart(16, "span", 106);
247
+ i0.ɵɵtext(17);
248
+ i0.ɵɵelementEnd();
249
+ i0.ɵɵconditionalCreate(18, TasksFullViewComponent_Conditional_116_For_2_For_33_Conditional_18_Template, 2, 0, "button", 107);
250
+ i0.ɵɵelementEnd()();
251
+ } if (rf & 2) {
252
+ const step_r13 = ctx.$implicit;
253
+ const ctx_r0 = i0.ɵɵnextContext(3);
254
+ i0.ɵɵclassProp("step-selected", ctx_r0.IsStepInspected(step_r13.Task));
255
+ i0.ɵɵattribute("data-status", ctx_r0.GetStepCategory(step_r13.Task.Status));
256
+ i0.ɵɵadvance();
257
+ i0.ɵɵattribute("data-status", ctx_r0.GetStepCategory(step_r13.Task.Status));
258
+ i0.ɵɵadvance();
259
+ i0.ɵɵconditional(step_r13.Task.Status === "Complete" ? 2 : step_r13.Task.Status === "In Progress" ? 3 : step_r13.Task.Status === "Skipped" ? 4 : step_r13.Task.Status === "Failed" || step_r13.Task.Status === "Cancelled" ? 5 : 6);
260
+ i0.ɵɵadvance(8);
261
+ i0.ɵɵtextInterpolate(step_r13.Task.Name);
262
+ i0.ɵɵadvance();
263
+ i0.ɵɵconditional(step_r13.AgentName ? 11 : -1);
264
+ i0.ɵɵadvance();
265
+ i0.ɵɵconditional(step_r13.DependsOnNames.length > 0 ? 12 : -1);
266
+ i0.ɵɵadvance();
267
+ i0.ɵɵconditional(step_r13.OutputPreview ? 13 : -1);
268
+ i0.ɵɵadvance(2);
269
+ i0.ɵɵconditional(step_r13.DurationText ? 15 : -1);
270
+ i0.ɵɵadvance();
271
+ i0.ɵɵattribute("data-status", ctx_r0.GetStepCategory(step_r13.Task.Status));
272
+ i0.ɵɵadvance();
273
+ i0.ɵɵtextInterpolate1(" ", step_r13.Task.Status, " ");
274
+ i0.ɵɵadvance();
275
+ i0.ɵɵconditional(step_r13.AgentRunID ? 18 : -1);
276
+ } }
277
+ function TasksFullViewComponent_Conditional_116_For_2_Template(rf, ctx) { if (rf & 1) {
278
+ const _r6 = i0.ɵɵgetCurrentView();
279
+ i0.ɵɵelementStart(0, "article", 67);
280
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_116_For_2_Template_article_click_0_listener() { const group_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.InspectWorkflowGroup(group_r7)); });
281
+ i0.ɵɵelementStart(1, "div", 68)(2, "div", 69)(3, "div", 70);
282
+ i0.ɵɵconditionalCreate(4, TasksFullViewComponent_Conditional_116_For_2_Conditional_4_Template, 1, 0, "i", 71)(5, TasksFullViewComponent_Conditional_116_For_2_Conditional_5_Template, 1, 0, "i", 63)(6, TasksFullViewComponent_Conditional_116_For_2_Conditional_6_Template, 1, 0, "i", 72);
283
+ i0.ɵɵelementEnd();
284
+ i0.ɵɵelementStart(7, "div", 73)(8, "div", 74)(9, "h3", 75);
285
+ i0.ɵɵtext(10);
286
+ i0.ɵɵelementEnd();
287
+ i0.ɵɵelementStart(11, "span", 76);
288
+ i0.ɵɵtext(12);
289
+ i0.ɵɵelementEnd();
290
+ i0.ɵɵelementStart(13, "span", 77);
291
+ i0.ɵɵtext(14);
292
+ i0.ɵɵelementEnd()();
293
+ i0.ɵɵconditionalCreate(15, TasksFullViewComponent_Conditional_116_For_2_Conditional_15_Template, 3, 0, "div", 78);
294
+ i0.ɵɵelementEnd()();
295
+ i0.ɵɵelementStart(16, "div", 79);
296
+ i0.ɵɵconditionalCreate(17, TasksFullViewComponent_Conditional_116_For_2_Conditional_17_Template, 3, 1, "span", 80);
297
+ i0.ɵɵelementStart(18, "span", 81);
298
+ i0.ɵɵtext(19);
299
+ i0.ɵɵelementEnd();
300
+ i0.ɵɵelementStart(20, "button", 82);
301
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_116_For_2_Template_button_click_20_listener($event) { const group_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.InspectWorkflowGroup(group_r7, undefined, $event)); });
302
+ i0.ɵɵelementStart(21, "span");
303
+ i0.ɵɵtext(22, "Inspect");
304
+ i0.ɵɵelementEnd();
305
+ i0.ɵɵelement(23, "i", 83);
306
+ i0.ɵɵelementEnd()()();
307
+ i0.ɵɵelementStart(24, "div", 84)(25, "div", 85);
308
+ i0.ɵɵelement(26, "div", 86);
309
+ i0.ɵɵelementEnd();
310
+ i0.ɵɵelementStart(27, "span", 87);
311
+ i0.ɵɵtext(28);
312
+ i0.ɵɵconditionalCreate(29, TasksFullViewComponent_Conditional_116_For_2_Conditional_29_Template, 1, 1);
313
+ i0.ɵɵtext(30);
314
+ i0.ɵɵelementEnd()();
315
+ i0.ɵɵelementStart(31, "div", 88);
316
+ i0.ɵɵrepeaterCreate(32, TasksFullViewComponent_Conditional_116_For_2_For_33_Template, 19, 13, "div", 89, _forTrack2);
317
+ i0.ɵɵelementEnd()();
318
+ } if (rf & 2) {
319
+ const group_r7 = ctx.$implicit;
320
+ const ctx_r0 = i0.ɵɵnextContext(2);
321
+ i0.ɵɵclassProp("card-active", group_r7.NormalizedCategory === "active")("card-completed", group_r7.NormalizedCategory === "completed")("card-failed", group_r7.NormalizedCategory === "failed")("card-selected", ctx_r0.IsGroupInspected(group_r7));
322
+ i0.ɵɵadvance(3);
323
+ i0.ɵɵattribute("data-status", group_r7.NormalizedCategory);
324
+ i0.ɵɵadvance();
325
+ i0.ɵɵconditional(group_r7.NormalizedCategory === "completed" ? 4 : group_r7.NormalizedCategory === "active" ? 5 : 6);
326
+ i0.ɵɵadvance(6);
327
+ i0.ɵɵtextInterpolate(group_r7.Title);
328
+ i0.ɵɵadvance(2);
329
+ i0.ɵɵtextInterpolate2(" ", group_r7.TotalSteps, " ", group_r7.TotalSteps === 1 ? "Step" : "Steps", " ");
330
+ i0.ɵɵadvance();
331
+ i0.ɵɵattribute("data-status", group_r7.NormalizedCategory);
332
+ i0.ɵɵadvance();
333
+ i0.ɵɵtextInterpolate1(" ", group_r7.Status, " ");
334
+ i0.ɵɵadvance();
335
+ i0.ɵɵconditional(group_r7.AgentPipeline.length > 0 ? 15 : -1);
336
+ i0.ɵɵadvance(2);
337
+ i0.ɵɵconditional(group_r7.DurationText ? 17 : -1);
338
+ i0.ɵɵadvance(2);
339
+ i0.ɵɵtextInterpolate(group_r7.RelativeTimeText);
340
+ i0.ɵɵadvance(7);
341
+ i0.ɵɵstyleProp("width", group_r7.PercentComplete, "%");
342
+ i0.ɵɵattribute("data-status", group_r7.NormalizedCategory);
343
+ i0.ɵɵadvance(2);
344
+ i0.ɵɵtextInterpolate2(" ", group_r7.CompletedSteps, " of ", group_r7.TotalSteps, " completed ");
345
+ i0.ɵɵadvance();
346
+ i0.ɵɵconditional(group_r7.SkippedSteps > 0 ? 29 : -1);
347
+ i0.ɵɵadvance();
348
+ i0.ɵɵtextInterpolate1(" \u00B7 ", group_r7.PercentComplete, "% ");
349
+ i0.ɵɵadvance(2);
350
+ i0.ɵɵrepeater(group_r7.Steps);
351
+ } }
352
+ function TasksFullViewComponent_Conditional_116_Template(rf, ctx) { if (rf & 1) {
353
+ i0.ɵɵelementStart(0, "div", 52);
354
+ i0.ɵɵrepeaterCreate(1, TasksFullViewComponent_Conditional_116_For_2_Template, 34, 25, "article", 66, _forTrack1);
355
+ i0.ɵɵelementEnd();
356
+ } if (rf & 2) {
357
+ const ctx_r0 = i0.ɵɵnextContext();
358
+ i0.ɵɵadvance();
359
+ i0.ɵɵrepeater(ctx_r0.FilteredWorkflowGroups);
360
+ } }
361
+ function TasksFullViewComponent_Conditional_117_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
362
+ i0.ɵɵelementStart(0, "span", 117);
363
+ i0.ɵɵelement(1, "i", 33);
364
+ i0.ɵɵtext(2);
365
+ i0.ɵɵelementEnd();
366
+ } if (rf & 2) {
367
+ const group_r16 = i0.ɵɵnextContext().$implicit;
368
+ i0.ɵɵadvance(2);
369
+ i0.ɵɵtextInterpolate1(" Total: ", group_r16.DurationText, " ");
370
+ } }
371
+ function TasksFullViewComponent_Conditional_117_For_2_For_23_Conditional_7_Template(rf, ctx) { if (rf & 1) {
372
+ i0.ɵɵelementStart(0, "span", 126);
373
+ i0.ɵɵelement(1, "i", 131);
374
+ i0.ɵɵtext(2);
375
+ i0.ɵɵelementEnd();
376
+ } if (rf & 2) {
377
+ const step_r18 = i0.ɵɵnextContext().$implicit;
378
+ i0.ɵɵadvance(2);
379
+ i0.ɵɵtextInterpolate1(" Depends on: ", step_r18.DependsOnNames.join(", "), " ");
380
+ } }
381
+ function TasksFullViewComponent_Conditional_117_For_2_For_23_Conditional_9_Template(rf, ctx) { if (rf & 1) {
382
+ i0.ɵɵelementStart(0, "span", 101);
383
+ i0.ɵɵelement(1, "i", 91);
384
+ i0.ɵɵtext(2);
385
+ i0.ɵɵelementEnd();
386
+ } if (rf & 2) {
387
+ const step_r18 = i0.ɵɵnextContext().$implicit;
388
+ i0.ɵɵadvance(2);
389
+ i0.ɵɵtextInterpolate1(" ", step_r18.AgentName, " ");
390
+ } }
391
+ function TasksFullViewComponent_Conditional_117_For_2_For_23_Conditional_10_Template(rf, ctx) { if (rf & 1) {
392
+ i0.ɵɵelementStart(0, "span", 127);
393
+ i0.ɵɵtext(1, "Orchestrator");
394
+ i0.ɵɵelementEnd();
395
+ } }
396
+ function TasksFullViewComponent_Conditional_117_For_2_For_23_Template(rf, ctx) { if (rf & 1) {
397
+ const _r17 = i0.ɵɵgetCurrentView();
398
+ i0.ɵɵelementStart(0, "div", 124);
399
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_117_For_2_For_23_Template_div_click_0_listener($event) { const step_r18 = i0.ɵɵrestoreView(_r17).$implicit; const group_r16 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.InspectWorkflowGroup(group_r16, step_r18, $event)); });
400
+ i0.ɵɵelementStart(1, "div", 120)(2, "span", 95);
401
+ i0.ɵɵtext(3);
402
+ i0.ɵɵelementEnd();
403
+ i0.ɵɵelementStart(4, "div", 125)(5, "span", 100);
404
+ i0.ɵɵtext(6);
405
+ i0.ɵɵelementEnd();
406
+ i0.ɵɵconditionalCreate(7, TasksFullViewComponent_Conditional_117_For_2_For_23_Conditional_7_Template, 3, 1, "span", 126);
407
+ i0.ɵɵelementEnd()();
408
+ i0.ɵɵelementStart(8, "div", 121);
409
+ i0.ɵɵconditionalCreate(9, TasksFullViewComponent_Conditional_117_For_2_For_23_Conditional_9_Template, 3, 1, "span", 101)(10, TasksFullViewComponent_Conditional_117_For_2_For_23_Conditional_10_Template, 2, 0, "span", 127);
410
+ i0.ɵɵelementEnd();
411
+ i0.ɵɵelementStart(11, "div", 122)(12, "div", 128)(13, "div", 129)(14, "span", 130);
412
+ i0.ɵɵtext(15);
413
+ i0.ɵɵelementEnd()()()()();
414
+ } if (rf & 2) {
415
+ const step_r18 = ctx.$implicit;
416
+ const ctx_r0 = i0.ɵɵnextContext(3);
417
+ i0.ɵɵclassProp("step-selected", ctx_r0.IsStepInspected(step_r18.Task));
418
+ i0.ɵɵadvance(2);
419
+ i0.ɵɵattribute("data-status", ctx_r0.GetStepCategory(step_r18.Task.Status));
420
+ i0.ɵɵadvance();
421
+ i0.ɵɵtextInterpolate1(" ", step_r18.StepNumber, " ");
422
+ i0.ɵɵadvance(3);
423
+ i0.ɵɵtextInterpolate(step_r18.Task.Name);
424
+ i0.ɵɵadvance();
425
+ i0.ɵɵconditional(step_r18.DependsOnNames.length > 0 ? 7 : -1);
426
+ i0.ɵɵadvance(2);
427
+ i0.ɵɵconditional(step_r18.AgentName ? 9 : 10);
428
+ i0.ɵɵadvance(4);
429
+ i0.ɵɵstyleProp("left", step_r18.TimelineOffsetPercent, "%")("width", step_r18.TimelineWidthPercent, "%");
430
+ i0.ɵɵattribute("data-status", ctx_r0.GetStepCategory(step_r18.Task.Status));
431
+ i0.ɵɵadvance(2);
432
+ i0.ɵɵtextInterpolate2(" ", step_r18.StartOffsetLabel, " \u00B7 ", step_r18.DurationText || step_r18.Task.Status, " ");
433
+ } }
434
+ function TasksFullViewComponent_Conditional_117_For_2_Template(rf, ctx) { if (rf & 1) {
435
+ const _r15 = i0.ɵɵgetCurrentView();
436
+ i0.ɵɵelementStart(0, "section", 113)(1, "div", 114);
437
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_117_For_2_Template_div_click_1_listener() { const group_r16 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.InspectWorkflowGroup(group_r16)); });
438
+ i0.ɵɵelementStart(2, "div", 115)(3, "span", 77);
439
+ i0.ɵɵtext(4);
440
+ i0.ɵɵelementEnd();
441
+ i0.ɵɵelementStart(5, "h3", 75);
442
+ i0.ɵɵtext(6);
443
+ i0.ɵɵelementEnd();
444
+ i0.ɵɵelementStart(7, "span", 76);
445
+ i0.ɵɵtext(8);
446
+ i0.ɵɵelementEnd()();
447
+ i0.ɵɵelementStart(9, "div", 116);
448
+ i0.ɵɵconditionalCreate(10, TasksFullViewComponent_Conditional_117_For_2_Conditional_10_Template, 3, 1, "span", 117);
449
+ i0.ɵɵelementStart(11, "span", 81);
450
+ i0.ɵɵtext(12);
451
+ i0.ɵɵelementEnd()()();
452
+ i0.ɵɵelementStart(13, "div", 118)(14, "div", 119)(15, "div", 120);
453
+ i0.ɵɵtext(16, "Workflow Step & Dependencies");
454
+ i0.ɵɵelementEnd();
455
+ i0.ɵɵelementStart(17, "div", 121);
456
+ i0.ɵɵtext(18, "Specialist Agent");
457
+ i0.ɵɵelementEnd();
458
+ i0.ɵɵelementStart(19, "div", 122)(20, "span");
459
+ i0.ɵɵtext(21);
460
+ i0.ɵɵelementEnd()()();
461
+ i0.ɵɵrepeaterCreate(22, TasksFullViewComponent_Conditional_117_For_2_For_23_Template, 16, 14, "div", 123, _forTrack2);
462
+ i0.ɵɵelementEnd()();
463
+ } if (rf & 2) {
464
+ const group_r16 = ctx.$implicit;
465
+ const ctx_r0 = i0.ɵɵnextContext(2);
466
+ i0.ɵɵclassProp("card-selected", ctx_r0.IsGroupInspected(group_r16));
467
+ i0.ɵɵadvance(3);
468
+ i0.ɵɵattribute("data-status", group_r16.NormalizedCategory);
469
+ i0.ɵɵadvance();
470
+ i0.ɵɵtextInterpolate1(" ", group_r16.Status, " ");
471
+ i0.ɵɵadvance(2);
472
+ i0.ɵɵtextInterpolate(group_r16.Title);
473
+ i0.ɵɵadvance(2);
474
+ i0.ɵɵtextInterpolate1("", group_r16.TotalSteps, " Steps");
475
+ i0.ɵɵadvance(2);
476
+ i0.ɵɵconditional(group_r16.DurationText ? 10 : -1);
477
+ i0.ɵɵadvance(2);
478
+ i0.ɵɵtextInterpolate(group_r16.RelativeTimeText);
37
479
  i0.ɵɵadvance(9);
38
- i0.ɵɵtextInterpolate(ctx_r1.selectedTask.Name);
480
+ i0.ɵɵtextInterpolate1("Execution Waterfall (0s \u2192 ", group_r16.DurationText || "Live", ")");
481
+ i0.ɵɵadvance();
482
+ i0.ɵɵrepeater(group_r16.Steps);
483
+ } }
484
+ function TasksFullViewComponent_Conditional_117_Template(rf, ctx) { if (rf & 1) {
485
+ i0.ɵɵelementStart(0, "div", 53);
486
+ i0.ɵɵrepeaterCreate(1, TasksFullViewComponent_Conditional_117_For_2_Template, 24, 9, "section", 112, _forTrack1);
487
+ i0.ɵɵelementEnd();
488
+ } if (rf & 2) {
489
+ const ctx_r0 = i0.ɵɵnextContext();
490
+ i0.ɵɵadvance();
491
+ i0.ɵɵrepeater(ctx_r0.FilteredWorkflowGroups);
492
+ } }
493
+ function TasksFullViewComponent_Conditional_118_Conditional_10_For_2_Template(rf, ctx) { if (rf & 1) {
494
+ const _r20 = i0.ɵɵgetCurrentView();
495
+ i0.ɵɵelementStart(0, "button", 141);
496
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_118_Conditional_10_For_2_Template_button_click_0_listener() { const s_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.SelectInspectorStep(s_r21)); });
497
+ i0.ɵɵelementStart(1, "span", 142);
498
+ i0.ɵɵtext(2);
499
+ i0.ɵɵelementEnd();
500
+ i0.ɵɵelementStart(3, "span", 143);
501
+ i0.ɵɵtext(4);
502
+ i0.ɵɵelementEnd()();
503
+ } if (rf & 2) {
504
+ const s_r21 = ctx.$implicit;
505
+ const ctx_r0 = i0.ɵɵnextContext(3);
506
+ i0.ɵɵclassProp("active", ctx_r0.IsStepInspected(s_r21.Task));
507
+ i0.ɵɵadvance(2);
508
+ i0.ɵɵtextInterpolate(s_r21.StepNumber);
509
+ i0.ɵɵadvance(2);
510
+ i0.ɵɵtextInterpolate(s_r21.Task.Name);
511
+ } }
512
+ function TasksFullViewComponent_Conditional_118_Conditional_10_Template(rf, ctx) { if (rf & 1) {
513
+ i0.ɵɵelementStart(0, "div", 138);
514
+ i0.ɵɵrepeaterCreate(1, TasksFullViewComponent_Conditional_118_Conditional_10_For_2_Template, 5, 4, "button", 140, _forTrack2);
515
+ i0.ɵɵelementEnd();
516
+ } if (rf & 2) {
517
+ const ctx_r0 = i0.ɵɵnextContext(2);
518
+ i0.ɵɵadvance();
519
+ i0.ɵɵrepeater(ctx_r0.InspectedGroup.Steps);
520
+ } }
521
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_22_Template(rf, ctx) { if (rf & 1) {
522
+ const _r22 = i0.ɵɵgetCurrentView();
523
+ i0.ɵɵelementStart(0, "button", 156);
524
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_22_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r22); const activeStep_r23 = i0.ɵɵnextContext(); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnAgentChipClicked($event, activeStep_r23.AgentID)); });
525
+ i0.ɵɵelementStart(1, "div", 157);
526
+ i0.ɵɵelement(2, "i", 91);
527
+ i0.ɵɵelementEnd();
528
+ i0.ɵɵelementStart(3, "div", 158)(4, "span", 159);
529
+ i0.ɵɵtext(5, "Assigned Specialist Agent");
530
+ i0.ɵɵelementEnd();
531
+ i0.ɵɵelementStart(6, "span", 160);
532
+ i0.ɵɵtext(7);
533
+ i0.ɵɵelementEnd()();
534
+ i0.ɵɵelement(8, "i", 161);
535
+ i0.ɵɵelementEnd();
536
+ } if (rf & 2) {
537
+ const activeStep_r23 = i0.ɵɵnextContext();
538
+ i0.ɵɵadvance(7);
539
+ i0.ɵɵtextInterpolate(activeStep_r23.AgentName);
540
+ } }
541
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_23_Template(rf, ctx) { if (rf & 1) {
542
+ const _r24 = i0.ɵɵgetCurrentView();
543
+ i0.ɵɵelementStart(0, "button", 156);
544
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_23_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r24); const activeStep_r23 = i0.ɵɵnextContext(); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnOpenAgentRunClicked($event, activeStep_r23.AgentRunID)); });
545
+ i0.ɵɵelementStart(1, "div", 162);
546
+ i0.ɵɵelement(2, "i", 163);
547
+ i0.ɵɵelementEnd();
548
+ i0.ɵɵelementStart(3, "div", 158)(4, "span", 159);
549
+ i0.ɵɵtext(5, "AI Agent Run Trace");
550
+ i0.ɵɵelementEnd();
551
+ i0.ɵɵelementStart(6, "span", 160);
552
+ i0.ɵɵtext(7, "Open Full Step & Prompt Run Log");
553
+ i0.ɵɵelementEnd()();
554
+ i0.ɵɵelement(8, "i", 161);
555
+ i0.ɵɵelementEnd();
556
+ } }
557
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_24_For_5_Template(rf, ctx) { if (rf & 1) {
558
+ i0.ɵɵelementStart(0, "span", 165);
559
+ i0.ɵɵelement(1, "i", 166);
560
+ i0.ɵɵtext(2);
561
+ i0.ɵɵelementEnd();
562
+ } if (rf & 2) {
563
+ const depName_r25 = ctx.$implicit;
564
+ i0.ɵɵadvance(2);
565
+ i0.ɵɵtextInterpolate1(" ", depName_r25, " ");
566
+ } }
567
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_24_For_7_Template(rf, ctx) { if (rf & 1) {
568
+ i0.ɵɵelementStart(0, "span", 165);
569
+ i0.ɵɵelement(1, "i", 167);
570
+ i0.ɵɵtext(2);
571
+ i0.ɵɵelementEnd();
572
+ } if (rf & 2) {
573
+ const cond_r26 = ctx.$implicit;
574
+ i0.ɵɵadvance(2);
575
+ i0.ɵɵtextInterpolate1(" if ", cond_r26, " ");
576
+ } }
577
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_24_Template(rf, ctx) { if (rf & 1) {
578
+ i0.ɵɵelementStart(0, "div", 150)(1, "h4", 151);
579
+ i0.ɵɵtext(2, "Prerequisite Dependencies");
580
+ i0.ɵɵelementEnd();
581
+ i0.ɵɵelementStart(3, "div", 164);
582
+ i0.ɵɵrepeaterCreate(4, TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_24_For_5_Template, 3, 1, "span", 165, i0.ɵɵrepeaterTrackByIdentity);
583
+ i0.ɵɵrepeaterCreate(6, TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_24_For_7_Template, 3, 1, "span", 165, i0.ɵɵrepeaterTrackByIdentity);
584
+ i0.ɵɵelementEnd()();
585
+ } if (rf & 2) {
586
+ const activeStep_r23 = i0.ɵɵnextContext();
587
+ i0.ɵɵadvance(4);
588
+ i0.ɵɵrepeater(activeStep_r23.DependsOnNames);
589
+ i0.ɵɵadvance(2);
590
+ i0.ɵɵrepeater(activeStep_r23.DependsOnConditions);
591
+ } }
592
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_29_Template(rf, ctx) { if (rf & 1) {
593
+ i0.ɵɵelementStart(0, "div", 155)(1, "span", 168);
594
+ i0.ɵɵtext(2, "Started");
595
+ i0.ɵɵelementEnd();
596
+ i0.ɵɵelementStart(3, "span", 169);
597
+ i0.ɵɵtext(4);
598
+ i0.ɵɵelementEnd()();
599
+ } if (rf & 2) {
600
+ const activeStep_r23 = i0.ɵɵnextContext();
601
+ const ctx_r0 = i0.ɵɵnextContext(2);
602
+ i0.ɵɵadvance(4);
603
+ i0.ɵɵtextInterpolate(ctx_r0.FormatDateTime(activeStep_r23.Task.StartedAt));
604
+ } }
605
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_30_Template(rf, ctx) { if (rf & 1) {
606
+ i0.ɵɵelementStart(0, "div", 155)(1, "span", 168);
607
+ i0.ɵɵtext(2, "Completed");
608
+ i0.ɵɵelementEnd();
609
+ i0.ɵɵelementStart(3, "span", 169);
610
+ i0.ɵɵtext(4);
611
+ i0.ɵɵelementEnd()();
612
+ } if (rf & 2) {
613
+ const activeStep_r23 = i0.ɵɵnextContext();
614
+ const ctx_r0 = i0.ɵɵnextContext(2);
615
+ i0.ɵɵadvance(4);
616
+ i0.ɵɵtextInterpolate(ctx_r0.FormatDateTime(activeStep_r23.Task.CompletedAt));
617
+ } }
618
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_31_Template(rf, ctx) { if (rf & 1) {
619
+ i0.ɵɵelementStart(0, "div", 150)(1, "h4", 151);
620
+ i0.ɵɵtext(2, "Step Instructions");
621
+ i0.ɵɵelementEnd();
622
+ i0.ɵɵelementStart(3, "div", 170);
623
+ i0.ɵɵtext(4);
624
+ i0.ɵɵelementEnd()();
625
+ } if (rf & 2) {
626
+ const activeStep_r23 = i0.ɵɵnextContext();
627
+ i0.ɵɵadvance(4);
628
+ i0.ɵɵtextInterpolate(activeStep_r23.Instructions);
629
+ } }
630
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_32_Template(rf, ctx) { if (rf & 1) {
631
+ const _r27 = i0.ɵɵgetCurrentView();
632
+ i0.ɵɵelementStart(0, "div", 150)(1, "div", 171)(2, "h4", 151);
633
+ i0.ɵɵtext(3);
634
+ i0.ɵɵelementEnd();
635
+ i0.ɵɵelementStart(4, "button", 172);
636
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_32_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r27); const activeStep_r23 = i0.ɵɵnextContext(); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.CopyStepOutput(activeStep_r23.Output)); });
637
+ i0.ɵɵelement(5, "i", 173);
638
+ i0.ɵɵelementStart(6, "span");
639
+ i0.ɵɵtext(7);
640
+ i0.ɵɵelementEnd()()();
641
+ i0.ɵɵelementStart(8, "div", 174);
642
+ i0.ɵɵtext(9);
643
+ i0.ɵɵelementEnd()();
644
+ } if (rf & 2) {
645
+ const activeStep_r23 = i0.ɵɵnextContext();
646
+ const ctx_r0 = i0.ɵɵnextContext(2);
647
+ i0.ɵɵadvance(3);
648
+ i0.ɵɵtextInterpolate1(" ", activeStep_r23.IsErrorOutput ? "Error Diagnostics" : "Specialist Agent Output", " ");
649
+ i0.ɵɵadvance(2);
650
+ i0.ɵɵclassProp("fa-copy", !ctx_r0.CopiedOutput)("fa-check", ctx_r0.CopiedOutput);
651
+ i0.ɵɵadvance(2);
652
+ i0.ɵɵtextInterpolate(ctx_r0.CopiedOutput ? "Copied" : "Copy");
653
+ i0.ɵɵadvance();
654
+ i0.ɵɵclassProp("output-error", activeStep_r23.IsErrorOutput);
655
+ i0.ɵɵadvance();
656
+ i0.ɵɵtextInterpolate(activeStep_r23.Output);
657
+ } }
658
+ function TasksFullViewComponent_Conditional_118_Conditional_12_Template(rf, ctx) { if (rf & 1) {
659
+ i0.ɵɵelementStart(0, "div", 144)(1, "div", 145)(2, "span", 146);
660
+ i0.ɵɵtext(3, "Status");
661
+ i0.ɵɵelementEnd();
662
+ i0.ɵɵelementStart(4, "span", 77);
663
+ i0.ɵɵtext(5);
664
+ i0.ɵɵelementEnd()();
665
+ i0.ɵɵelementStart(6, "div", 145)(7, "span", 146);
666
+ i0.ɵɵtext(8, "Duration");
667
+ i0.ɵɵelementEnd();
668
+ i0.ɵɵelementStart(9, "span", 147);
669
+ i0.ɵɵtext(10);
670
+ i0.ɵɵelementEnd()();
671
+ i0.ɵɵelementStart(11, "div", 145)(12, "span", 146);
672
+ i0.ɵɵtext(13, "Completion");
673
+ i0.ɵɵelementEnd();
674
+ i0.ɵɵelementStart(14, "span", 147);
675
+ i0.ɵɵtext(15);
676
+ i0.ɵɵelementEnd()()();
677
+ i0.ɵɵelementStart(16, "div", 148);
678
+ i0.ɵɵelement(17, "div", 149);
679
+ i0.ɵɵelementEnd();
680
+ i0.ɵɵelementStart(18, "div", 150)(19, "h4", 151);
681
+ i0.ɵɵtext(20, "Execution & Telemetry Links");
682
+ i0.ɵɵelementEnd();
683
+ i0.ɵɵelementStart(21, "div", 152);
684
+ i0.ɵɵconditionalCreate(22, TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_22_Template, 9, 1, "button", 153);
685
+ i0.ɵɵconditionalCreate(23, TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_23_Template, 9, 0, "button", 153);
686
+ i0.ɵɵelementEnd()();
687
+ i0.ɵɵconditionalCreate(24, TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_24_Template, 8, 0, "div", 150);
688
+ i0.ɵɵelementStart(25, "div", 150)(26, "h4", 151);
689
+ i0.ɵɵtext(27, "Timeline");
690
+ i0.ɵɵelementEnd();
691
+ i0.ɵɵelementStart(28, "div", 154);
692
+ i0.ɵɵconditionalCreate(29, TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_29_Template, 5, 1, "div", 155);
693
+ i0.ɵɵconditionalCreate(30, TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_30_Template, 5, 1, "div", 155);
694
+ i0.ɵɵelementEnd()();
695
+ i0.ɵɵconditionalCreate(31, TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_31_Template, 5, 1, "div", 150);
696
+ i0.ɵɵconditionalCreate(32, TasksFullViewComponent_Conditional_118_Conditional_12_Conditional_32_Template, 10, 9, "div", 150);
697
+ } if (rf & 2) {
698
+ const activeStep_r23 = ctx;
699
+ const ctx_r0 = i0.ɵɵnextContext(2);
700
+ i0.ɵɵadvance(4);
701
+ i0.ɵɵattribute("data-status", ctx_r0.GetStepCategory(activeStep_r23.Task.Status));
702
+ i0.ɵɵadvance();
703
+ i0.ɵɵtextInterpolate1(" ", activeStep_r23.Task.Status, " ");
704
+ i0.ɵɵadvance(5);
705
+ i0.ɵɵtextInterpolate(activeStep_r23.DurationText || "\u2014");
706
+ i0.ɵɵadvance(5);
707
+ i0.ɵɵtextInterpolate1("", activeStep_r23.Task.PercentComplete ?? 0, "%");
708
+ i0.ɵɵadvance(2);
709
+ i0.ɵɵstyleProp("width", activeStep_r23.Task.PercentComplete ?? 0, "%");
710
+ i0.ɵɵattribute("data-status", ctx_r0.GetStepCategory(activeStep_r23.Task.Status));
711
+ i0.ɵɵadvance(5);
712
+ i0.ɵɵconditional(activeStep_r23.AgentID && activeStep_r23.AgentName ? 22 : -1);
713
+ i0.ɵɵadvance();
714
+ i0.ɵɵconditional(activeStep_r23.AgentRunID ? 23 : -1);
715
+ i0.ɵɵadvance();
716
+ i0.ɵɵconditional(activeStep_r23.DependsOnNames.length > 0 ? 24 : -1);
717
+ i0.ɵɵadvance(5);
718
+ i0.ɵɵconditional(activeStep_r23.Task.StartedAt ? 29 : -1);
719
+ i0.ɵɵadvance();
720
+ i0.ɵɵconditional(activeStep_r23.Task.CompletedAt ? 30 : -1);
39
721
  i0.ɵɵadvance();
40
- i0.ɵɵproperty("tasks", ctx_r1.subTasks)("ganttTasks", ctx_r1.subTasksWithParent)("taskDependencies", ctx_r1.taskDependencies)("agentRunMap", ctx_r1.agentRunMap)("title", ctx_r1.selectedTask.Name)("description", ctx_r1.getTaskDetailDescription())("showHeader", true)("showViewToggle", true)("viewMode", "gantt");
722
+ i0.ɵɵconditional(activeStep_r23.Instructions ? 31 : -1);
723
+ i0.ɵɵadvance();
724
+ i0.ɵɵconditional(activeStep_r23.Output ? 32 : -1);
725
+ } }
726
+ function TasksFullViewComponent_Conditional_118_Template(rf, ctx) { if (rf & 1) {
727
+ const _r19 = i0.ɵɵgetCurrentView();
728
+ i0.ɵɵelementStart(0, "aside", 54)(1, "div", 132)(2, "div", 133)(3, "span", 134);
729
+ i0.ɵɵelement(4, "i", 135);
730
+ i0.ɵɵtext(5);
731
+ i0.ɵɵelementEnd();
732
+ i0.ɵɵelementStart(6, "button", 136);
733
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Conditional_118_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.BackToTaskList()); });
734
+ i0.ɵɵelement(7, "i", 57);
735
+ i0.ɵɵelementEnd()();
736
+ i0.ɵɵelementStart(8, "h2", 137);
737
+ i0.ɵɵtext(9);
738
+ i0.ɵɵelementEnd();
739
+ i0.ɵɵconditionalCreate(10, TasksFullViewComponent_Conditional_118_Conditional_10_Template, 3, 0, "div", 138);
740
+ i0.ɵɵelementEnd();
741
+ i0.ɵɵelementStart(11, "div", 139);
742
+ i0.ɵɵconditionalCreate(12, TasksFullViewComponent_Conditional_118_Conditional_12_Template, 33, 14);
743
+ i0.ɵɵelementEnd()();
744
+ } if (rf & 2) {
745
+ let tmp_4_0;
746
+ const ctx_r0 = i0.ɵɵnextContext();
747
+ i0.ɵɵadvance(5);
748
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.InspectedStep ? "Step " + ctx_r0.InspectedStep.StepNumber + " of " + ctx_r0.InspectedGroup.TotalSteps : "Workflow Overview", " ");
749
+ i0.ɵɵadvance(4);
750
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.InspectedStep ? ctx_r0.InspectedStep.Task.Name : ctx_r0.InspectedGroup.Title, " ");
751
+ i0.ɵɵadvance();
752
+ i0.ɵɵconditional(ctx_r0.InspectedGroup.Steps.length > 1 ? 10 : -1);
753
+ i0.ɵɵadvance(2);
754
+ i0.ɵɵconditional((tmp_4_0 = ctx_r0.InspectedStep) ? 12 : -1, tmp_4_0);
41
755
  } }
42
756
  /**
43
- * Full-page tasks view with task list and Gantt chart
44
- * Generic component that displays tasks based on provided filter
45
- * Supports drilling into individual tasks to see sub-tasks
757
+ * AI Agent Workflows & Tasks Command Center (`mj-tasks-full-view`).
758
+ *
759
+ * Provides a hierarchy-aware, real-time command center for monitoring and inspecting
760
+ * multi-agent task graphs and durable background agent executions launched from conversations.
46
761
  */
47
762
  export class TasksFullViewComponent extends BaseAngularComponent {
763
+ cdr = inject(ChangeDetectorRef, { optional: true });
48
764
  EnvironmentId;
49
765
  /** @deprecated Use {@link EnvironmentId}. */
50
766
  set environmentId(value) {
@@ -71,7 +787,12 @@ export class TasksFullViewComponent extends BaseAngularComponent {
71
787
  /** @deprecated Use {@link BaseFilter}. */
72
788
  get baseFilter() {
73
789
  return this.BaseFilter;
74
- } // SQL filter for tasks (default: show all)
790
+ }
791
+ /**
792
+ * Builds the task filter each time the view loads or refreshes, so the list includes tasks
793
+ * created since the last load. Replaces {@link BaseFilter} when set.
794
+ */
795
+ BaseFilterResolver = null;
75
796
  ActiveTaskId;
76
797
  /** @deprecated Use {@link ActiveTaskId}. */
77
798
  set activeTaskId(value) {
@@ -80,25 +801,13 @@ export class TasksFullViewComponent extends BaseAngularComponent {
80
801
  /** @deprecated Use {@link ActiveTaskId}. */
81
802
  get activeTaskId() {
82
803
  return this.ActiveTaskId;
83
- } // Task ID to auto-select and drill into
804
+ }
84
805
  OpenEntityRecord = new EventEmitter();
85
- /**
86
- * @deprecated Use {@link OpenEntityRecord}.
87
- *
88
- * The same emitter under the old binding name, so a template still binding
89
- * (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields
90
- * initialise in order, and the other way round this captures undefined.
91
- */
806
+ /** @deprecated Use {@link OpenEntityRecord}. */
92
807
  openEntityRecord = this.OpenEntityRecord;
93
808
  TaskSelected = new EventEmitter();
94
- /**
95
- * @deprecated Use {@link TaskSelected}.
96
- *
97
- * The same emitter under the old binding name, so a template still binding
98
- * (taskSelected) keeps working. Must stay AFTER TaskSelected: class fields
99
- * initialise in order, and the other way round this captures undefined.
100
- */
101
- taskSelected = this.TaskSelected; // Emits task ID when drill-down occurs, null when returning to list
809
+ /** @deprecated Use {@link TaskSelected}. */
810
+ taskSelected = this.TaskSelected;
102
811
  AllTasks = [];
103
812
  /** @deprecated Use {@link AllTasks}. */
104
813
  get allTasks() {
@@ -134,7 +843,7 @@ export class TasksFullViewComponent extends BaseAngularComponent {
134
843
  /** @deprecated Use {@link SubTasksWithParent}. */
135
844
  set subTasksWithParent(value) {
136
845
  this.SubTasksWithParent = value;
137
- } // Includes parent for Gantt hierarchy
846
+ }
138
847
  TaskDependencies = [];
139
848
  /** @deprecated Use {@link TaskDependencies}. */
140
849
  get taskDependencies() {
@@ -143,7 +852,7 @@ export class TasksFullViewComponent extends BaseAngularComponent {
143
852
  /** @deprecated Use {@link TaskDependencies}. */
144
853
  set taskDependencies(value) {
145
854
  this.TaskDependencies = value;
146
- } // Dependencies for Gantt links
855
+ }
147
856
  AgentRunMap = new Map();
148
857
  /** @deprecated Use {@link AgentRunMap}. */
149
858
  get agentRunMap() {
@@ -152,7 +861,7 @@ export class TasksFullViewComponent extends BaseAngularComponent {
152
861
  /** @deprecated Use {@link AgentRunMap}. */
153
862
  set agentRunMap(value) {
154
863
  this.AgentRunMap = value;
155
- } // Maps TaskID -> AgentRunID
864
+ }
156
865
  SelectedTask = null;
157
866
  /** @deprecated Use {@link SelectedTask}. */
158
867
  get selectedTask() {
@@ -173,185 +882,537 @@ export class TasksFullViewComponent extends BaseAngularComponent {
173
882
  }
174
883
  isLoading = false;
175
884
  aiEngineConfigured = false;
885
+ // Command Center state
886
+ CommandViewMode = 'workflows';
887
+ StatusFilter = 'all';
888
+ SearchQuery = '';
889
+ SelectedAgentFilter = 'all';
890
+ WorkflowGroups = [];
891
+ FilteredWorkflowGroups = [];
892
+ AvailableAgents = [];
893
+ InspectedGroup = null;
894
+ InspectedStep = null;
895
+ CopiedOutput = false;
896
+ Kpis = {
897
+ TotalWorkflows: 0,
898
+ TotalSteps: 0,
899
+ ActiveWorkflows: 0,
900
+ CompletedSteps: 0,
901
+ SuccessRatePercent: 100,
902
+ AvgExecutionTimeText: '—'
903
+ };
904
+ allHierarchyTasks = [];
905
+ streamSubscription = null;
906
+ livePollTimer = null;
176
907
  ngOnInit() {
177
908
  this.LoadTasks();
909
+ this.setupLiveTaskGraphSubscription();
178
910
  }
179
911
  ngOnChanges(changes) {
180
- // Reload tasks if baseFilter changes
181
- if (changes['baseFilter'] && !changes['baseFilter'].firstChange) {
912
+ const filterChanged = (key) => !!changes[key] && !changes[key].firstChange;
913
+ if (filterChanged('baseFilter') || filterChanged('BaseFilter') || filterChanged('BaseFilterResolver')) {
182
914
  this.LoadTasks();
183
915
  }
184
- // Auto-drill into task if activeTaskId changes
185
- if (changes['activeTaskId'] && this.ActiveTaskId) {
186
- const task = this.AllTasks.find(t => UUIDsEqual(t.ID, this.ActiveTaskId));
187
- if (task) {
188
- this.OnTaskClick(task);
916
+ if ((changes['activeTaskId'] || changes['ActiveTaskId']) && this.ActiveTaskId) {
917
+ this.selectTaskById(this.ActiveTaskId);
918
+ }
919
+ }
920
+ ngOnDestroy() {
921
+ if (this.streamSubscription) {
922
+ this.streamSubscription.unsubscribe();
923
+ this.streamSubscription = null;
924
+ }
925
+ this.stopLivePolling();
926
+ }
927
+ setupLiveTaskGraphSubscription() {
928
+ try {
929
+ const runtime = ConversationsRuntime.Instance;
930
+ if (runtime?.Streaming?.TaskGraphEvents$) {
931
+ this.streamSubscription = runtime.Streaming.TaskGraphEvents$.subscribe(() => {
932
+ void this.LoadTasks();
933
+ });
189
934
  }
190
935
  }
936
+ catch {
937
+ // Safe no-op in isolated test contexts
938
+ }
939
+ }
940
+ updateLivePollingState() {
941
+ const hasActive = this.WorkflowGroups.some(g => g.NormalizedCategory === 'active');
942
+ if (hasActive && !this.livePollTimer) {
943
+ this.livePollTimer = setInterval(() => {
944
+ void this.LoadTasks();
945
+ }, 4000);
946
+ }
947
+ else if (!hasActive && this.livePollTimer) {
948
+ this.stopLivePolling();
949
+ }
950
+ }
951
+ stopLivePolling() {
952
+ if (this.livePollTimer) {
953
+ clearInterval(this.livePollTimer);
954
+ this.livePollTimer = null;
955
+ }
191
956
  }
192
957
  async LoadTasks() {
193
958
  this.isLoading = true;
194
959
  try {
195
- // Configure AIEngineBase on first load (false = don't force refresh)
196
960
  if (!this.aiEngineConfigured) {
197
961
  await AIEngineBase.Instance.Config(false);
198
962
  this.aiEngineConfigured = true;
199
963
  }
200
964
  const rv = RunView.FromMetadataProvider(this.ProviderToUse);
201
- console.log('📝 Tasks filter SQL:', this.BaseFilter);
202
- // Load all tasks with the provided filter
965
+ const filter = this.BaseFilterResolver ? await this.BaseFilterResolver() : this.BaseFilter;
203
966
  const tasksResult = await rv.RunView({
204
967
  EntityName: 'MJ: Tasks',
205
- ExtraFilter: this.BaseFilter,
968
+ ExtraFilter: filter,
206
969
  OrderBy: '__mj_CreatedAt DESC',
207
970
  MaxRows: 1000,
208
- ResultType: 'entity_object'
971
+ ResultType: 'entity_object',
972
+ BypassCache: true
209
973
  }, this.CurrentUser);
210
- console.log('📊 Tasks query result:', {
211
- success: tasksResult.Success,
212
- resultCount: tasksResult.Results?.length || 0,
213
- errorMessage: tasksResult.ErrorMessage
214
- });
215
974
  if (tasksResult.Success) {
216
975
  this.AllTasks = tasksResult.Results || [];
217
976
  this.FilteredTasks = this.AllTasks;
218
- console.log(`📋 Loaded ${this.AllTasks.length} tasks`);
219
- if (this.AllTasks.length === 0) {
220
- console.log('💡 No tasks found with current filter');
221
- }
222
- else {
223
- console.log('✅ Sample task:', {
224
- id: this.AllTasks[0].ID,
225
- name: this.AllTasks[0].Name,
226
- status: this.AllTasks[0].Status,
227
- conversationDetailID: this.AllTasks[0].ConversationDetailID
228
- });
229
- }
977
+ await this.loadChildTasksAndDependencies(rv, this.AllTasks);
978
+ this.rebuildWorkflowCommandCenter();
230
979
  }
231
980
  else {
232
- console.error('❌ Failed to load tasks:', tasksResult.ErrorMessage);
233
981
  this.AllTasks = [];
234
982
  this.FilteredTasks = [];
983
+ this.allHierarchyTasks = [];
984
+ this.WorkflowGroups = [];
985
+ this.FilteredWorkflowGroups = [];
235
986
  }
236
987
  }
237
988
  catch (error) {
238
989
  console.error('Failed to load tasks:', error);
239
990
  this.AllTasks = [];
240
991
  this.FilteredTasks = [];
992
+ this.allHierarchyTasks = [];
993
+ this.WorkflowGroups = [];
994
+ this.FilteredWorkflowGroups = [];
241
995
  }
242
996
  finally {
243
997
  this.isLoading = false;
998
+ this.updateLivePollingState();
999
+ this.cdr?.markForCheck();
244
1000
  }
245
1001
  }
246
1002
  /** @deprecated Use {@link LoadTasks}. */
247
1003
  async loadTasks() {
248
1004
  return this.LoadTasks();
249
1005
  }
250
- async OnTaskClick(task) {
251
- console.log('Task clicked:', task);
252
- this.SelectedTask = task;
253
- this.ShowDetailAnimation = true;
254
- // Emit task selection event for URL tracking
255
- this.TaskSelected.emit(task.ID);
256
- // Load all tasks in the hierarchy using RootParentID
257
- await this.loadTaskHierarchy(task);
258
- }
259
- /** @deprecated Use {@link OnTaskClick}. */
260
- async onTaskClick(task) {
261
- return this.OnTaskClick(task);
262
- }
263
- async loadTaskHierarchy(task) {
264
- try {
265
- const rv = RunView.FromMetadataProvider(this.ProviderToUse);
266
- // Use RootParentID to load all tasks in this hierarchy
267
- // If task has no RootParentID, it's the root itself, so use its ID
268
- const rootId = task.RootParentID || task.ID;
269
- // Load all tasks where RootParentID matches, or tasks that are the root itself
270
- const hierarchyResult = await rv.RunView({
271
- EntityName: 'MJ: Tasks',
272
- ExtraFilter: `RootParentID='${rootId}' OR ID='${rootId}'`,
273
- OrderBy: '__mj_CreatedAt ASC',
274
- MaxRows: 1000,
275
- ResultType: 'entity_object'
276
- }, this.CurrentUser);
277
- if (hierarchyResult.Success) {
278
- const allHierarchy = hierarchyResult.Results || [];
279
- // For list view: Filter out the clicked task itself - only show its children/descendants
280
- this.SubTasks = allHierarchy.filter(t => !UUIDsEqual(t.ID, task.ID));
281
- // For Gantt view: Include the parent task so hierarchy works correctly
282
- this.SubTasksWithParent = allHierarchy;
283
- console.log(`📋 Loaded ${this.SubTasks.length} tasks in hierarchy for root ${rootId}`);
284
- // Load task dependencies for this hierarchy
285
- await this.loadTaskDependencies(rootId);
286
- // Load agent runs for this hierarchy
287
- this.loadAgentRuns(allHierarchy);
288
- }
289
- else {
290
- console.error('❌ Failed to load task hierarchy:', hierarchyResult.ErrorMessage);
291
- this.SubTasks = [];
292
- this.SubTasksWithParent = [];
293
- this.TaskDependencies = [];
1006
+ /**
1007
+ * Ensures child step tasks and dependencies are loaded even when the primary filter
1008
+ * scopes to top-level (`ParentID IS NULL`) tasks.
1009
+ */
1010
+ async loadChildTasksAndDependencies(rv, primaryTasks) {
1011
+ const mergedMap = new Map();
1012
+ for (const t of primaryTasks) {
1013
+ if (t?.ID) {
1014
+ mergedMap.set(t.ID.toLowerCase(), t);
294
1015
  }
295
1016
  }
296
- catch (error) {
297
- console.error('Failed to load task hierarchy:', error);
298
- this.SubTasks = [];
1017
+ const rootIds = Array.from(new Set(primaryTasks
1018
+ .map(t => t.RootParentID || t.ParentID || t.ID)
1019
+ .filter((id) => Boolean(id))));
1020
+ if (rootIds.length > 0) {
1021
+ const quotedIds = rootIds.map(id => `'${EscapeSQLString(id)}'`).join(',');
1022
+ try {
1023
+ const childrenResult = await rv.RunView({
1024
+ EntityName: 'MJ: Tasks',
1025
+ ExtraFilter: `ParentID IN (${quotedIds}) OR RootParentID IN (${quotedIds})`,
1026
+ OrderBy: '__mj_CreatedAt ASC',
1027
+ MaxRows: 1000,
1028
+ ResultType: 'entity_object',
1029
+ BypassCache: true
1030
+ }, this.CurrentUser);
1031
+ if (childrenResult.Success && childrenResult.Results) {
1032
+ for (const child of childrenResult.Results) {
1033
+ if (child?.ID && !mergedMap.has(child.ID.toLowerCase())) {
1034
+ mergedMap.set(child.ID.toLowerCase(), child);
1035
+ }
1036
+ }
1037
+ }
1038
+ }
1039
+ catch {
1040
+ // Fallback to primaryTasks when running against minimal unit-test fake providers
1041
+ }
1042
+ const allTaskIds = Array.from(mergedMap.values())
1043
+ .map(t => t.ID)
1044
+ .filter((id) => Boolean(id));
1045
+ if (allTaskIds.length > 0) {
1046
+ const quotedAllIds = allTaskIds.slice(0, 300).map(id => `'${EscapeSQLString(id)}'`).join(',');
1047
+ try {
1048
+ const depsResult = await rv.RunView({
1049
+ EntityName: 'MJ: Task Dependencies',
1050
+ ExtraFilter: `TaskID IN (${quotedAllIds}) OR DependsOnTaskID IN (${quotedAllIds})`,
1051
+ ResultType: 'entity_object'
1052
+ }, this.CurrentUser);
1053
+ if (depsResult.Success && depsResult.Results) {
1054
+ this.TaskDependencies = depsResult.Results;
1055
+ }
1056
+ }
1057
+ catch {
1058
+ // Optional dependency enrichment
1059
+ }
1060
+ }
299
1061
  }
1062
+ this.allHierarchyTasks = Array.from(mergedMap.values());
1063
+ this.loadAgentRuns(this.allHierarchyTasks);
300
1064
  }
301
- async loadTaskDependencies(rootId) {
302
- try {
303
- const rv = RunView.FromMetadataProvider(this.ProviderToUse);
304
- // Load task dependencies where either TaskID or DependsOnTaskID is in this hierarchy
305
- // Use subquery to find all tasks with this RootParentID
306
- // Note: Using __mj as the default schema - this is the standard MJ schema
307
- const schema = '__mj';
308
- const depsResult = await rv.RunView({
309
- EntityName: 'MJ: Task Dependencies',
310
- ExtraFilter: `
311
- TaskID IN (SELECT ID FROM [${schema}].[vwTasks] WHERE RootParentID='${rootId}' OR ID='${rootId}')
312
- OR
313
- DependsOnTaskID IN (SELECT ID FROM [${schema}].[vwTasks] WHERE RootParentID='${rootId}' OR ID='${rootId}')
314
- `,
315
- ResultType: 'entity_object'
316
- }, this.CurrentUser);
317
- if (depsResult.Success) {
318
- this.TaskDependencies = depsResult.Results || [];
319
- console.log(`🔗 Loaded ${this.TaskDependencies.length} task dependencies`);
1065
+ /**
1066
+ * Builds the hierarchy-aware `WorkflowGroups`, KPI metrics, and agent filter options.
1067
+ */
1068
+ rebuildWorkflowCommandCenter() {
1069
+ const tasks = this.allHierarchyTasks.length > 0 ? this.allHierarchyTasks : this.AllTasks;
1070
+ const taskById = new Map();
1071
+ for (const t of tasks) {
1072
+ if (t?.ID) {
1073
+ taskById.set(t.ID.toLowerCase(), t);
320
1074
  }
321
- else {
322
- console.error('❌ Failed to load task dependencies:', depsResult.ErrorMessage);
323
- this.TaskDependencies = [];
1075
+ }
1076
+ // Group tasks by root workflow ID
1077
+ const buckets = new Map();
1078
+ for (const t of tasks) {
1079
+ if (!t?.ID)
1080
+ continue;
1081
+ const rootKey = (t.RootParentID || t.ParentID || t.ID).toLowerCase();
1082
+ const list = buckets.get(rootKey) ?? [];
1083
+ list.push(t);
1084
+ buckets.set(rootKey, list);
1085
+ }
1086
+ const depsByTaskId = new Map();
1087
+ for (const dep of this.TaskDependencies) {
1088
+ if (dep?.TaskID) {
1089
+ const key = dep.TaskID.toLowerCase();
1090
+ const existing = depsByTaskId.get(key) ?? [];
1091
+ existing.push(dep);
1092
+ depsByTaskId.set(key, existing);
324
1093
  }
325
1094
  }
326
- catch (error) {
327
- console.error('Failed to load task dependencies:', error);
328
- this.TaskDependencies = [];
1095
+ const groups = [];
1096
+ const agentUsageMap = new Map();
1097
+ for (const [rootKey, bucket] of buckets.entries()) {
1098
+ const parentTask = bucket.find(t => t.ID.toLowerCase() === rootKey) ??
1099
+ bucket.find(t => !t.ParentID) ??
1100
+ bucket[0];
1101
+ const childSteps = ExcludeByUUIDs(bucket, [parentTask.ID]);
1102
+ const rawSteps = childSteps.length > 0 ? childSteps : [parentTask];
1103
+ // Sort steps chronologically by StartedAt / __mj_CreatedAt
1104
+ const sortedRawSteps = [...rawSteps].sort((a, b) => {
1105
+ const aTime = this.toEpochMs(a.StartedAt ?? a.__mj_CreatedAt);
1106
+ const bTime = this.toEpochMs(b.StartedAt ?? b.__mj_CreatedAt);
1107
+ return aTime - bTime;
1108
+ });
1109
+ // Calculate workflow time bounds
1110
+ const startCandidates = bucket
1111
+ .map(t => this.toEpochMs(t.StartedAt ?? t.__mj_CreatedAt))
1112
+ .filter(ms => ms > 0);
1113
+ const endCandidates = bucket
1114
+ .map(t => this.toEpochMs(t.CompletedAt ?? t.__mj_UpdatedAt))
1115
+ .filter(ms => ms > 0);
1116
+ const workflowStartMs = startCandidates.length > 0 ? Math.min(...startCandidates) : 0;
1117
+ const workflowEndMs = endCandidates.length > 0 ? Math.max(...endCandidates) : workflowStartMs;
1118
+ const totalSpanMs = Math.max(1000, workflowEndMs - workflowStartMs);
1119
+ const pipelineAgents = [];
1120
+ const seenPipelineAgents = new Set();
1121
+ const seenUpstreamKeyValues = new Map();
1122
+ const enrichedSteps = sortedRawSteps.map((stepTask, idx) => {
1123
+ const agentName = this.resolveAgentName(stepTask);
1124
+ const agentId = stepTask.AgentID || null;
1125
+ if (agentId && agentName) {
1126
+ const lowerId = agentId.toLowerCase();
1127
+ if (!seenPipelineAgents.has(lowerId)) {
1128
+ seenPipelineAgents.add(lowerId);
1129
+ pipelineAgents.push({ id: agentId, name: agentName });
1130
+ }
1131
+ const existingUsage = agentUsageMap.get(lowerId);
1132
+ if (existingUsage) {
1133
+ existingUsage.count += 1;
1134
+ }
1135
+ else {
1136
+ agentUsageMap.set(lowerId, { id: agentId, name: agentName, count: 1 });
1137
+ }
1138
+ }
1139
+ const { instructions, output: rawDescOutput, isError } = this.splitTaskDescription(stepTask.Description || '');
1140
+ const deltaPayloadOutput = this.resolveDeltaStepOutput(stepTask.OutputPayload, seenUpstreamKeyValues);
1141
+ const output = (!rawDescOutput || rawDescOutput.startsWith('output available (')) && deltaPayloadOutput
1142
+ ? deltaPayloadOutput
1143
+ : rawDescOutput;
1144
+ const stepStartMs = this.toEpochMs(stepTask.StartedAt ?? stepTask.__mj_CreatedAt) || workflowStartMs;
1145
+ const stepEndMs = this.toEpochMs(stepTask.CompletedAt) ||
1146
+ (stepTask.Status === 'In Progress' ? Date.now() : stepStartMs + 1000);
1147
+ const stepDurationMs = Math.max(0, stepEndMs - stepStartMs);
1148
+ const rawOffsetPct = workflowStartMs > 0
1149
+ ? ((stepStartMs - workflowStartMs) / totalSpanMs) * 100
1150
+ : idx * (80 / Math.max(1, sortedRawSteps.length));
1151
+ const offsetPct = Math.max(0, Math.min(86, Math.round(rawOffsetPct)));
1152
+ const rawWidthPct = (Math.max(1000, stepDurationMs) / totalSpanMs) * 100;
1153
+ const widthPct = Math.max(14, Math.min(100 - offsetPct, Math.round(rawWidthPct)));
1154
+ const startOffsetSec = Math.max(0, Math.round((stepStartMs - workflowStartMs) / 1000));
1155
+ // Resolve dependencies for this step
1156
+ const stepDeps = stepTask.ID ? (depsByTaskId.get(stepTask.ID.toLowerCase()) ?? []) : [];
1157
+ const dependsOnNames = [];
1158
+ const dependsOnTaskIds = [];
1159
+ const dependsOnConditions = [];
1160
+ for (const dep of stepDeps) {
1161
+ if (dep.DependsOnTaskID) {
1162
+ dependsOnTaskIds.push(dep.DependsOnTaskID);
1163
+ const prereq = taskById.get(dep.DependsOnTaskID.toLowerCase());
1164
+ if (prereq?.Name) {
1165
+ dependsOnNames.push(prereq.Name);
1166
+ }
1167
+ }
1168
+ if (dep.Condition && dep.Condition.trim().length > 0) {
1169
+ dependsOnConditions.push(dep.Condition.trim());
1170
+ }
1171
+ }
1172
+ const isSkipped = stepTask.Status === 'Skipped';
1173
+ const effectiveDurationMs = isSkipped ? 0 : stepDurationMs;
1174
+ const rawPreview = isSkipped && !output
1175
+ ? dependsOnConditions.length > 0
1176
+ ? `Skipped (condition not met: ${dependsOnConditions.join(' AND ')}) — ${instructions || ''}`
1177
+ : `Skipped (conditional prerequisite not met) — ${instructions || ''}`
1178
+ : output || instructions || '';
1179
+ const cleanPreview = rawPreview.replace(/[#*`_~]/g, '').replace(/\s+/g, ' ').trim();
1180
+ return {
1181
+ Task: stepTask,
1182
+ StepNumber: idx + 1,
1183
+ AgentName: agentName,
1184
+ AgentID: agentId,
1185
+ AgentRunID: stepTask.AgentRunID || null,
1186
+ Instructions: instructions,
1187
+ Output: output,
1188
+ IsErrorOutput: isError,
1189
+ OutputPreview: cleanPreview.length > 180 ? `${cleanPreview.substring(0, 180)}...` : cleanPreview,
1190
+ DurationText: isSkipped ? '' : this.formatDurationMs(effectiveDurationMs, Boolean(stepTask.StartedAt)),
1191
+ DurationMs: effectiveDurationMs,
1192
+ TimelineOffsetPercent: offsetPct,
1193
+ TimelineWidthPercent: widthPct,
1194
+ StartOffsetLabel: `+${startOffsetSec}s`,
1195
+ DependsOnNames: dependsOnNames,
1196
+ DependsOnTaskIds: dependsOnTaskIds,
1197
+ DependsOnConditions: dependsOnConditions
1198
+ };
1199
+ });
1200
+ const totalSteps = enrichedSteps.length;
1201
+ const completedSteps = enrichedSteps.filter(s => s.Task.Status === 'Complete').length;
1202
+ const skippedSteps = enrichedSteps.filter(s => s.Task.Status === 'Skipped').length;
1203
+ const failedSteps = enrichedSteps.filter(s => s.Task.Status === 'Failed' || s.Task.Status === 'Cancelled' || s.Task.Status === 'Blocked').length;
1204
+ const activeSteps = enrichedSteps.filter(s => s.Task.Status === 'In Progress' || s.Task.Status === 'Pending').length;
1205
+ let category = 'active';
1206
+ if (failedSteps > 0 || parentTask.Status === 'Failed' || parentTask.Status === 'Cancelled') {
1207
+ category = 'failed';
1208
+ }
1209
+ else if ((completedSteps + skippedSteps) === totalSteps || parentTask.Status === 'Complete') {
1210
+ category = 'completed';
1211
+ }
1212
+ const percentComplete = category === 'completed'
1213
+ ? 100
1214
+ : totalSteps > 0
1215
+ ? Math.round(((completedSteps + skippedSteps) / totalSteps) * 100)
1216
+ : parentTask.PercentComplete ?? 0;
1217
+ const { instructions: parentInstructions } = this.splitTaskDescription(parentTask.Description || '');
1218
+ const wfStartDate = parentTask.StartedAt ?? sortedRawSteps[0]?.StartedAt ?? parentTask.__mj_CreatedAt ?? null;
1219
+ const wfEndDate = parentTask.CompletedAt ?? sortedRawSteps[sortedRawSteps.length - 1]?.CompletedAt ?? null;
1220
+ const wfDurationMs = wfStartDate && wfEndDate
1221
+ ? Math.max(0, new Date(wfEndDate).getTime() - new Date(wfStartDate).getTime())
1222
+ : enrichedSteps.reduce((acc, s) => acc + s.DurationMs, 0);
1223
+ groups.push({
1224
+ RootTaskId: parentTask.ID,
1225
+ ParentTask: parentTask,
1226
+ Title: parentTask.Name || 'Agent Workflow',
1227
+ SummaryInstruction: parentInstructions,
1228
+ Status: parentTask.Status,
1229
+ NormalizedCategory: category,
1230
+ PercentComplete: percentComplete,
1231
+ TotalSteps: totalSteps,
1232
+ CompletedSteps: completedSteps,
1233
+ SkippedSteps: skippedSteps,
1234
+ ActiveSteps: activeSteps,
1235
+ FailedSteps: failedSteps,
1236
+ Steps: enrichedSteps,
1237
+ AgentPipeline: pipelineAgents,
1238
+ StartedAt: wfStartDate ? new Date(wfStartDate) : null,
1239
+ CompletedAt: wfEndDate ? new Date(wfEndDate) : null,
1240
+ DurationText: this.formatDurationMs(wfDurationMs, wfDurationMs > 0),
1241
+ DurationMs: wfDurationMs,
1242
+ RelativeTimeText: this.formatRelativeTime(wfStartDate),
1243
+ ConversationDetailID: parentTask.ConversationDetailID || sortedRawSteps[0]?.ConversationDetailID || null,
1244
+ IsMultiStep: childSteps.length > 0
1245
+ });
1246
+ }
1247
+ // Sort workflows newest first
1248
+ groups.sort((a, b) => {
1249
+ const aMs = a.StartedAt ? a.StartedAt.getTime() : 0;
1250
+ const bMs = b.StartedAt ? b.StartedAt.getTime() : 0;
1251
+ return bMs - aMs;
1252
+ });
1253
+ this.WorkflowGroups = groups;
1254
+ this.AvailableAgents = Array.from(agentUsageMap.values()).sort((a, b) => b.count - a.count);
1255
+ this.computeCommandCenterKPIs(groups);
1256
+ this.ApplyWorkflowFilters();
1257
+ // Refresh open inspector drawer if active
1258
+ if (this.ActiveTaskId) {
1259
+ this.selectTaskById(this.ActiveTaskId, false);
1260
+ }
1261
+ else if (this.InspectedGroup) {
1262
+ const updatedGroup = IndexByUUID(groups, g => g.RootTaskId).Get(this.InspectedGroup.RootTaskId) ?? null;
1263
+ this.InspectedGroup = updatedGroup;
1264
+ if (updatedGroup && this.InspectedStep) {
1265
+ this.InspectedStep =
1266
+ IndexByUUID(updatedGroup.Steps, s => s.Task.ID).Get(this.InspectedStep.Task.ID) ??
1267
+ updatedGroup.Steps[0] ??
1268
+ null;
1269
+ }
329
1270
  }
330
1271
  }
331
- /**
332
- * Builds the TaskID -> AgentRunID map from each task's own AgentRunID column.
333
- *
334
- * Previously this joined tasks to runs through the shared ConversationDetailID, which meant
335
- * every sibling task in a graph resolved to the SAME agent run — the run link in the Gantt
336
- * and detail panel was wrong for all but one task. Each task now records the specific run
337
- * that executed it (Task.AgentRunID), so the mapping is direct and needs no query at all.
338
- */
339
- loadAgentRuns(tasks) {
340
- this.AgentRunMap.clear();
341
- for (const task of tasks) {
342
- if (task.AgentRunID) {
343
- this.AgentRunMap.set(task.ID, task.AgentRunID);
1272
+ computeCommandCenterKPIs(groups) {
1273
+ const totalWorkflows = groups.length;
1274
+ const totalSteps = groups.reduce((sum, g) => sum + g.TotalSteps, 0);
1275
+ const activeWorkflows = groups.filter(g => g.NormalizedCategory === 'active').length;
1276
+ const completedSteps = groups.reduce((sum, g) => sum + g.CompletedSteps, 0);
1277
+ const failedSteps = groups.reduce((sum, g) => sum + g.FailedSteps, 0);
1278
+ const terminalSteps = completedSteps + failedSteps;
1279
+ const successRate = terminalSteps > 0 ? Math.round((completedSteps / terminalSteps) * 100) : 100;
1280
+ const completedWithDuration = groups.filter(g => g.NormalizedCategory === 'completed' && g.DurationMs > 0);
1281
+ const avgMs = completedWithDuration.length > 0
1282
+ ? Math.round(completedWithDuration.reduce((sum, g) => sum + g.DurationMs, 0) / completedWithDuration.length)
1283
+ : 0;
1284
+ this.Kpis = {
1285
+ TotalWorkflows: totalWorkflows,
1286
+ TotalSteps: totalSteps,
1287
+ ActiveWorkflows: activeWorkflows,
1288
+ CompletedSteps: completedSteps,
1289
+ SuccessRatePercent: successRate,
1290
+ AvgExecutionTimeText: avgMs > 0 ? this.formatDurationMs(avgMs, true) : '—'
1291
+ };
1292
+ }
1293
+ ApplyWorkflowFilters() {
1294
+ const q = this.SearchQuery.trim().toLowerCase();
1295
+ this.FilteredWorkflowGroups = this.WorkflowGroups.filter(group => {
1296
+ if (this.StatusFilter !== 'all' && group.NormalizedCategory !== this.StatusFilter) {
1297
+ return false;
1298
+ }
1299
+ if (this.SelectedAgentFilter !== 'all') {
1300
+ const stepAgentIds = new UUIDSet(group.Steps.map(s => s.AgentID));
1301
+ if (!stepAgentIds.Has(this.SelectedAgentFilter))
1302
+ return false;
1303
+ }
1304
+ if (q) {
1305
+ const titleMatch = group.Title.toLowerCase().includes(q);
1306
+ const stepMatch = group.Steps.some(s => (s.Task.Name || '').toLowerCase().includes(q) ||
1307
+ s.Instructions.toLowerCase().includes(q) ||
1308
+ (s.Output || '').toLowerCase().includes(q) ||
1309
+ (s.AgentName || '').toLowerCase().includes(q));
1310
+ return titleMatch || stepMatch;
1311
+ }
1312
+ return true;
1313
+ });
1314
+ }
1315
+ /** @deprecated Use {@link ApplyWorkflowFilters}. */
1316
+ applyWorkflowFilters() {
1317
+ this.ApplyWorkflowFilters();
1318
+ }
1319
+ SetCommandViewMode(mode) {
1320
+ this.CommandViewMode = mode;
1321
+ }
1322
+ SetStatusFilter(filter) {
1323
+ this.StatusFilter = filter;
1324
+ this.ApplyWorkflowFilters();
1325
+ }
1326
+ SetAgentFilter(agentId) {
1327
+ this.SelectedAgentFilter = agentId;
1328
+ this.ApplyWorkflowFilters();
1329
+ }
1330
+ OnFilterCriteriaChanged() {
1331
+ this.ApplyWorkflowFilters();
1332
+ }
1333
+ ClearSearch() {
1334
+ this.SearchQuery = '';
1335
+ this.ApplyWorkflowFilters();
1336
+ }
1337
+ ResetAllFilters() {
1338
+ this.SearchQuery = '';
1339
+ this.StatusFilter = 'all';
1340
+ this.SelectedAgentFilter = 'all';
1341
+ this.ApplyWorkflowFilters();
1342
+ }
1343
+ CountByCategory(category) {
1344
+ return this.WorkflowGroups.filter(g => g.NormalizedCategory === category).length;
1345
+ }
1346
+ GetStepCategory(status) {
1347
+ if (status === 'Complete')
1348
+ return 'completed';
1349
+ if (status === 'Skipped')
1350
+ return 'skipped';
1351
+ if (status === 'Failed' || status === 'Cancelled' || status === 'Blocked')
1352
+ return 'failed';
1353
+ return 'active';
1354
+ }
1355
+ IsGroupInspected(group) {
1356
+ return Boolean(this.InspectedGroup && UUIDsEqual(this.InspectedGroup.RootTaskId, group.RootTaskId));
1357
+ }
1358
+ IsStepInspected(task) {
1359
+ return Boolean(this.InspectedStep && UUIDsEqual(this.InspectedStep.Task.ID, task.ID));
1360
+ }
1361
+ InspectWorkflowGroup(group, step, event) {
1362
+ event?.stopPropagation();
1363
+ this.InspectedGroup = group;
1364
+ this.InspectedStep = step ?? group.Steps[0] ?? null;
1365
+ this.SelectedTask = step ? step.Task : group.ParentTask;
1366
+ this.SubTasks = group.Steps.map(s => s.Task);
1367
+ this.SubTasksWithParent = [group.ParentTask, ...this.SubTasks];
1368
+ this.ShowDetailAnimation = true;
1369
+ this.TaskSelected.emit(this.SelectedTask.ID);
1370
+ }
1371
+ SelectInspectorStep(step) {
1372
+ this.InspectedStep = step;
1373
+ this.SelectedTask = step.Task;
1374
+ this.TaskSelected.emit(step.Task.ID);
1375
+ }
1376
+ selectTaskById(taskId, emitEvent = true) {
1377
+ for (const group of this.WorkflowGroups) {
1378
+ if (UUIDsEqual(group.RootTaskId, taskId)) {
1379
+ this.InspectedGroup = group;
1380
+ this.InspectedStep = group.Steps[0] ?? null;
1381
+ this.SelectedTask = group.ParentTask;
1382
+ if (emitEvent) {
1383
+ this.TaskSelected.emit(taskId);
1384
+ }
1385
+ return;
1386
+ }
1387
+ const stepMatch = IndexByUUID(group.Steps, s => s.Task.ID).Get(taskId);
1388
+ if (stepMatch) {
1389
+ this.InspectedGroup = group;
1390
+ this.InspectedStep = stepMatch;
1391
+ this.SelectedTask = stepMatch.Task;
1392
+ if (emitEvent) {
1393
+ this.TaskSelected.emit(taskId);
1394
+ }
1395
+ return;
344
1396
  }
345
1397
  }
346
1398
  }
1399
+ async OnTaskClick(task) {
1400
+ this.SelectedTask = task;
1401
+ this.ShowDetailAnimation = true;
1402
+ this.TaskSelected.emit(task.ID);
1403
+ this.selectTaskById(task.ID, false);
1404
+ }
1405
+ /** @deprecated Use {@link OnTaskClick}. */
1406
+ async onTaskClick(task) {
1407
+ return this.OnTaskClick(task);
1408
+ }
347
1409
  BackToTaskList() {
1410
+ this.InspectedGroup = null;
1411
+ this.InspectedStep = null;
348
1412
  this.SelectedTask = null;
349
1413
  this.SubTasks = [];
350
1414
  this.SubTasksWithParent = [];
351
- this.TaskDependencies = [];
352
- this.AgentRunMap.clear();
353
1415
  this.ShowDetailAnimation = false;
354
- // Emit null to indicate returning to task list (for URL tracking)
355
1416
  this.TaskSelected.emit(null);
356
1417
  }
357
1418
  /** @deprecated Use {@link BackToTaskList}. */
@@ -359,21 +1420,167 @@ export class TasksFullViewComponent extends BaseAngularComponent {
359
1420
  return this.BackToTaskList();
360
1421
  }
361
1422
  OnSubTaskClick(subTask) {
362
- console.log('Sub-task clicked:', subTask);
363
- // Could drill down further if needed
1423
+ this.selectTaskById(subTask.ID, true);
364
1424
  }
365
1425
  /** @deprecated Use {@link OnSubTaskClick}. */
366
1426
  onSubTaskClick(subTask) {
367
1427
  return this.OnSubTaskClick(subTask);
368
1428
  }
1429
+ OnAgentChipClicked(event, agentId) {
1430
+ event.stopPropagation();
1431
+ if (agentId) {
1432
+ this.OpenEntityRecord.emit({
1433
+ entityName: 'MJ: AI Agents',
1434
+ recordId: agentId
1435
+ });
1436
+ }
1437
+ }
1438
+ OnOpenAgentRunClicked(event, agentRunId) {
1439
+ event.stopPropagation();
1440
+ if (agentRunId) {
1441
+ this.OpenEntityRecord.emit({
1442
+ entityName: 'MJ: AI Agent Runs',
1443
+ recordId: agentRunId
1444
+ });
1445
+ }
1446
+ }
369
1447
  OnOpenEntityRecord(event) {
370
- // Bubble up the event to parent component
371
1448
  this.OpenEntityRecord.emit(event);
372
1449
  }
373
1450
  /** @deprecated Use {@link OnOpenEntityRecord}. */
374
1451
  onOpenEntityRecord(event) {
375
1452
  return this.OnOpenEntityRecord(event);
376
1453
  }
1454
+ CopyStepOutput(output) {
1455
+ if (typeof navigator !== 'undefined' && navigator.clipboard) {
1456
+ void navigator.clipboard.writeText(output);
1457
+ this.CopiedOutput = true;
1458
+ setTimeout(() => {
1459
+ this.CopiedOutput = false;
1460
+ this.cdr?.markForCheck();
1461
+ }, 1800);
1462
+ }
1463
+ }
1464
+ loadAgentRuns(tasks) {
1465
+ this.AgentRunMap.clear();
1466
+ for (const task of tasks) {
1467
+ if (task?.ID && task.AgentRunID) {
1468
+ this.AgentRunMap.set(task.ID, task.AgentRunID);
1469
+ }
1470
+ }
1471
+ }
1472
+ resolveAgentName(task) {
1473
+ if (task.Agent) {
1474
+ return task.Agent;
1475
+ }
1476
+ if (task.AgentID) {
1477
+ const agents = AIEngineBase.Instance.Agents || [];
1478
+ const found = agents.find((a) => UUIDsEqual(a.ID, task.AgentID));
1479
+ if (found?.Name) {
1480
+ return found.Name;
1481
+ }
1482
+ }
1483
+ return null;
1484
+ }
1485
+ splitTaskDescription(raw) {
1486
+ const outputMarker = '\n\n--- Output ---\n';
1487
+ const errorMarker = '\n\n--- Error ---\n';
1488
+ const outIdx = raw.indexOf(outputMarker);
1489
+ if (outIdx >= 0) {
1490
+ return {
1491
+ instructions: raw.substring(0, outIdx).trim(),
1492
+ output: raw.substring(outIdx + outputMarker.length).trim(),
1493
+ isError: false
1494
+ };
1495
+ }
1496
+ const errIdx = raw.indexOf(errorMarker);
1497
+ if (errIdx >= 0) {
1498
+ return {
1499
+ instructions: raw.substring(0, errIdx).trim(),
1500
+ output: raw.substring(errIdx + errorMarker.length).trim(),
1501
+ isError: true
1502
+ };
1503
+ }
1504
+ return {
1505
+ instructions: raw.trim(),
1506
+ output: null,
1507
+ isError: false
1508
+ };
1509
+ }
1510
+ /**
1511
+ * Strips upstream keys inherited unchanged from earlier workflow steps and returns a formatted
1512
+ * human-readable or JSON excerpt for the step inspector drawer.
1513
+ */
1514
+ resolveDeltaStepOutput(rawPayload, seenUpstreamKeyValues) {
1515
+ const trimmed = rawPayload?.trim();
1516
+ if (!trimmed) {
1517
+ return null;
1518
+ }
1519
+ try {
1520
+ const parsed = JSON.parse(trimmed);
1521
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
1522
+ const delta = {};
1523
+ for (const [k, v] of Object.entries(parsed)) {
1524
+ const serializedVal = JSON.stringify(v);
1525
+ if (seenUpstreamKeyValues.get(k) !== serializedVal) {
1526
+ delta[k] = v;
1527
+ }
1528
+ seenUpstreamKeyValues.set(k, serializedVal);
1529
+ }
1530
+ const source = Object.keys(delta).length > 0 ? delta : parsed;
1531
+ return JSON.stringify(source, null, 2);
1532
+ }
1533
+ }
1534
+ catch {
1535
+ // Non-JSON payload; return as-is.
1536
+ }
1537
+ return trimmed;
1538
+ }
1539
+ toEpochMs(date) {
1540
+ if (!date)
1541
+ return 0;
1542
+ const ms = new Date(date).getTime();
1543
+ return Number.isFinite(ms) ? ms : 0;
1544
+ }
1545
+ formatDurationMs(durationMs, hasStarted) {
1546
+ if (!hasStarted || durationMs <= 0)
1547
+ return '';
1548
+ const totalSeconds = Math.max(1, Math.round(durationMs / 1000));
1549
+ if (totalSeconds < 60) {
1550
+ return `${totalSeconds}s`;
1551
+ }
1552
+ const minutes = Math.floor(totalSeconds / 60);
1553
+ const seconds = totalSeconds % 60;
1554
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
1555
+ }
1556
+ formatRelativeTime(date) {
1557
+ if (!date)
1558
+ return '';
1559
+ const ms = new Date(date).getTime();
1560
+ if (!Number.isFinite(ms))
1561
+ return '';
1562
+ const diffSec = Math.round((Date.now() - ms) / 1000);
1563
+ if (diffSec < 60)
1564
+ return 'Just now';
1565
+ if (diffSec < 3600)
1566
+ return `${Math.floor(diffSec / 60)}m ago`;
1567
+ if (diffSec < 86400)
1568
+ return `${Math.floor(diffSec / 3600)}h ago`;
1569
+ return new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
1570
+ }
1571
+ FormatDateTime(date) {
1572
+ if (!date)
1573
+ return '';
1574
+ const d = new Date(date);
1575
+ return d.toLocaleDateString('en-US', {
1576
+ month: 'short',
1577
+ day: 'numeric',
1578
+ year: 'numeric',
1579
+ hour: '2-digit',
1580
+ minute: '2-digit',
1581
+ second: '2-digit'
1582
+ });
1583
+ }
377
1584
  getDescription() {
378
1585
  const activeCount = this.AllTasks.filter(t => t.Status === 'Pending' || t.Status === 'In Progress').length;
379
1586
  const completedCount = this.AllTasks.filter(t => t.Status === 'Complete').length;
@@ -392,61 +1599,865 @@ export class TasksFullViewComponent extends BaseAngularComponent {
392
1599
  return this.GetTaskDetailDescription();
393
1600
  }
394
1601
  static ɵfac = /*@__PURE__*/ (() => { let ɵTasksFullViewComponent_BaseFactory; return function TasksFullViewComponent_Factory(__ngFactoryType__) { return (ɵTasksFullViewComponent_BaseFactory || (ɵTasksFullViewComponent_BaseFactory = i0.ɵɵgetInheritedFactory(TasksFullViewComponent)))(__ngFactoryType__ || TasksFullViewComponent); }; })();
395
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TasksFullViewComponent, selectors: [["mj-tasks-full-view"]], inputs: { EnvironmentId: "EnvironmentId", environmentId: "environmentId", CurrentUser: "CurrentUser", currentUser: "currentUser", BaseFilter: "BaseFilter", baseFilter: "baseFilter", ActiveTaskId: "ActiveTaskId", activeTaskId: "activeTaskId" }, outputs: { OpenEntityRecord: "OpenEntityRecord", openEntityRecord: "openEntityRecord", TaskSelected: "TaskSelected", taskSelected: "taskSelected" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 3, vars: 1, consts: [[1, "tasks-full-view"], [3, "tasks", "title", "description", "showHeader", "showViewToggle", "viewMode"], [1, "task-detail-view", 3, "swoosh-in"], [3, "taskClicked", "tasks", "title", "description", "showHeader", "showViewToggle", "viewMode"], [1, "task-detail-view"], [1, "breadcrumb-nav"], [1, "breadcrumb-back", 3, "click"], [1, "fas", "fa-arrow-left"], [1, "breadcrumb-divider"], [1, "breadcrumb-current"], [3, "taskClicked", "openEntityRecord", "tasks", "ganttTasks", "taskDependencies", "agentRunMap", "title", "description", "showHeader", "showViewToggle", "viewMode"]], template: function TasksFullViewComponent_Template(rf, ctx) { if (rf & 1) {
396
- i0.ɵɵelementStart(0, "div", 0);
397
- i0.ɵɵconditionalCreate(1, TasksFullViewComponent_Conditional_1_Template, 1, 6, "mj-task", 1)(2, TasksFullViewComponent_Conditional_2_Template, 11, 12, "div", 2);
1602
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TasksFullViewComponent, selectors: [["mj-tasks-full-view"]], inputs: { EnvironmentId: "EnvironmentId", environmentId: "environmentId", CurrentUser: "CurrentUser", currentUser: "currentUser", BaseFilter: "BaseFilter", baseFilter: "baseFilter", BaseFilterResolver: "BaseFilterResolver", ActiveTaskId: "ActiveTaskId", activeTaskId: "activeTaskId" }, outputs: { OpenEntityRecord: "OpenEntityRecord", openEntityRecord: "openEntityRecord", TaskSelected: "TaskSelected", taskSelected: "taskSelected" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 119, vars: 37, consts: [[1, "tasks-command-center"], [1, "cc-header"], [1, "cc-header-left"], [1, "cc-title-icon"], [1, "fa-solid", "fa-diagram-project"], [1, "cc-title-block"], [1, "cc-title-row"], [1, "cc-title"], [1, "cc-live-pill"], [1, "cc-subtitle"], [1, "cc-header-actions"], ["role", "tablist", "aria-label", "View Mode", 1, "cc-view-switcher"], ["type", "button", 1, "cc-view-btn", 3, "click"], [1, "fa-solid", "fa-layer-group"], [1, "fa-solid", "fa-bars-staggered"], ["type", "button", "title", "Refresh workflows and tasks", 1, "cc-refresh-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-arrows-rotate"], ["aria-label", "Workflow Metrics", 1, "cc-kpi-ribbon"], [1, "cc-kpi-card"], [1, "cc-kpi-icon", "kpi-brand"], [1, "fa-solid", "fa-sitemap"], [1, "cc-kpi-body"], [1, "cc-kpi-label"], [1, "cc-kpi-value-row"], [1, "cc-kpi-value"], [1, "cc-kpi-sub"], [1, "cc-kpi-icon", "kpi-active"], [1, "fa-solid", "fa-bolt"], [1, "cc-kpi-icon", "kpi-success"], [1, "fa-solid", "fa-circle-check"], [1, "cc-kpi-icon", "kpi-rate"], [1, "fa-solid", "fa-chart-line"], [1, "cc-kpi-icon", "kpi-time"], [1, "fa-solid", "fa-stopwatch"], [1, "cc-filter-bar"], [1, "cc-search-box"], [1, "fa-solid", "fa-magnifying-glass", "cc-search-icon"], ["type", "text", "placeholder", "Search workflows, step names, specialist agents, or outputs...", 1, "cc-search-input", 3, "ngModelChange", "ngModel"], ["type", "button", "title", "Clear search", 1, "cc-search-clear"], ["role", "group", "aria-label", "Filter by status", 1, "cc-status-pills"], ["type", "button", 1, "cc-filter-pill", 3, "click"], [1, "cc-pill-count"], ["type", "button", 1, "cc-filter-pill", "pill-active", 3, "click"], [1, "cc-status-dot", "dot-active"], ["type", "button", 1, "cc-filter-pill", "pill-completed", 3, "click"], [1, "cc-status-dot", "dot-completed"], ["type", "button", 1, "cc-filter-pill", "pill-failed", 3, "click"], [1, "cc-status-dot", "dot-failed"], [1, "cc-agent-filter"], [1, "cc-workspace-body"], [1, "cc-main-scroll"], [1, "cc-empty-state"], [1, "cc-workflow-grid"], [1, "cc-timeline-list"], ["aria-label", "Workflow and Step Inspector", 1, "cc-inspector-drawer"], [1, "cc-live-dot"], ["type", "button", "title", "Clear search", 1, "cc-search-clear", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "fa-solid", "fa-robot", "cc-agent-filter-icon"], ["aria-label", "Filter by specialist agent", 1, "cc-agent-select", 3, "ngModelChange", "ngModel"], ["value", "all"], [3, "value"], [1, "cc-empty-icon"], [1, "fa-solid", "fa-circle-notch", "fa-spin"], ["type", "button", 1, "cc-reset-filters-btn", 3, "click"], [1, "fa-solid", "fa-rotate-left"], [1, "cc-workflow-card", 3, "card-active", "card-completed", "card-failed", "card-selected"], [1, "cc-workflow-card", 3, "click"], [1, "cc-wf-header"], [1, "cc-wf-header-left"], [1, "cc-wf-status-icon"], [1, "fa-solid", "fa-check"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "cc-wf-title-group"], [1, "cc-wf-title-line"], [1, "cc-wf-title"], [1, "cc-wf-step-count-badge"], [1, "cc-wf-status-badge"], [1, "cc-wf-agent-pipeline"], [1, "cc-wf-header-right"], ["title", "Total workflow execution duration", 1, "cc-wf-duration"], [1, "cc-wf-timestamp"], ["type", "button", "title", "Open Workflow Inspector", 1, "cc-wf-inspect-btn", 3, "click"], [1, "fa-solid", "fa-chevron-right"], [1, "cc-wf-progress-row"], [1, "cc-wf-progress-track"], [1, "cc-wf-progress-fill"], [1, "cc-wf-progress-label"], [1, "cc-wf-steps-list"], [1, "cc-step-row", 3, "step-selected"], ["type", "button", 1, "cc-agent-chip", 3, "click", "title"], [1, "fa-solid", "fa-robot"], [1, "fa-solid", "fa-arrow-right", "cc-pipeline-arrow"], [1, "fa-regular", "fa-clock"], [1, "cc-step-row", 3, "click"], [1, "cc-step-index"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-forward-step"], [1, "cc-step-main"], [1, "cc-step-top-line"], [1, "cc-step-name"], [1, "cc-step-agent-tag"], [1, "cc-step-dep-tag", 3, "title"], [1, "cc-step-preview", 3, "preview-error"], [1, "cc-step-right"], [1, "cc-step-duration"], [1, "cc-step-status-pill"], ["type", "button", "title", "Open AI Agent Run Telemetry", 1, "cc-step-run-btn"], [1, "fa-solid", "fa-link"], [1, "cc-step-preview"], ["type", "button", "title", "Open AI Agent Run Telemetry", 1, "cc-step-run-btn", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "cc-timeline-card", 3, "card-selected"], [1, "cc-timeline-card"], [1, "cc-timeline-card-header", 3, "click"], [1, "cc-timeline-title-wrap"], [1, "cc-timeline-meta"], [1, "cc-wf-duration"], [1, "cc-waterfall-table"], [1, "cc-waterfall-head"], [1, "cc-wf-col-step"], [1, "cc-wf-col-agent"], [1, "cc-wf-col-bars"], [1, "cc-waterfall-row", 3, "step-selected"], [1, "cc-waterfall-row", 3, "click"], [1, "cc-waterfall-step-text"], [1, "cc-waterfall-dep"], [1, "cc-text-muted"], [1, "cc-waterfall-track"], [1, "cc-waterfall-bar"], [1, "cc-waterfall-bar-label"], [1, "fa-solid", "fa-turn-up", "fa-rotate-90"], [1, "cc-drawer-header"], [1, "cc-drawer-header-top"], [1, "cc-drawer-eyebrow"], [1, "fa-solid", "fa-microscope"], ["type", "button", "title", "Close Inspector", 1, "cc-drawer-close", 3, "click"], [1, "cc-drawer-title"], [1, "cc-drawer-step-tabs"], [1, "cc-drawer-content"], ["type", "button", 1, "cc-drawer-step-tab", 3, "active"], ["type", "button", 1, "cc-drawer-step-tab", 3, "click"], [1, "cc-tab-num"], [1, "cc-tab-label"], [1, "cc-drawer-metrics-grid"], [1, "cc-drawer-metric-box"], [1, "cc-drawer-metric-label"], [1, "cc-drawer-metric-val"], [1, "cc-drawer-progress-bar"], [1, "cc-drawer-progress-fill"], [1, "cc-drawer-section"], [1, "cc-drawer-section-title"], [1, "cc-drawer-links-stack"], ["type", "button", 1, "cc-drawer-link-card"], [1, "cc-drawer-timestamps"], [1, "cc-ts-row"], ["type", "button", 1, "cc-drawer-link-card", 3, "click"], [1, "cc-link-card-icon"], [1, "cc-link-card-body"], [1, "cc-link-card-label"], [1, "cc-link-card-title"], [1, "fa-solid", "fa-arrow-up-right-from-square", "cc-link-card-ext"], [1, "cc-link-card-icon", "run-icon"], [1, "fa-solid", "fa-gauge-high"], [1, "cc-drawer-deps-list"], [1, "cc-drawer-dep-pill"], [1, "fa-solid", "fa-code-commit"], [1, "fa-solid", "fa-code-branch"], [1, "cc-ts-label"], [1, "cc-ts-val"], [1, "cc-drawer-text-box"], [1, "cc-drawer-section-head"], ["type", "button", "title", "Copy output to clipboard", 1, "cc-copy-btn", 3, "click"], [1, "fa-regular"], [1, "cc-drawer-output-box"]], template: function TasksFullViewComponent_Template(rf, ctx) { if (rf & 1) {
1603
+ i0.ɵɵelementStart(0, "div", 0)(1, "header", 1)(2, "div", 2)(3, "div", 3);
1604
+ i0.ɵɵelement(4, "i", 4);
1605
+ i0.ɵɵelementEnd();
1606
+ i0.ɵɵelementStart(5, "div", 5)(6, "div", 6)(7, "h1", 7);
1607
+ i0.ɵɵtext(8, "AI Agent Workflows & Tasks");
1608
+ i0.ɵɵelementEnd();
1609
+ i0.ɵɵconditionalCreate(9, TasksFullViewComponent_Conditional_9_Template, 3, 1, "span", 8);
1610
+ i0.ɵɵelementEnd();
1611
+ i0.ɵɵelementStart(10, "p", 9);
1612
+ i0.ɵɵtext(11, " Real-time multi-agent task orchestration, step dependencies & execution telemetry ");
1613
+ i0.ɵɵelementEnd()()();
1614
+ i0.ɵɵelementStart(12, "div", 10)(13, "div", 11)(14, "button", 12);
1615
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Template_button_click_14_listener() { return ctx.SetCommandViewMode("workflows"); });
1616
+ i0.ɵɵelement(15, "i", 13);
1617
+ i0.ɵɵelementStart(16, "span");
1618
+ i0.ɵɵtext(17, "Workflow Cards");
1619
+ i0.ɵɵelementEnd()();
1620
+ i0.ɵɵelementStart(18, "button", 12);
1621
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Template_button_click_18_listener() { return ctx.SetCommandViewMode("timeline"); });
1622
+ i0.ɵɵelement(19, "i", 14);
1623
+ i0.ɵɵelementStart(20, "span");
1624
+ i0.ɵɵtext(21, "Execution Timeline & DAG");
1625
+ i0.ɵɵelementEnd()()();
1626
+ i0.ɵɵelementStart(22, "button", 15);
1627
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Template_button_click_22_listener() { return ctx.LoadTasks(); });
1628
+ i0.ɵɵelement(23, "i", 16);
1629
+ i0.ɵɵelementStart(24, "span");
1630
+ i0.ɵɵtext(25, "Refresh");
1631
+ i0.ɵɵelementEnd()()()();
1632
+ i0.ɵɵelementStart(26, "section", 17)(27, "div", 18)(28, "div", 19);
1633
+ i0.ɵɵelement(29, "i", 20);
1634
+ i0.ɵɵelementEnd();
1635
+ i0.ɵɵelementStart(30, "div", 21)(31, "span", 22);
1636
+ i0.ɵɵtext(32, "Total Workflows");
1637
+ i0.ɵɵelementEnd();
1638
+ i0.ɵɵelementStart(33, "div", 23)(34, "span", 24);
1639
+ i0.ɵɵtext(35);
1640
+ i0.ɵɵelementEnd();
1641
+ i0.ɵɵelementStart(36, "span", 25);
1642
+ i0.ɵɵtext(37);
1643
+ i0.ɵɵelementEnd()()()();
1644
+ i0.ɵɵelementStart(38, "div", 18)(39, "div", 26);
1645
+ i0.ɵɵelement(40, "i", 27);
1646
+ i0.ɵɵelementEnd();
1647
+ i0.ɵɵelementStart(41, "div", 21)(42, "span", 22);
1648
+ i0.ɵɵtext(43, "Active / Running");
1649
+ i0.ɵɵelementEnd();
1650
+ i0.ɵɵelementStart(44, "div", 23)(45, "span", 24);
1651
+ i0.ɵɵtext(46);
1652
+ i0.ɵɵelementEnd();
1653
+ i0.ɵɵelementStart(47, "span", 25);
1654
+ i0.ɵɵtext(48);
1655
+ i0.ɵɵelementEnd()()()();
1656
+ i0.ɵɵelementStart(49, "div", 18)(50, "div", 28);
1657
+ i0.ɵɵelement(51, "i", 29);
1658
+ i0.ɵɵelementEnd();
1659
+ i0.ɵɵelementStart(52, "div", 21)(53, "span", 22);
1660
+ i0.ɵɵtext(54, "Completed Steps");
1661
+ i0.ɵɵelementEnd();
1662
+ i0.ɵɵelementStart(55, "div", 23)(56, "span", 24);
1663
+ i0.ɵɵtext(57);
1664
+ i0.ɵɵelementEnd();
1665
+ i0.ɵɵelementStart(58, "span", 25);
1666
+ i0.ɵɵtext(59);
1667
+ i0.ɵɵelementEnd()()()();
1668
+ i0.ɵɵelementStart(60, "div", 18)(61, "div", 30);
1669
+ i0.ɵɵelement(62, "i", 31);
1670
+ i0.ɵɵelementEnd();
1671
+ i0.ɵɵelementStart(63, "div", 21)(64, "span", 22);
1672
+ i0.ɵɵtext(65, "Success Rate");
1673
+ i0.ɵɵelementEnd();
1674
+ i0.ɵɵelementStart(66, "div", 23)(67, "span", 24);
1675
+ i0.ɵɵtext(68);
1676
+ i0.ɵɵelementEnd();
1677
+ i0.ɵɵelementStart(69, "span", 25);
1678
+ i0.ɵɵtext(70, "terminal reliability");
1679
+ i0.ɵɵelementEnd()()()();
1680
+ i0.ɵɵelementStart(71, "div", 18)(72, "div", 32);
1681
+ i0.ɵɵelement(73, "i", 33);
398
1682
  i0.ɵɵelementEnd();
1683
+ i0.ɵɵelementStart(74, "div", 21)(75, "span", 22);
1684
+ i0.ɵɵtext(76, "Avg Execution Time");
1685
+ i0.ɵɵelementEnd();
1686
+ i0.ɵɵelementStart(77, "div", 23)(78, "span", 24);
1687
+ i0.ɵɵtext(79);
1688
+ i0.ɵɵelementEnd();
1689
+ i0.ɵɵelementStart(80, "span", 25);
1690
+ i0.ɵɵtext(81, "per completed workflow");
1691
+ i0.ɵɵelementEnd()()()()();
1692
+ i0.ɵɵelementStart(82, "section", 34)(83, "div", 35);
1693
+ i0.ɵɵelement(84, "i", 36);
1694
+ i0.ɵɵelementStart(85, "input", 37);
1695
+ i0.ɵɵtwoWayListener("ngModelChange", function TasksFullViewComponent_Template_input_ngModelChange_85_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.SearchQuery, $event) || (ctx.SearchQuery = $event); return $event; });
1696
+ i0.ɵɵlistener("ngModelChange", function TasksFullViewComponent_Template_input_ngModelChange_85_listener() { return ctx.OnFilterCriteriaChanged(); });
1697
+ i0.ɵɵelementEnd();
1698
+ i0.ɵɵconditionalCreate(86, TasksFullViewComponent_Conditional_86_Template, 2, 0, "button", 38);
1699
+ i0.ɵɵelementEnd();
1700
+ i0.ɵɵelementStart(87, "div", 39)(88, "button", 40);
1701
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Template_button_click_88_listener() { return ctx.SetStatusFilter("all"); });
1702
+ i0.ɵɵelementStart(89, "span");
1703
+ i0.ɵɵtext(90, "All");
1704
+ i0.ɵɵelementEnd();
1705
+ i0.ɵɵelementStart(91, "span", 41);
1706
+ i0.ɵɵtext(92);
1707
+ i0.ɵɵelementEnd()();
1708
+ i0.ɵɵelementStart(93, "button", 42);
1709
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Template_button_click_93_listener() { return ctx.SetStatusFilter("active"); });
1710
+ i0.ɵɵelement(94, "span", 43);
1711
+ i0.ɵɵelementStart(95, "span");
1712
+ i0.ɵɵtext(96, "Active");
1713
+ i0.ɵɵelementEnd();
1714
+ i0.ɵɵelementStart(97, "span", 41);
1715
+ i0.ɵɵtext(98);
1716
+ i0.ɵɵelementEnd()();
1717
+ i0.ɵɵelementStart(99, "button", 44);
1718
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Template_button_click_99_listener() { return ctx.SetStatusFilter("completed"); });
1719
+ i0.ɵɵelement(100, "span", 45);
1720
+ i0.ɵɵelementStart(101, "span");
1721
+ i0.ɵɵtext(102, "Completed");
1722
+ i0.ɵɵelementEnd();
1723
+ i0.ɵɵelementStart(103, "span", 41);
1724
+ i0.ɵɵtext(104);
1725
+ i0.ɵɵelementEnd()();
1726
+ i0.ɵɵelementStart(105, "button", 46);
1727
+ i0.ɵɵlistener("click", function TasksFullViewComponent_Template_button_click_105_listener() { return ctx.SetStatusFilter("failed"); });
1728
+ i0.ɵɵelement(106, "span", 47);
1729
+ i0.ɵɵelementStart(107, "span");
1730
+ i0.ɵɵtext(108, "Failed");
1731
+ i0.ɵɵelementEnd();
1732
+ i0.ɵɵelementStart(109, "span", 41);
1733
+ i0.ɵɵtext(110);
1734
+ i0.ɵɵelementEnd()()();
1735
+ i0.ɵɵconditionalCreate(111, TasksFullViewComponent_Conditional_111_Template, 7, 2, "div", 48);
1736
+ i0.ɵɵelementEnd();
1737
+ i0.ɵɵelementStart(112, "div", 49)(113, "div", 50);
1738
+ i0.ɵɵconditionalCreate(114, TasksFullViewComponent_Conditional_114_Template, 7, 0, "div", 51)(115, TasksFullViewComponent_Conditional_115_Template, 5, 1, "div", 51)(116, TasksFullViewComponent_Conditional_116_Template, 3, 0, "div", 52)(117, TasksFullViewComponent_Conditional_117_Template, 3, 0, "div", 53);
1739
+ i0.ɵɵelementEnd();
1740
+ i0.ɵɵconditionalCreate(118, TasksFullViewComponent_Conditional_118_Template, 13, 4, "aside", 54);
1741
+ i0.ɵɵelementEnd()();
399
1742
  } if (rf & 2) {
1743
+ i0.ɵɵadvance(9);
1744
+ i0.ɵɵconditional(ctx.Kpis.ActiveWorkflows > 0 ? 9 : -1);
1745
+ i0.ɵɵadvance(5);
1746
+ i0.ɵɵclassProp("active", ctx.CommandViewMode === "workflows");
1747
+ i0.ɵɵadvance(4);
1748
+ i0.ɵɵclassProp("active", ctx.CommandViewMode === "timeline");
1749
+ i0.ɵɵadvance(4);
1750
+ i0.ɵɵproperty("disabled", ctx.isLoading);
1751
+ i0.ɵɵadvance();
1752
+ i0.ɵɵclassProp("fa-spin", ctx.isLoading);
1753
+ i0.ɵɵadvance(12);
1754
+ i0.ɵɵtextInterpolate(ctx.Kpis.TotalWorkflows);
1755
+ i0.ɵɵadvance(2);
1756
+ i0.ɵɵtextInterpolate1("", ctx.Kpis.TotalSteps, " total steps");
1757
+ i0.ɵɵadvance();
1758
+ i0.ɵɵclassProp("kpi-card-active", ctx.Kpis.ActiveWorkflows > 0);
1759
+ i0.ɵɵadvance(8);
1760
+ i0.ɵɵtextInterpolate(ctx.Kpis.ActiveWorkflows);
1761
+ i0.ɵɵadvance(2);
1762
+ i0.ɵɵtextInterpolate(ctx.Kpis.ActiveWorkflows > 0 ? "Streaming live updates" : "All queues idle");
1763
+ i0.ɵɵadvance(9);
1764
+ i0.ɵɵtextInterpolate(ctx.Kpis.CompletedSteps);
1765
+ i0.ɵɵadvance(2);
1766
+ i0.ɵɵtextInterpolate1("of ", ctx.Kpis.TotalSteps, " steps");
1767
+ i0.ɵɵadvance(9);
1768
+ i0.ɵɵtextInterpolate1("", ctx.Kpis.SuccessRatePercent, "%");
1769
+ i0.ɵɵadvance(11);
1770
+ i0.ɵɵtextInterpolate(ctx.Kpis.AvgExecutionTimeText);
1771
+ i0.ɵɵadvance(6);
1772
+ i0.ɵɵtwoWayProperty("ngModel", ctx.SearchQuery);
1773
+ i0.ɵɵadvance();
1774
+ i0.ɵɵconditional(ctx.SearchQuery ? 86 : -1);
1775
+ i0.ɵɵadvance(2);
1776
+ i0.ɵɵclassProp("active", ctx.StatusFilter === "all");
1777
+ i0.ɵɵadvance(4);
1778
+ i0.ɵɵtextInterpolate(ctx.WorkflowGroups.length);
1779
+ i0.ɵɵadvance();
1780
+ i0.ɵɵclassProp("active", ctx.StatusFilter === "active");
1781
+ i0.ɵɵadvance(5);
1782
+ i0.ɵɵtextInterpolate(ctx.CountByCategory("active"));
400
1783
  i0.ɵɵadvance();
401
- i0.ɵɵconditional(!ctx.selectedTask ? 1 : 2);
402
- } }, dependencies: [TaskComponent], styles: [".tasks-full-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n }\n\n .task-detail-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface);\n }\n\n .swoosh-in[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_swooshIn 0.3s ease-out;\n }\n\n @keyframes _ngcontent-%COMP%_swooshIn {\n from {\n opacity: 0;\n transform: translateX(50px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n .breadcrumb-nav[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .breadcrumb-back[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .breadcrumb-back[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n }\n\n .breadcrumb-back[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .breadcrumb-divider[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 14px;\n }\n\n .breadcrumb-current[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }"] });
1784
+ i0.ɵɵclassProp("active", ctx.StatusFilter === "completed");
1785
+ i0.ɵɵadvance(5);
1786
+ i0.ɵɵtextInterpolate(ctx.CountByCategory("completed"));
1787
+ i0.ɵɵadvance();
1788
+ i0.ɵɵclassProp("active", ctx.StatusFilter === "failed");
1789
+ i0.ɵɵadvance(5);
1790
+ i0.ɵɵtextInterpolate(ctx.CountByCategory("failed"));
1791
+ i0.ɵɵadvance();
1792
+ i0.ɵɵconditional(ctx.AvailableAgents.length > 0 ? 111 : -1);
1793
+ i0.ɵɵadvance();
1794
+ i0.ɵɵclassProp("drawer-open", !!ctx.InspectedGroup);
1795
+ i0.ɵɵadvance(2);
1796
+ i0.ɵɵconditional(ctx.isLoading && ctx.WorkflowGroups.length === 0 ? 114 : ctx.FilteredWorkflowGroups.length === 0 ? 115 : ctx.CommandViewMode === "workflows" ? 116 : 117);
1797
+ i0.ɵɵadvance(4);
1798
+ i0.ɵɵconditional(ctx.InspectedGroup ? 118 : -1);
1799
+ } }, dependencies: [FormsModule, i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .tasks-command-center[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n overflow: hidden;\n }\n\n \n .cc-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 18px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .cc-header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n min-width: 0;\n }\n\n .cc-title-icon[_ngcontent-%COMP%] {\n width: 42px;\n height: 42px;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 26%, var(--mj-border-default));\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n flex-shrink: 0;\n }\n\n .cc-title-block[_ngcontent-%COMP%] {\n min-width: 0;\n }\n\n .cc-title-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .cc-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 19px;\n font-weight: 700;\n color: var(--mj-text-primary);\n letter-spacing: -0.01em;\n }\n\n .cc-live-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n }\n\n .cc-live-dot[_ngcontent-%COMP%] {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n animation: _ngcontent-%COMP%_ccPulse 1.5s infinite ease-in-out;\n }\n\n @keyframes _ngcontent-%COMP%_ccPulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.4; transform: scale(1.25); }\n }\n\n .cc-subtitle[_ngcontent-%COMP%] {\n margin: 3px 0 0 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n }\n\n .cc-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n }\n\n .cc-view-switcher[_ngcontent-%COMP%] {\n display: inline-flex;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 3px;\n gap: 2px;\n }\n\n .cc-view-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n padding: 6px 12px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .cc-view-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n }\n\n .cc-view-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n }\n\n .cc-refresh-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n padding: 7px 14px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .cc-refresh-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n }\n\n .cc-refresh-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n \n .cc-kpi-ribbon[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(5, minmax(0, 1fr));\n gap: 12px;\n padding: 14px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .cc-kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 11px 14px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n min-width: 0;\n }\n\n .cc-kpi-card.kpi-card-active[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n }\n\n .cc-kpi-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 15px;\n flex-shrink: 0;\n }\n\n .cc-kpi-icon.kpi-brand[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-kpi-icon.kpi-active[_ngcontent-%COMP%] {\n background: rgba(245, 158, 11, 0.15);\n color: #d97706;\n }\n\n .cc-kpi-icon.kpi-success[_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.15);\n color: #059669;\n }\n\n .cc-kpi-icon.kpi-rate[_ngcontent-%COMP%] {\n background: rgba(99, 102, 241, 0.15);\n color: #4f46e5;\n }\n\n .cc-kpi-icon.kpi-time[_ngcontent-%COMP%] {\n background: rgba(14, 165, 233, 0.15);\n color: #0284c7;\n }\n\n .cc-kpi-body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .cc-kpi-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n }\n\n .cc-kpi-value-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n gap: 6px;\n margin-top: 2px;\n flex-wrap: wrap;\n }\n\n .cc-kpi-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .cc-kpi-sub[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n \n .cc-filter-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n flex-wrap: wrap;\n }\n\n .cc-search-box[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n min-width: 240px;\n display: flex;\n align-items: center;\n }\n\n .cc-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n color: var(--mj-text-muted);\n font-size: 13px;\n pointer-events: none;\n }\n\n .cc-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 32px 8px 34px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .cc-search-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n }\n\n .cc-search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 8px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n }\n\n .cc-status-pills[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n }\n\n .cc-filter-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 11px;\n border-radius: 999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .cc-filter-pill[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-primary);\n }\n\n .cc-filter-pill.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n }\n\n .cc-status-dot[_ngcontent-%COMP%] {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n }\n\n .cc-status-dot.dot-active[_ngcontent-%COMP%] { background: #f59e0b; }\n .cc-status-dot.dot-completed[_ngcontent-%COMP%] { background: #10b981; }\n .cc-status-dot.dot-failed[_ngcontent-%COMP%] { background: #ef4444; }\n\n .cc-pill-count[_ngcontent-%COMP%] {\n padding: 1px 6px;\n border-radius: 999px;\n background: var(--mj-bg-surface);\n font-size: 11px;\n color: var(--mj-text-muted);\n }\n\n .cc-agent-filter[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 0 10px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n }\n\n .cc-agent-filter-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 13px;\n }\n\n .cc-agent-select[_ngcontent-%COMP%] {\n padding: 7px 4px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 12px;\n font-weight: 600;\n outline: none;\n cursor: pointer;\n }\n\n \n .cc-workspace-body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: flex;\n overflow: hidden;\n position: relative;\n }\n\n .cc-main-scroll[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n overflow-y: auto;\n padding: 20px 24px;\n }\n\n .cc-workflow-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-width: 1280px;\n margin: 0 auto;\n }\n\n .cc-workflow-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 18px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n cursor: pointer;\n }\n\n .cc-workflow-card[_ngcontent-%COMP%]:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 45%, var(--mj-border-default));\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);\n }\n\n .cc-workflow-card.card-selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n }\n\n .cc-workflow-card.card-active[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-brand-primary);\n }\n\n .cc-workflow-card.card-completed[_ngcontent-%COMP%] {\n border-left: 4px solid #10b981;\n }\n\n .cc-workflow-card.card-failed[_ngcontent-%COMP%] {\n border-left: 4px solid #ef4444;\n }\n\n .cc-wf-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n }\n\n .cc-wf-header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n min-width: 0;\n flex: 1;\n }\n\n .cc-wf-status-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 2px;\n }\n\n .cc-wf-status-icon[data-status=\"completed\"][_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.14);\n color: #059669;\n }\n\n .cc-wf-status-icon[data-status=\"active\"][_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-wf-status-icon[data-status=\"failed\"][_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.14);\n color: #dc2626;\n }\n\n .cc-wf-title-group[_ngcontent-%COMP%] {\n min-width: 0;\n flex: 1;\n }\n\n .cc-wf-title-line[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n }\n\n .cc-wf-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .cc-wf-step-count-badge[_ngcontent-%COMP%] {\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n }\n\n .cc-wf-status-badge[_ngcontent-%COMP%] {\n padding: 2px 9px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n }\n\n .cc-wf-status-badge[data-status=\"completed\"][_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.14);\n color: #059669;\n }\n\n .cc-wf-status-badge[data-status=\"active\"][_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-wf-status-badge[data-status=\"failed\"][_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.14);\n color: #dc2626;\n }\n\n .cc-wf-agent-pipeline[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: 8px;\n }\n\n .cc-agent-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 9px;\n border-radius: 6px;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 28%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .cc-agent-chip[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n }\n\n .cc-pipeline-arrow[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n }\n\n .cc-wf-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n }\n\n .cc-wf-duration[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n }\n\n .cc-wf-timestamp[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n\n .cc-wf-inspect-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n }\n\n .cc-wf-inspect-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n }\n\n \n .cc-wf-progress-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 12px 0;\n }\n\n .cc-wf-progress-track[_ngcontent-%COMP%] {\n flex: 1;\n height: 6px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n }\n\n .cc-wf-progress-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 999px;\n transition: width 0.35s ease;\n }\n\n .cc-wf-progress-fill[data-status=\"completed\"][_ngcontent-%COMP%] { background: #10b981; }\n .cc-wf-progress-fill[data-status=\"active\"][_ngcontent-%COMP%] { background: var(--mj-brand-primary); }\n .cc-wf-progress-fill[data-status=\"failed\"][_ngcontent-%COMP%] { background: #ef4444; }\n\n .cc-wf-progress-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n }\n\n \n .cc-wf-steps-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n border-top: 1px solid var(--mj-border-default);\n padding-top: 10px;\n }\n\n .cc-step-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid transparent;\n transition: all 0.15s ease;\n }\n\n .cc-step-row[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-default);\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface-sunken));\n }\n\n .cc-step-row.step-selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n }\n\n .cc-step-index[_ngcontent-%COMP%] {\n width: 22px;\n height: 22px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 700;\n flex-shrink: 0;\n margin-top: 1px;\n }\n\n .cc-step-index[data-status=\"completed\"][_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.16);\n color: #059669;\n }\n\n .cc-step-index[data-status=\"active\"][_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-step-index[data-status=\"failed\"][_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.16);\n color: #dc2626;\n }\n\n .cc-step-index[data-status=\"skipped\"][_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px dashed var(--mj-border-strong);\n color: var(--mj-text-muted);\n }\n\n .cc-step-main[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .cc-step-top-line[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n }\n\n .cc-step-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .cc-step-row[data-status=\"skipped\"][_ngcontent-%COMP%] .cc-step-name[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n }\n\n .cc-step-agent-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 1px 7px;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 600;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n }\n\n .cc-step-dep-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n }\n\n .cc-step-preview[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .cc-step-preview.preview-error[_ngcontent-%COMP%] {\n color: #dc2626;\n }\n\n .cc-step-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n }\n\n .cc-step-duration[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n }\n\n .cc-step-status-pill[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n padding: 2px 7px;\n border-radius: 999px;\n }\n\n .cc-step-status-pill[data-status=\"completed\"][_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.14);\n color: #059669;\n }\n\n .cc-step-status-pill[data-status=\"active\"][_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-step-status-pill[data-status=\"failed\"][_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.14);\n color: #dc2626;\n }\n\n .cc-step-status-pill[data-status=\"skipped\"][_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px dashed var(--mj-border-strong);\n color: var(--mj-text-muted);\n }\n\n .cc-step-run-btn[_ngcontent-%COMP%] {\n background: none;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n color: var(--mj-text-muted);\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 11px;\n }\n\n .cc-step-run-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n\n \n .cc-timeline-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-width: 1280px;\n margin: 0 auto;\n }\n\n .cc-timeline-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n }\n\n .cc-timeline-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 18px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n cursor: pointer;\n }\n\n .cc-timeline-title-wrap[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .cc-timeline-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .cc-waterfall-table[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n }\n\n .cc-waterfall-head[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 280px 170px 1fr;\n gap: 12px;\n padding: 8px 18px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .cc-waterfall-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 280px 170px 1fr;\n gap: 12px;\n align-items: center;\n padding: 10px 18px;\n border-bottom: 1px solid var(--mj-border-default);\n cursor: pointer;\n transition: background 0.12s ease;\n }\n\n .cc-waterfall-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n }\n\n .cc-waterfall-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .cc-waterfall-row.step-selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n }\n\n .cc-wf-col-step[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n min-width: 0;\n }\n\n .cc-waterfall-step-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .cc-waterfall-dep[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n\n .cc-waterfall-track[_ngcontent-%COMP%] {\n position: relative;\n height: 26px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n overflow: hidden;\n }\n\n .cc-waterfall-bar[_ngcontent-%COMP%] {\n position: absolute;\n top: 3px;\n bottom: 3px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n padding: 0 8px;\n min-width: 64px;\n white-space: nowrap;\n font-size: 11px;\n font-weight: 600;\n }\n\n .cc-waterfall-bar[data-status=\"completed\"][_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.2);\n border: 1px solid rgba(16, 185, 129, 0.5);\n color: #047857;\n }\n\n .cc-waterfall-bar[data-status=\"active\"][_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n }\n\n .cc-waterfall-bar[data-status=\"failed\"][_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.2);\n border: 1px solid rgba(239, 68, 68, 0.5);\n color: #b91c1c;\n }\n\n .cc-waterfall-bar[data-status=\"skipped\"][_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px dashed var(--mj-border-strong);\n color: var(--mj-text-muted);\n }\n\n \n .cc-inspector-drawer[_ngcontent-%COMP%] {\n width: 440px;\n max-width: 46%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n box-shadow: -4px 0 18px rgba(0, 0, 0, 0.06);\n animation: _ngcontent-%COMP%_ccSlideIn 0.2s ease-out;\n }\n\n @keyframes _ngcontent-%COMP%_ccSlideIn {\n from { opacity: 0; transform: translateX(24px); }\n to { opacity: 1; transform: translateX(0); }\n }\n\n .cc-drawer-header[_ngcontent-%COMP%] {\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .cc-drawer-header-top[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 6px;\n }\n\n .cc-drawer-eyebrow[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-brand-primary);\n display: inline-flex;\n align-items: center;\n gap: 6px;\n }\n\n .cc-drawer-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n width: 28px;\n height: 28px;\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .cc-drawer-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n }\n\n .cc-drawer-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.35;\n }\n\n .cc-drawer-step-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n overflow-x: auto;\n margin-top: 12px;\n padding-bottom: 2px;\n }\n\n .cc-drawer-step-tab[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n max-width: 180px;\n white-space: nowrap;\n }\n\n .cc-drawer-step-tab.active[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .cc-tab-num[_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n flex-shrink: 0;\n }\n\n .cc-tab-label[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .cc-drawer-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 18px 20px;\n display: flex;\n flex-direction: column;\n gap: 18px;\n }\n\n .cc-drawer-metrics-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 10px;\n }\n\n .cc-drawer-metric-box[_ngcontent-%COMP%] {\n padding: 10px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n gap: 4px;\n align-items: flex-start;\n }\n\n .cc-drawer-metric-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n }\n\n .cc-drawer-metric-val[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .cc-drawer-progress-bar[_ngcontent-%COMP%] {\n height: 8px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n }\n\n .cc-drawer-progress-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 999px;\n transition: width 0.3s ease;\n }\n\n .cc-drawer-progress-fill[data-status=\"completed\"][_ngcontent-%COMP%] { background: #10b981; }\n .cc-drawer-progress-fill[data-status=\"active\"][_ngcontent-%COMP%] { background: var(--mj-brand-primary); }\n .cc-drawer-progress-fill[data-status=\"failed\"][_ngcontent-%COMP%] { background: #ef4444; }\n\n .cc-drawer-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .cc-drawer-section-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .cc-drawer-section-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-muted);\n }\n\n .cc-drawer-links-stack[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .cc-drawer-link-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n cursor: pointer;\n text-align: left;\n transition: all 0.15s ease;\n }\n\n .cc-drawer-link-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n }\n\n .cc-link-card-icon[_ngcontent-%COMP%] {\n width: 34px;\n height: 34px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 15px;\n flex-shrink: 0;\n }\n\n .cc-link-card-body[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n }\n\n .cc-link-card-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n }\n\n .cc-link-card-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .cc-link-card-ext[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n\n .cc-drawer-deps-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n }\n\n .cc-drawer-dep-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n font-size: 12px;\n color: var(--mj-text-secondary);\n }\n\n .cc-drawer-timestamps[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n }\n\n .cc-ts-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n }\n\n .cc-ts-label[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-weight: 600; }\n .cc-ts-val[_ngcontent-%COMP%] { color: var(--mj-text-primary); font-variant-numeric: tabular-nums; }\n\n .cc-drawer-text-box[_ngcontent-%COMP%] {\n padding: 12px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n font-size: 13px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .cc-drawer-output-box[_ngcontent-%COMP%] {\n padding: 12px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n font-size: 13px;\n line-height: 1.6;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 360px;\n overflow-y: auto;\n }\n\n .cc-drawer-output-box.output-error[_ngcontent-%COMP%] {\n border-color: #ef4444;\n color: #dc2626;\n }\n\n .cc-copy-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n border-radius: 5px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n }\n\n \n .cc-empty-state[_ngcontent-%COMP%] {\n max-width: 460px;\n margin: 64px auto;\n text-align: center;\n padding: 32px 24px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 14px;\n }\n\n .cc-empty-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n border-radius: 12px;\n margin: 0 auto 14px auto;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n }\n\n .cc-empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .cc-empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n line-height: 1.55;\n color: var(--mj-text-secondary);\n }\n\n .cc-reset-filters-btn[_ngcontent-%COMP%] {\n margin-top: 14px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n border-radius: 8px;\n border: 1px solid var(--mj-brand-primary);\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n }"] });
403
1800
  }
404
1801
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TasksFullViewComponent, [{
405
1802
  type: Component,
406
- args: [{ selector: 'mj-tasks-full-view', standalone: true, imports: [TaskComponent], template: `
407
- <div class="tasks-full-view">
408
- @if (!selectedTask) {
409
- <!-- Task List View -->
410
- <mj-task
411
- [tasks]="filteredTasks"
412
- [title]="'Tasks'"
413
- [description]="getDescription()"
414
- [showHeader]="true"
415
- [showViewToggle]="false"
416
- [viewMode]="'simple'"
417
- (taskClicked)="onTaskClick($event)">
418
- </mj-task>
419
- } @else {
420
- <!-- Task Detail View with Sub-tasks -->
421
- <div class="task-detail-view" [class.swoosh-in]="showDetailAnimation">
422
- <!-- Breadcrumb -->
423
- <div class="breadcrumb-nav">
424
- <button class="breadcrumb-back" (click)="backToTaskList()">
425
- <i class="fas fa-arrow-left"></i>
426
- <span>Back to Tasks</span>
1803
+ args: [{ selector: 'mj-tasks-full-view', standalone: true, imports: [FormsModule], template: `
1804
+ <div class="tasks-command-center">
1805
+ <!-- Top Command Center Header -->
1806
+ <header class="cc-header">
1807
+ <div class="cc-header-left">
1808
+ <div class="cc-title-icon">
1809
+ <i class="fa-solid fa-diagram-project"></i>
1810
+ </div>
1811
+ <div class="cc-title-block">
1812
+ <div class="cc-title-row">
1813
+ <h1 class="cc-title">AI Agent Workflows &amp; Tasks</h1>
1814
+ @if (Kpis.ActiveWorkflows > 0) {
1815
+ <span class="cc-live-pill">
1816
+ <span class="cc-live-dot"></span>
1817
+ {{ Kpis.ActiveWorkflows }} Running Live
1818
+ </span>
1819
+ }
1820
+ </div>
1821
+ <p class="cc-subtitle">
1822
+ Real-time multi-agent task orchestration, step dependencies &amp; execution telemetry
1823
+ </p>
1824
+ </div>
1825
+ </div>
1826
+
1827
+ <div class="cc-header-actions">
1828
+ <!-- View Mode Switcher -->
1829
+ <div class="cc-view-switcher" role="tablist" aria-label="View Mode">
1830
+ <button
1831
+ type="button"
1832
+ class="cc-view-btn"
1833
+ [class.active]="CommandViewMode === 'workflows'"
1834
+ (click)="SetCommandViewMode('workflows')">
1835
+ <i class="fa-solid fa-layer-group"></i>
1836
+ <span>Workflow Cards</span>
1837
+ </button>
1838
+ <button
1839
+ type="button"
1840
+ class="cc-view-btn"
1841
+ [class.active]="CommandViewMode === 'timeline'"
1842
+ (click)="SetCommandViewMode('timeline')">
1843
+ <i class="fa-solid fa-bars-staggered"></i>
1844
+ <span>Execution Timeline &amp; DAG</span>
1845
+ </button>
1846
+ </div>
1847
+
1848
+ <button
1849
+ type="button"
1850
+ class="cc-refresh-btn"
1851
+ [disabled]="isLoading"
1852
+ (click)="LoadTasks()"
1853
+ title="Refresh workflows and tasks">
1854
+ <i class="fa-solid fa-arrows-rotate" [class.fa-spin]="isLoading"></i>
1855
+ <span>Refresh</span>
1856
+ </button>
1857
+ </div>
1858
+ </header>
1859
+
1860
+ <!-- KPI Metric Ribbon -->
1861
+ <section class="cc-kpi-ribbon" aria-label="Workflow Metrics">
1862
+ <div class="cc-kpi-card">
1863
+ <div class="cc-kpi-icon kpi-brand">
1864
+ <i class="fa-solid fa-sitemap"></i>
1865
+ </div>
1866
+ <div class="cc-kpi-body">
1867
+ <span class="cc-kpi-label">Total Workflows</span>
1868
+ <div class="cc-kpi-value-row">
1869
+ <span class="cc-kpi-value">{{ Kpis.TotalWorkflows }}</span>
1870
+ <span class="cc-kpi-sub">{{ Kpis.TotalSteps }} total steps</span>
1871
+ </div>
1872
+ </div>
1873
+ </div>
1874
+
1875
+ <div class="cc-kpi-card" [class.kpi-card-active]="Kpis.ActiveWorkflows > 0">
1876
+ <div class="cc-kpi-icon kpi-active">
1877
+ <i class="fa-solid fa-bolt"></i>
1878
+ </div>
1879
+ <div class="cc-kpi-body">
1880
+ <span class="cc-kpi-label">Active / Running</span>
1881
+ <div class="cc-kpi-value-row">
1882
+ <span class="cc-kpi-value">{{ Kpis.ActiveWorkflows }}</span>
1883
+ <span class="cc-kpi-sub">{{ Kpis.ActiveWorkflows > 0 ? 'Streaming live updates' : 'All queues idle' }}</span>
1884
+ </div>
1885
+ </div>
1886
+ </div>
1887
+
1888
+ <div class="cc-kpi-card">
1889
+ <div class="cc-kpi-icon kpi-success">
1890
+ <i class="fa-solid fa-circle-check"></i>
1891
+ </div>
1892
+ <div class="cc-kpi-body">
1893
+ <span class="cc-kpi-label">Completed Steps</span>
1894
+ <div class="cc-kpi-value-row">
1895
+ <span class="cc-kpi-value">{{ Kpis.CompletedSteps }}</span>
1896
+ <span class="cc-kpi-sub">of {{ Kpis.TotalSteps }} steps</span>
1897
+ </div>
1898
+ </div>
1899
+ </div>
1900
+
1901
+ <div class="cc-kpi-card">
1902
+ <div class="cc-kpi-icon kpi-rate">
1903
+ <i class="fa-solid fa-chart-line"></i>
1904
+ </div>
1905
+ <div class="cc-kpi-body">
1906
+ <span class="cc-kpi-label">Success Rate</span>
1907
+ <div class="cc-kpi-value-row">
1908
+ <span class="cc-kpi-value">{{ Kpis.SuccessRatePercent }}%</span>
1909
+ <span class="cc-kpi-sub">terminal reliability</span>
1910
+ </div>
1911
+ </div>
1912
+ </div>
1913
+
1914
+ <div class="cc-kpi-card">
1915
+ <div class="cc-kpi-icon kpi-time">
1916
+ <i class="fa-solid fa-stopwatch"></i>
1917
+ </div>
1918
+ <div class="cc-kpi-body">
1919
+ <span class="cc-kpi-label">Avg Execution Time</span>
1920
+ <div class="cc-kpi-value-row">
1921
+ <span class="cc-kpi-value">{{ Kpis.AvgExecutionTimeText }}</span>
1922
+ <span class="cc-kpi-sub">per completed workflow</span>
1923
+ </div>
1924
+ </div>
1925
+ </div>
1926
+ </section>
1927
+
1928
+ <!-- Filter & Search Bar -->
1929
+ <section class="cc-filter-bar">
1930
+ <div class="cc-search-box">
1931
+ <i class="fa-solid fa-magnifying-glass cc-search-icon"></i>
1932
+ <input
1933
+ type="text"
1934
+ class="cc-search-input"
1935
+ placeholder="Search workflows, step names, specialist agents, or outputs..."
1936
+ [(ngModel)]="SearchQuery"
1937
+ (ngModelChange)="OnFilterCriteriaChanged()" />
1938
+ @if (SearchQuery) {
1939
+ <button type="button" class="cc-search-clear" (click)="ClearSearch()" title="Clear search">
1940
+ <i class="fa-solid fa-xmark"></i>
427
1941
  </button>
428
- <div class="breadcrumb-divider">/</div>
429
- <span class="breadcrumb-current">{{ selectedTask.Name }}</span>
1942
+ }
1943
+ </div>
1944
+
1945
+ <div class="cc-status-pills" role="group" aria-label="Filter by status">
1946
+ <button
1947
+ type="button"
1948
+ class="cc-filter-pill"
1949
+ [class.active]="StatusFilter === 'all'"
1950
+ (click)="SetStatusFilter('all')">
1951
+ <span>All</span>
1952
+ <span class="cc-pill-count">{{ WorkflowGroups.length }}</span>
1953
+ </button>
1954
+ <button
1955
+ type="button"
1956
+ class="cc-filter-pill pill-active"
1957
+ [class.active]="StatusFilter === 'active'"
1958
+ (click)="SetStatusFilter('active')">
1959
+ <span class="cc-status-dot dot-active"></span>
1960
+ <span>Active</span>
1961
+ <span class="cc-pill-count">{{ CountByCategory('active') }}</span>
1962
+ </button>
1963
+ <button
1964
+ type="button"
1965
+ class="cc-filter-pill pill-completed"
1966
+ [class.active]="StatusFilter === 'completed'"
1967
+ (click)="SetStatusFilter('completed')">
1968
+ <span class="cc-status-dot dot-completed"></span>
1969
+ <span>Completed</span>
1970
+ <span class="cc-pill-count">{{ CountByCategory('completed') }}</span>
1971
+ </button>
1972
+ <button
1973
+ type="button"
1974
+ class="cc-filter-pill pill-failed"
1975
+ [class.active]="StatusFilter === 'failed'"
1976
+ (click)="SetStatusFilter('failed')">
1977
+ <span class="cc-status-dot dot-failed"></span>
1978
+ <span>Failed</span>
1979
+ <span class="cc-pill-count">{{ CountByCategory('failed') }}</span>
1980
+ </button>
1981
+ </div>
1982
+
1983
+ @if (AvailableAgents.length > 0) {
1984
+ <div class="cc-agent-filter">
1985
+ <i class="fa-solid fa-robot cc-agent-filter-icon"></i>
1986
+ <select
1987
+ class="cc-agent-select"
1988
+ [ngModel]="SelectedAgentFilter"
1989
+ (ngModelChange)="SetAgentFilter($event)"
1990
+ aria-label="Filter by specialist agent">
1991
+ <option value="all">All Specialist Agents ({{ AvailableAgents.length }})</option>
1992
+ @for (ag of AvailableAgents; track ag.id) {
1993
+ <option [value]="ag.id">{{ ag.name }} ({{ ag.count }})</option>
1994
+ }
1995
+ </select>
430
1996
  </div>
1997
+ }
1998
+ </section>
1999
+
2000
+ <!-- Main Body: Content List + Slide-Over Inspector Drawer -->
2001
+ <div class="cc-workspace-body" [class.drawer-open]="!!InspectedGroup">
2002
+ <div class="cc-main-scroll">
2003
+ @if (isLoading && WorkflowGroups.length === 0) {
2004
+ <div class="cc-empty-state">
2005
+ <div class="cc-empty-icon">
2006
+ <i class="fa-solid fa-circle-notch fa-spin"></i>
2007
+ </div>
2008
+ <h3>Loading AI Agent Workflows...</h3>
2009
+ <p>Fetching orchestrated task graphs, specialist agent steps, and execution telemetry.</p>
2010
+ </div>
2011
+ } @else if (FilteredWorkflowGroups.length === 0) {
2012
+ <div class="cc-empty-state">
2013
+ <div class="cc-empty-icon">
2014
+ <i class="fa-solid fa-diagram-project"></i>
2015
+ </div>
2016
+ @if (WorkflowGroups.length === 0) {
2017
+ <h3>No Agent Workflows Recorded Yet</h3>
2018
+ <p>When Sage or other orchestrator agents launch multi-step task graphs in Chat, their live progress, specialist delegations, and outputs will appear here.</p>
2019
+ } @else {
2020
+ <h3>No Workflows Match Your Filters</h3>
2021
+ <p>Try clearing your search query or switching the status / specialist agent filter.</p>
2022
+ <button type="button" class="cc-reset-filters-btn" (click)="ResetAllFilters()">
2023
+ <i class="fa-solid fa-rotate-left"></i>
2024
+ <span>Reset Filters</span>
2025
+ </button>
2026
+ }
2027
+ </div>
2028
+ } @else if (CommandViewMode === 'workflows') {
2029
+ <!-- VIEW MODE 1: HIERARCHY-AWARE WORKFLOW CARDS -->
2030
+ <div class="cc-workflow-grid">
2031
+ @for (group of FilteredWorkflowGroups; track group.RootTaskId) {
2032
+ <article
2033
+ class="cc-workflow-card"
2034
+ [class.card-active]="group.NormalizedCategory === 'active'"
2035
+ [class.card-completed]="group.NormalizedCategory === 'completed'"
2036
+ [class.card-failed]="group.NormalizedCategory === 'failed'"
2037
+ [class.card-selected]="IsGroupInspected(group)"
2038
+ (click)="InspectWorkflowGroup(group)">
2039
+
2040
+ <!-- Workflow Card Header -->
2041
+ <div class="cc-wf-header">
2042
+ <div class="cc-wf-header-left">
2043
+ <div class="cc-wf-status-icon" [attr.data-status]="group.NormalizedCategory">
2044
+ @if (group.NormalizedCategory === 'completed') {
2045
+ <i class="fa-solid fa-check"></i>
2046
+ } @else if (group.NormalizedCategory === 'active') {
2047
+ <i class="fa-solid fa-circle-notch fa-spin"></i>
2048
+ } @else {
2049
+ <i class="fa-solid fa-triangle-exclamation"></i>
2050
+ }
2051
+ </div>
2052
+
2053
+ <div class="cc-wf-title-group">
2054
+ <div class="cc-wf-title-line">
2055
+ <h3 class="cc-wf-title">{{ group.Title }}</h3>
2056
+ <span class="cc-wf-step-count-badge">
2057
+ {{ group.TotalSteps }} {{ group.TotalSteps === 1 ? 'Step' : 'Steps' }}
2058
+ </span>
2059
+ <span class="cc-wf-status-badge" [attr.data-status]="group.NormalizedCategory">
2060
+ {{ group.Status }}
2061
+ </span>
2062
+ </div>
2063
+
2064
+ <!-- Agent Pipeline Chips -->
2065
+ @if (group.AgentPipeline.length > 0) {
2066
+ <div class="cc-wf-agent-pipeline">
2067
+ @for (ag of group.AgentPipeline; track ag.id; let isLast = $last) {
2068
+ <button
2069
+ type="button"
2070
+ class="cc-agent-chip"
2071
+ (click)="OnAgentChipClicked($event, ag.id)"
2072
+ title="Inspect {{ ag.name }}">
2073
+ <i class="fa-solid fa-robot"></i>
2074
+ <span>{{ ag.name }}</span>
2075
+ </button>
2076
+ @if (!isLast) {
2077
+ <i class="fa-solid fa-arrow-right cc-pipeline-arrow"></i>
2078
+ }
2079
+ }
2080
+ </div>
2081
+ }
2082
+ </div>
2083
+ </div>
431
2084
 
432
- <!-- Task Details & Sub-tasks with Gantt Toggle -->
433
- <mj-task
434
- [tasks]="subTasks"
435
- [ganttTasks]="subTasksWithParent"
436
- [taskDependencies]="taskDependencies"
437
- [agentRunMap]="agentRunMap"
438
- [title]="selectedTask.Name"
439
- [description]="getTaskDetailDescription()"
440
- [showHeader]="true"
441
- [showViewToggle]="true"
442
- [viewMode]="'gantt'"
443
- (taskClicked)="onSubTaskClick($event)"
444
- (openEntityRecord)="onOpenEntityRecord($event)">
445
- </mj-task>
2085
+ <div class="cc-wf-header-right">
2086
+ @if (group.DurationText) {
2087
+ <span class="cc-wf-duration" title="Total workflow execution duration">
2088
+ <i class="fa-regular fa-clock"></i>
2089
+ {{ group.DurationText }}
2090
+ </span>
2091
+ }
2092
+ <span class="cc-wf-timestamp">{{ group.RelativeTimeText }}</span>
2093
+ <button
2094
+ type="button"
2095
+ class="cc-wf-inspect-btn"
2096
+ (click)="InspectWorkflowGroup(group, undefined, $event)"
2097
+ title="Open Workflow Inspector">
2098
+ <span>Inspect</span>
2099
+ <i class="fa-solid fa-chevron-right"></i>
2100
+ </button>
2101
+ </div>
2102
+ </div>
2103
+
2104
+ <!-- Progress Bar -->
2105
+ <div class="cc-wf-progress-row">
2106
+ <div class="cc-wf-progress-track">
2107
+ <div
2108
+ class="cc-wf-progress-fill"
2109
+ [attr.data-status]="group.NormalizedCategory"
2110
+ [style.width.%]="group.PercentComplete">
2111
+ </div>
2112
+ </div>
2113
+ <span class="cc-wf-progress-label">
2114
+ {{ group.CompletedSteps }} of {{ group.TotalSteps }} completed
2115
+ @if (group.SkippedSteps > 0) {
2116
+ &middot; {{ group.SkippedSteps }} skipped
2117
+ }
2118
+ &middot; {{ group.PercentComplete }}%
2119
+ </span>
2120
+ </div>
2121
+
2122
+ <!-- Step Pipeline List inside Card -->
2123
+ <div class="cc-wf-steps-list">
2124
+ @for (step of group.Steps; track step.Task.ID) {
2125
+ <div
2126
+ class="cc-step-row"
2127
+ [class.step-selected]="IsStepInspected(step.Task)"
2128
+ [attr.data-status]="GetStepCategory(step.Task.Status)"
2129
+ (click)="InspectWorkflowGroup(group, step, $event)">
2130
+
2131
+ <div class="cc-step-index" [attr.data-status]="GetStepCategory(step.Task.Status)">
2132
+ @if (step.Task.Status === 'Complete') {
2133
+ <i class="fa-solid fa-check"></i>
2134
+ } @else if (step.Task.Status === 'In Progress') {
2135
+ <i class="fa-solid fa-spinner fa-spin"></i>
2136
+ } @else if (step.Task.Status === 'Skipped') {
2137
+ <i class="fa-solid fa-forward-step"></i>
2138
+ } @else if (step.Task.Status === 'Failed' || step.Task.Status === 'Cancelled') {
2139
+ <i class="fa-solid fa-xmark"></i>
2140
+ } @else {
2141
+ <span>{{ step.StepNumber }}</span>
2142
+ }
2143
+ </div>
2144
+
2145
+ <div class="cc-step-main">
2146
+ <div class="cc-step-top-line">
2147
+ <span class="cc-step-name">{{ step.Task.Name }}</span>
2148
+
2149
+ @if (step.AgentName) {
2150
+ <span class="cc-step-agent-tag">
2151
+ <i class="fa-solid fa-robot"></i>
2152
+ {{ step.AgentName }}
2153
+ </span>
2154
+ }
2155
+
2156
+ @if (step.DependsOnNames.length > 0) {
2157
+ <span class="cc-step-dep-tag" title="Waits for: {{ step.DependsOnNames.join(', ') }}">
2158
+ <i class="fa-solid fa-link"></i>
2159
+ After {{ step.DependsOnNames.join(', ') }}
2160
+ </span>
2161
+ }
2162
+ </div>
2163
+
2164
+ @if (step.OutputPreview) {
2165
+ <p class="cc-step-preview" [class.preview-error]="step.IsErrorOutput">
2166
+ {{ step.OutputPreview }}
2167
+ </p>
2168
+ }
2169
+ </div>
2170
+
2171
+ <div class="cc-step-right">
2172
+ @if (step.DurationText) {
2173
+ <span class="cc-step-duration">{{ step.DurationText }}</span>
2174
+ }
2175
+ <span class="cc-step-status-pill" [attr.data-status]="GetStepCategory(step.Task.Status)">
2176
+ {{ step.Task.Status }}
2177
+ </span>
2178
+ @if (step.AgentRunID) {
2179
+ <button
2180
+ type="button"
2181
+ class="cc-step-run-btn"
2182
+ (click)="OnOpenAgentRunClicked($event, step.AgentRunID)"
2183
+ title="Open AI Agent Run Telemetry">
2184
+ <i class="fa-solid fa-arrow-up-right-from-square"></i>
2185
+ </button>
2186
+ }
2187
+ </div>
2188
+ </div>
2189
+ }
2190
+ </div>
2191
+ </article>
2192
+ }
2193
+ </div>
2194
+ } @else {
2195
+ <!-- VIEW MODE 2: EXECUTION TIMELINE & DEPENDENCY DAG WATERFALL -->
2196
+ <div class="cc-timeline-list">
2197
+ @for (group of FilteredWorkflowGroups; track group.RootTaskId) {
2198
+ <section
2199
+ class="cc-timeline-card"
2200
+ [class.card-selected]="IsGroupInspected(group)">
2201
+ <div class="cc-timeline-card-header" (click)="InspectWorkflowGroup(group)">
2202
+ <div class="cc-timeline-title-wrap">
2203
+ <span class="cc-wf-status-badge" [attr.data-status]="group.NormalizedCategory">
2204
+ {{ group.Status }}
2205
+ </span>
2206
+ <h3 class="cc-wf-title">{{ group.Title }}</h3>
2207
+ <span class="cc-wf-step-count-badge">{{ group.TotalSteps }} Steps</span>
2208
+ </div>
2209
+ <div class="cc-timeline-meta">
2210
+ @if (group.DurationText) {
2211
+ <span class="cc-wf-duration">
2212
+ <i class="fa-solid fa-stopwatch"></i>
2213
+ Total: {{ group.DurationText }}
2214
+ </span>
2215
+ }
2216
+ <span class="cc-wf-timestamp">{{ group.RelativeTimeText }}</span>
2217
+ </div>
2218
+ </div>
2219
+
2220
+ <div class="cc-waterfall-table">
2221
+ <div class="cc-waterfall-head">
2222
+ <div class="cc-wf-col-step">Workflow Step &amp; Dependencies</div>
2223
+ <div class="cc-wf-col-agent">Specialist Agent</div>
2224
+ <div class="cc-wf-col-bars">
2225
+ <span>Execution Waterfall (0s &rarr; {{ group.DurationText || 'Live' }})</span>
2226
+ </div>
2227
+ </div>
2228
+
2229
+ @for (step of group.Steps; track step.Task.ID) {
2230
+ <div
2231
+ class="cc-waterfall-row"
2232
+ [class.step-selected]="IsStepInspected(step.Task)"
2233
+ (click)="InspectWorkflowGroup(group, step, $event)">
2234
+ <div class="cc-wf-col-step">
2235
+ <span class="cc-step-index" [attr.data-status]="GetStepCategory(step.Task.Status)">
2236
+ {{ step.StepNumber }}
2237
+ </span>
2238
+ <div class="cc-waterfall-step-text">
2239
+ <span class="cc-step-name">{{ step.Task.Name }}</span>
2240
+ @if (step.DependsOnNames.length > 0) {
2241
+ <span class="cc-waterfall-dep">
2242
+ <i class="fa-solid fa-turn-up fa-rotate-90"></i>
2243
+ Depends on: {{ step.DependsOnNames.join(', ') }}
2244
+ </span>
2245
+ }
2246
+ </div>
2247
+ </div>
2248
+
2249
+ <div class="cc-wf-col-agent">
2250
+ @if (step.AgentName) {
2251
+ <span class="cc-step-agent-tag">
2252
+ <i class="fa-solid fa-robot"></i>
2253
+ {{ step.AgentName }}
2254
+ </span>
2255
+ } @else {
2256
+ <span class="cc-text-muted">Orchestrator</span>
2257
+ }
2258
+ </div>
2259
+
2260
+ <div class="cc-wf-col-bars">
2261
+ <div class="cc-waterfall-track">
2262
+ <div
2263
+ class="cc-waterfall-bar"
2264
+ [attr.data-status]="GetStepCategory(step.Task.Status)"
2265
+ [style.left.%]="step.TimelineOffsetPercent"
2266
+ [style.width.%]="step.TimelineWidthPercent">
2267
+ <span class="cc-waterfall-bar-label">
2268
+ {{ step.StartOffsetLabel }} &middot; {{ step.DurationText || step.Task.Status }}
2269
+ </span>
2270
+ </div>
2271
+ </div>
2272
+ </div>
2273
+ </div>
2274
+ }
2275
+ </div>
2276
+ </section>
2277
+ }
2278
+ </div>
2279
+ }
446
2280
  </div>
447
- }
2281
+
2282
+ <!-- SLIDE-OVER WORKFLOW & STEP INSPECTOR DRAWER -->
2283
+ @if (InspectedGroup) {
2284
+ <aside class="cc-inspector-drawer" aria-label="Workflow and Step Inspector">
2285
+ <div class="cc-drawer-header">
2286
+ <div class="cc-drawer-header-top">
2287
+ <span class="cc-drawer-eyebrow">
2288
+ <i class="fa-solid fa-microscope"></i>
2289
+ {{ InspectedStep ? 'Step ' + InspectedStep.StepNumber + ' of ' + InspectedGroup.TotalSteps : 'Workflow Overview' }}
2290
+ </span>
2291
+ <button
2292
+ type="button"
2293
+ class="cc-drawer-close"
2294
+ (click)="BackToTaskList()"
2295
+ title="Close Inspector">
2296
+ <i class="fa-solid fa-xmark"></i>
2297
+ </button>
2298
+ </div>
2299
+
2300
+ <h2 class="cc-drawer-title">
2301
+ {{ InspectedStep ? InspectedStep.Task.Name : InspectedGroup.Title }}
2302
+ </h2>
2303
+
2304
+ <!-- Step Switcher Pills inside Drawer -->
2305
+ @if (InspectedGroup.Steps.length > 1) {
2306
+ <div class="cc-drawer-step-tabs">
2307
+ @for (s of InspectedGroup.Steps; track s.Task.ID) {
2308
+ <button
2309
+ type="button"
2310
+ class="cc-drawer-step-tab"
2311
+ [class.active]="IsStepInspected(s.Task)"
2312
+ (click)="SelectInspectorStep(s)">
2313
+ <span class="cc-tab-num">{{ s.StepNumber }}</span>
2314
+ <span class="cc-tab-label">{{ s.Task.Name }}</span>
2315
+ </button>
2316
+ }
2317
+ </div>
2318
+ }
2319
+ </div>
2320
+
2321
+ <div class="cc-drawer-content">
2322
+ @if (InspectedStep; as activeStep) {
2323
+ <!-- Status + Progress + Duration Summary -->
2324
+ <div class="cc-drawer-metrics-grid">
2325
+ <div class="cc-drawer-metric-box">
2326
+ <span class="cc-drawer-metric-label">Status</span>
2327
+ <span class="cc-wf-status-badge" [attr.data-status]="GetStepCategory(activeStep.Task.Status)">
2328
+ {{ activeStep.Task.Status }}
2329
+ </span>
2330
+ </div>
2331
+ <div class="cc-drawer-metric-box">
2332
+ <span class="cc-drawer-metric-label">Duration</span>
2333
+ <span class="cc-drawer-metric-val">{{ activeStep.DurationText || '—' }}</span>
2334
+ </div>
2335
+ <div class="cc-drawer-metric-box">
2336
+ <span class="cc-drawer-metric-label">Completion</span>
2337
+ <span class="cc-drawer-metric-val">{{ activeStep.Task.PercentComplete ?? 0 }}%</span>
2338
+ </div>
2339
+ </div>
2340
+
2341
+ <div class="cc-drawer-progress-bar">
2342
+ <div
2343
+ class="cc-drawer-progress-fill"
2344
+ [attr.data-status]="GetStepCategory(activeStep.Task.Status)"
2345
+ [style.width.%]="activeStep.Task.PercentComplete ?? 0">
2346
+ </div>
2347
+ </div>
2348
+
2349
+ <!-- Specialist Agent & AI Agent Run Deep Links -->
2350
+ <div class="cc-drawer-section">
2351
+ <h4 class="cc-drawer-section-title">Execution &amp; Telemetry Links</h4>
2352
+ <div class="cc-drawer-links-stack">
2353
+ @if (activeStep.AgentID && activeStep.AgentName) {
2354
+ <button
2355
+ type="button"
2356
+ class="cc-drawer-link-card"
2357
+ (click)="OnAgentChipClicked($event, activeStep.AgentID)">
2358
+ <div class="cc-link-card-icon">
2359
+ <i class="fa-solid fa-robot"></i>
2360
+ </div>
2361
+ <div class="cc-link-card-body">
2362
+ <span class="cc-link-card-label">Assigned Specialist Agent</span>
2363
+ <span class="cc-link-card-title">{{ activeStep.AgentName }}</span>
2364
+ </div>
2365
+ <i class="fa-solid fa-arrow-up-right-from-square cc-link-card-ext"></i>
2366
+ </button>
2367
+ }
2368
+
2369
+ @if (activeStep.AgentRunID) {
2370
+ <button
2371
+ type="button"
2372
+ class="cc-drawer-link-card"
2373
+ (click)="OnOpenAgentRunClicked($event, activeStep.AgentRunID)">
2374
+ <div class="cc-link-card-icon run-icon">
2375
+ <i class="fa-solid fa-gauge-high"></i>
2376
+ </div>
2377
+ <div class="cc-link-card-body">
2378
+ <span class="cc-link-card-label">AI Agent Run Trace</span>
2379
+ <span class="cc-link-card-title">Open Full Step &amp; Prompt Run Log</span>
2380
+ </div>
2381
+ <i class="fa-solid fa-arrow-up-right-from-square cc-link-card-ext"></i>
2382
+ </button>
2383
+ }
2384
+ </div>
2385
+ </div>
2386
+
2387
+ <!-- Dependencies -->
2388
+ @if (activeStep.DependsOnNames.length > 0) {
2389
+ <div class="cc-drawer-section">
2390
+ <h4 class="cc-drawer-section-title">Prerequisite Dependencies</h4>
2391
+ <div class="cc-drawer-deps-list">
2392
+ @for (depName of activeStep.DependsOnNames; track depName) {
2393
+ <span class="cc-drawer-dep-pill">
2394
+ <i class="fa-solid fa-code-commit"></i>
2395
+ {{ depName }}
2396
+ </span>
2397
+ }
2398
+ @for (cond of activeStep.DependsOnConditions; track cond) {
2399
+ <span class="cc-drawer-dep-pill">
2400
+ <i class="fa-solid fa-code-branch"></i>
2401
+ if {{ cond }}
2402
+ </span>
2403
+ }
2404
+ </div>
2405
+ </div>
2406
+ }
2407
+
2408
+ <!-- Timestamps -->
2409
+ <div class="cc-drawer-section">
2410
+ <h4 class="cc-drawer-section-title">Timeline</h4>
2411
+ <div class="cc-drawer-timestamps">
2412
+ @if (activeStep.Task.StartedAt) {
2413
+ <div class="cc-ts-row">
2414
+ <span class="cc-ts-label">Started</span>
2415
+ <span class="cc-ts-val">{{ FormatDateTime(activeStep.Task.StartedAt) }}</span>
2416
+ </div>
2417
+ }
2418
+ @if (activeStep.Task.CompletedAt) {
2419
+ <div class="cc-ts-row">
2420
+ <span class="cc-ts-label">Completed</span>
2421
+ <span class="cc-ts-val">{{ FormatDateTime(activeStep.Task.CompletedAt) }}</span>
2422
+ </div>
2423
+ }
2424
+ </div>
2425
+ </div>
2426
+
2427
+ <!-- Task Instructions -->
2428
+ @if (activeStep.Instructions) {
2429
+ <div class="cc-drawer-section">
2430
+ <h4 class="cc-drawer-section-title">Step Instructions</h4>
2431
+ <div class="cc-drawer-text-box">{{ activeStep.Instructions }}</div>
2432
+ </div>
2433
+ }
2434
+
2435
+ <!-- Agent Output / Error Details -->
2436
+ @if (activeStep.Output) {
2437
+ <div class="cc-drawer-section">
2438
+ <div class="cc-drawer-section-head">
2439
+ <h4 class="cc-drawer-section-title">
2440
+ {{ activeStep.IsErrorOutput ? 'Error Diagnostics' : 'Specialist Agent Output' }}
2441
+ </h4>
2442
+ <button
2443
+ type="button"
2444
+ class="cc-copy-btn"
2445
+ (click)="CopyStepOutput(activeStep.Output)"
2446
+ title="Copy output to clipboard">
2447
+ <i class="fa-regular" [class.fa-copy]="!CopiedOutput" [class.fa-check]="CopiedOutput"></i>
2448
+ <span>{{ CopiedOutput ? 'Copied' : 'Copy' }}</span>
2449
+ </button>
2450
+ </div>
2451
+ <div class="cc-drawer-output-box" [class.output-error]="activeStep.IsErrorOutput">{{ activeStep.Output }}</div>
2452
+ </div>
2453
+ }
2454
+ }
2455
+ </div>
2456
+ </aside>
2457
+ }
2458
+ </div>
448
2459
  </div>
449
- `, styles: ["\n .tasks-full-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n }\n\n .task-detail-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface);\n }\n\n .swoosh-in {\n animation: swooshIn 0.3s ease-out;\n }\n\n @keyframes swooshIn {\n from {\n opacity: 0;\n transform: translateX(50px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n .breadcrumb-nav {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .breadcrumb-back {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .breadcrumb-back:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n }\n\n .breadcrumb-back i {\n font-size: 12px;\n }\n\n .breadcrumb-divider {\n color: var(--mj-text-disabled);\n font-size: 14px;\n }\n\n .breadcrumb-current {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n "] }]
2460
+ `, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .tasks-command-center {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n overflow: hidden;\n }\n\n /* Header */\n .cc-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 18px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .cc-header-left {\n display: flex;\n align-items: center;\n gap: 14px;\n min-width: 0;\n }\n\n .cc-title-icon {\n width: 42px;\n height: 42px;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 26%, var(--mj-border-default));\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n flex-shrink: 0;\n }\n\n .cc-title-block {\n min-width: 0;\n }\n\n .cc-title-row {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .cc-title {\n margin: 0;\n font-size: 19px;\n font-weight: 700;\n color: var(--mj-text-primary);\n letter-spacing: -0.01em;\n }\n\n .cc-live-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 10px;\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n }\n\n .cc-live-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n animation: ccPulse 1.5s infinite ease-in-out;\n }\n\n @keyframes ccPulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.4; transform: scale(1.25); }\n }\n\n .cc-subtitle {\n margin: 3px 0 0 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n }\n\n .cc-header-actions {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n }\n\n .cc-view-switcher {\n display: inline-flex;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 3px;\n gap: 2px;\n }\n\n .cc-view-btn {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n padding: 6px 12px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .cc-view-btn:hover {\n color: var(--mj-text-primary);\n }\n\n .cc-view-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n }\n\n .cc-refresh-btn {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n padding: 7px 14px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .cc-refresh-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n }\n\n .cc-refresh-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n /* KPI Ribbon */\n .cc-kpi-ribbon {\n display: grid;\n grid-template-columns: repeat(5, minmax(0, 1fr));\n gap: 12px;\n padding: 14px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .cc-kpi-card {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 11px 14px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n min-width: 0;\n }\n\n .cc-kpi-card.kpi-card-active {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 45%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n }\n\n .cc-kpi-icon {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 15px;\n flex-shrink: 0;\n }\n\n .cc-kpi-icon.kpi-brand {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-kpi-icon.kpi-active {\n background: rgba(245, 158, 11, 0.15);\n color: #d97706;\n }\n\n .cc-kpi-icon.kpi-success {\n background: rgba(16, 185, 129, 0.15);\n color: #059669;\n }\n\n .cc-kpi-icon.kpi-rate {\n background: rgba(99, 102, 241, 0.15);\n color: #4f46e5;\n }\n\n .cc-kpi-icon.kpi-time {\n background: rgba(14, 165, 233, 0.15);\n color: #0284c7;\n }\n\n .cc-kpi-body {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .cc-kpi-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n }\n\n .cc-kpi-value-row {\n display: flex;\n align-items: baseline;\n gap: 6px;\n margin-top: 2px;\n flex-wrap: wrap;\n }\n\n .cc-kpi-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .cc-kpi-sub {\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n /* Filter Bar */\n .cc-filter-bar {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n flex-wrap: wrap;\n }\n\n .cc-search-box {\n position: relative;\n flex: 1;\n min-width: 240px;\n display: flex;\n align-items: center;\n }\n\n .cc-search-icon {\n position: absolute;\n left: 12px;\n color: var(--mj-text-muted);\n font-size: 13px;\n pointer-events: none;\n }\n\n .cc-search-input {\n width: 100%;\n padding: 8px 32px 8px 34px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .cc-search-input:focus {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n }\n\n .cc-search-clear {\n position: absolute;\n right: 8px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n }\n\n .cc-status-pills {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n }\n\n .cc-filter-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 11px;\n border-radius: 999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .cc-filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-primary);\n }\n\n .cc-filter-pill.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n }\n\n .cc-status-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n }\n\n .cc-status-dot.dot-active { background: #f59e0b; }\n .cc-status-dot.dot-completed { background: #10b981; }\n .cc-status-dot.dot-failed { background: #ef4444; }\n\n .cc-pill-count {\n padding: 1px 6px;\n border-radius: 999px;\n background: var(--mj-bg-surface);\n font-size: 11px;\n color: var(--mj-text-muted);\n }\n\n .cc-agent-filter {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 0 10px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n }\n\n .cc-agent-filter-icon {\n color: var(--mj-brand-primary);\n font-size: 13px;\n }\n\n .cc-agent-select {\n padding: 7px 4px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 12px;\n font-weight: 600;\n outline: none;\n cursor: pointer;\n }\n\n /* Main Workspace Body & Grid */\n .cc-workspace-body {\n flex: 1;\n min-height: 0;\n display: flex;\n overflow: hidden;\n position: relative;\n }\n\n .cc-main-scroll {\n flex: 1;\n min-width: 0;\n overflow-y: auto;\n padding: 20px 24px;\n }\n\n .cc-workflow-grid {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-width: 1280px;\n margin: 0 auto;\n }\n\n .cc-workflow-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 18px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n cursor: pointer;\n }\n\n .cc-workflow-card:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 45%, var(--mj-border-default));\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);\n }\n\n .cc-workflow-card.card-selected {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n }\n\n .cc-workflow-card.card-active {\n border-left: 4px solid var(--mj-brand-primary);\n }\n\n .cc-workflow-card.card-completed {\n border-left: 4px solid #10b981;\n }\n\n .cc-workflow-card.card-failed {\n border-left: 4px solid #ef4444;\n }\n\n .cc-wf-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n }\n\n .cc-wf-header-left {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n min-width: 0;\n flex: 1;\n }\n\n .cc-wf-status-icon {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 2px;\n }\n\n .cc-wf-status-icon[data-status=\"completed\"] {\n background: rgba(16, 185, 129, 0.14);\n color: #059669;\n }\n\n .cc-wf-status-icon[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-wf-status-icon[data-status=\"failed\"] {\n background: rgba(239, 68, 68, 0.14);\n color: #dc2626;\n }\n\n .cc-wf-title-group {\n min-width: 0;\n flex: 1;\n }\n\n .cc-wf-title-line {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n }\n\n .cc-wf-title {\n margin: 0;\n font-size: 15px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .cc-wf-step-count-badge {\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n }\n\n .cc-wf-status-badge {\n padding: 2px 9px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n }\n\n .cc-wf-status-badge[data-status=\"completed\"] {\n background: rgba(16, 185, 129, 0.14);\n color: #059669;\n }\n\n .cc-wf-status-badge[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-wf-status-badge[data-status=\"failed\"] {\n background: rgba(239, 68, 68, 0.14);\n color: #dc2626;\n }\n\n .cc-wf-agent-pipeline {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n margin-top: 8px;\n }\n\n .cc-agent-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 9px;\n border-radius: 6px;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 28%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .cc-agent-chip:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n }\n\n .cc-pipeline-arrow {\n font-size: 10px;\n color: var(--mj-text-muted);\n }\n\n .cc-wf-header-right {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n }\n\n .cc-wf-duration {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-variant-numeric: tabular-nums;\n }\n\n .cc-wf-timestamp {\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n\n .cc-wf-inspect-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n }\n\n .cc-wf-inspect-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n }\n\n /* Progress Bar inside Card */\n .cc-wf-progress-row {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 12px 0;\n }\n\n .cc-wf-progress-track {\n flex: 1;\n height: 6px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n }\n\n .cc-wf-progress-fill {\n height: 100%;\n border-radius: 999px;\n transition: width 0.35s ease;\n }\n\n .cc-wf-progress-fill[data-status=\"completed\"] { background: #10b981; }\n .cc-wf-progress-fill[data-status=\"active\"] { background: var(--mj-brand-primary); }\n .cc-wf-progress-fill[data-status=\"failed\"] { background: #ef4444; }\n\n .cc-wf-progress-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n }\n\n /* Step Rows inside Card */\n .cc-wf-steps-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n border-top: 1px solid var(--mj-border-default);\n padding-top: 10px;\n }\n\n .cc-step-row {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid transparent;\n transition: all 0.15s ease;\n }\n\n .cc-step-row:hover {\n border-color: var(--mj-border-default);\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface-sunken));\n }\n\n .cc-step-row.step-selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n }\n\n .cc-step-index {\n width: 22px;\n height: 22px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 700;\n flex-shrink: 0;\n margin-top: 1px;\n }\n\n .cc-step-index[data-status=\"completed\"] {\n background: rgba(16, 185, 129, 0.16);\n color: #059669;\n }\n\n .cc-step-index[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-step-index[data-status=\"failed\"] {\n background: rgba(239, 68, 68, 0.16);\n color: #dc2626;\n }\n\n .cc-step-index[data-status=\"skipped\"] {\n background: var(--mj-bg-surface);\n border: 1px dashed var(--mj-border-strong);\n color: var(--mj-text-muted);\n }\n\n .cc-step-main {\n flex: 1;\n min-width: 0;\n }\n\n .cc-step-top-line {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n }\n\n .cc-step-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .cc-step-row[data-status=\"skipped\"] .cc-step-name {\n color: var(--mj-text-muted);\n }\n\n .cc-step-agent-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 1px 7px;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 600;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n }\n\n .cc-step-dep-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n }\n\n .cc-step-preview {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .cc-step-preview.preview-error {\n color: #dc2626;\n }\n\n .cc-step-right {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n }\n\n .cc-step-duration {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n }\n\n .cc-step-status-pill {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n padding: 2px 7px;\n border-radius: 999px;\n }\n\n .cc-step-status-pill[data-status=\"completed\"] {\n background: rgba(16, 185, 129, 0.14);\n color: #059669;\n }\n\n .cc-step-status-pill[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .cc-step-status-pill[data-status=\"failed\"] {\n background: rgba(239, 68, 68, 0.14);\n color: #dc2626;\n }\n\n .cc-step-status-pill[data-status=\"skipped\"] {\n background: var(--mj-bg-surface);\n border: 1px dashed var(--mj-border-strong);\n color: var(--mj-text-muted);\n }\n\n .cc-step-run-btn {\n background: none;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n color: var(--mj-text-muted);\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 11px;\n }\n\n .cc-step-run-btn:hover {\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n }\n\n /* Timeline & Waterfall DAG View */\n .cc-timeline-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n max-width: 1280px;\n margin: 0 auto;\n }\n\n .cc-timeline-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n }\n\n .cc-timeline-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 18px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n cursor: pointer;\n }\n\n .cc-timeline-title-wrap {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n }\n\n .cc-timeline-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .cc-waterfall-table {\n display: flex;\n flex-direction: column;\n }\n\n .cc-waterfall-head {\n display: grid;\n grid-template-columns: 280px 170px 1fr;\n gap: 12px;\n padding: 8px 18px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .cc-waterfall-row {\n display: grid;\n grid-template-columns: 280px 170px 1fr;\n gap: 12px;\n align-items: center;\n padding: 10px 18px;\n border-bottom: 1px solid var(--mj-border-default);\n cursor: pointer;\n transition: background 0.12s ease;\n }\n\n .cc-waterfall-row:last-child {\n border-bottom: none;\n }\n\n .cc-waterfall-row:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .cc-waterfall-row.step-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n }\n\n .cc-wf-col-step {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n min-width: 0;\n }\n\n .cc-waterfall-step-text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .cc-waterfall-dep {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n }\n\n .cc-waterfall-track {\n position: relative;\n height: 26px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n overflow: hidden;\n }\n\n .cc-waterfall-bar {\n position: absolute;\n top: 3px;\n bottom: 3px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n padding: 0 8px;\n min-width: 64px;\n white-space: nowrap;\n font-size: 11px;\n font-weight: 600;\n }\n\n .cc-waterfall-bar[data-status=\"completed\"] {\n background: rgba(16, 185, 129, 0.2);\n border: 1px solid rgba(16, 185, 129, 0.5);\n color: #047857;\n }\n\n .cc-waterfall-bar[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border: 1px solid var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n }\n\n .cc-waterfall-bar[data-status=\"failed\"] {\n background: rgba(239, 68, 68, 0.2);\n border: 1px solid rgba(239, 68, 68, 0.5);\n color: #b91c1c;\n }\n\n .cc-waterfall-bar[data-status=\"skipped\"] {\n background: var(--mj-bg-surface);\n border: 1px dashed var(--mj-border-strong);\n color: var(--mj-text-muted);\n }\n\n /* Slide-Over Inspector Drawer */\n .cc-inspector-drawer {\n width: 440px;\n max-width: 46%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n box-shadow: -4px 0 18px rgba(0, 0, 0, 0.06);\n animation: ccSlideIn 0.2s ease-out;\n }\n\n @keyframes ccSlideIn {\n from { opacity: 0; transform: translateX(24px); }\n to { opacity: 1; transform: translateX(0); }\n }\n\n .cc-drawer-header {\n padding: 16px 20px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n }\n\n .cc-drawer-header-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 6px;\n }\n\n .cc-drawer-eyebrow {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-brand-primary);\n display: inline-flex;\n align-items: center;\n gap: 6px;\n }\n\n .cc-drawer-close {\n background: none;\n border: none;\n width: 28px;\n height: 28px;\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .cc-drawer-close:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n }\n\n .cc-drawer-title {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.35;\n }\n\n .cc-drawer-step-tabs {\n display: flex;\n gap: 6px;\n overflow-x: auto;\n margin-top: 12px;\n padding-bottom: 2px;\n }\n\n .cc-drawer-step-tab {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n max-width: 180px;\n white-space: nowrap;\n }\n\n .cc-drawer-step-tab.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .cc-tab-num {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n flex-shrink: 0;\n }\n\n .cc-tab-label {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .cc-drawer-content {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 18px 20px;\n display: flex;\n flex-direction: column;\n gap: 18px;\n }\n\n .cc-drawer-metrics-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 10px;\n }\n\n .cc-drawer-metric-box {\n padding: 10px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n gap: 4px;\n align-items: flex-start;\n }\n\n .cc-drawer-metric-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n }\n\n .cc-drawer-metric-val {\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .cc-drawer-progress-bar {\n height: 8px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n }\n\n .cc-drawer-progress-fill {\n height: 100%;\n border-radius: 999px;\n transition: width 0.3s ease;\n }\n\n .cc-drawer-progress-fill[data-status=\"completed\"] { background: #10b981; }\n .cc-drawer-progress-fill[data-status=\"active\"] { background: var(--mj-brand-primary); }\n .cc-drawer-progress-fill[data-status=\"failed\"] { background: #ef4444; }\n\n .cc-drawer-section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .cc-drawer-section-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .cc-drawer-section-title {\n margin: 0;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--mj-text-muted);\n }\n\n .cc-drawer-links-stack {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .cc-drawer-link-card {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n cursor: pointer;\n text-align: left;\n transition: all 0.15s ease;\n }\n\n .cc-drawer-link-card:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n }\n\n .cc-link-card-icon {\n width: 34px;\n height: 34px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 15px;\n flex-shrink: 0;\n }\n\n .cc-link-card-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n }\n\n .cc-link-card-label {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n }\n\n .cc-link-card-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .cc-link-card-ext {\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n\n .cc-drawer-deps-list {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n }\n\n .cc-drawer-dep-pill {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n font-size: 12px;\n color: var(--mj-text-secondary);\n }\n\n .cc-drawer-timestamps {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n }\n\n .cc-ts-row {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n }\n\n .cc-ts-label { color: var(--mj-text-muted); font-weight: 600; }\n .cc-ts-val { color: var(--mj-text-primary); font-variant-numeric: tabular-nums; }\n\n .cc-drawer-text-box {\n padding: 12px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n font-size: 13px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .cc-drawer-output-box {\n padding: 12px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n font-size: 13px;\n line-height: 1.6;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 360px;\n overflow-y: auto;\n }\n\n .cc-drawer-output-box.output-error {\n border-color: #ef4444;\n color: #dc2626;\n }\n\n .cc-copy-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n border-radius: 5px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n }\n\n /* Empty State */\n .cc-empty-state {\n max-width: 460px;\n margin: 64px auto;\n text-align: center;\n padding: 32px 24px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 14px;\n }\n\n .cc-empty-icon {\n width: 52px;\n height: 52px;\n border-radius: 12px;\n margin: 0 auto 14px auto;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n }\n\n .cc-empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n }\n\n .cc-empty-state p {\n margin: 0;\n font-size: 13px;\n line-height: 1.55;\n color: var(--mj-text-secondary);\n }\n\n .cc-reset-filters-btn {\n margin-top: 14px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n border-radius: 8px;\n border: 1px solid var(--mj-brand-primary);\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n }\n "] }]
450
2461
  }], null, { EnvironmentId: [{
451
2462
  type: Input
452
2463
  }], environmentId: [{
@@ -459,6 +2470,8 @@ export class TasksFullViewComponent extends BaseAngularComponent {
459
2470
  type: Input
460
2471
  }], baseFilter: [{
461
2472
  type: Input
2473
+ }], BaseFilterResolver: [{
2474
+ type: Input
462
2475
  }], ActiveTaskId: [{
463
2476
  type: Input
464
2477
  }], activeTaskId: [{
@@ -472,5 +2485,5 @@ export class TasksFullViewComponent extends BaseAngularComponent {
472
2485
  }], taskSelected: [{
473
2486
  type: Output
474
2487
  }] }); })();
475
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TasksFullViewComponent, { className: "TasksFullViewComponent", filePath: "src/lib/components/task/tasks-full-view.component.ts", lineNumber: 138 }); })();
2488
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TasksFullViewComponent, { className: "TasksFullViewComponent", filePath: "src/lib/components/task/tasks-full-view.component.ts", lineNumber: 2150 }); })();
476
2489
  //# sourceMappingURL=tasks-full-view.component.js.map