@kortix/ui 0.14.11 → 0.14.13

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 (447) hide show
  1. package/README.md +1 -1
  2. package/dist/_vendor/kortix-shared.js +521 -7045
  3. package/dist/_vendor/shared/app-config.d.ts +8 -0
  4. package/dist/_vendor/shared/artifact-annotations.d.ts +708 -0
  5. package/dist/_vendor/shared/artifact-comments.d.ts +327 -0
  6. package/dist/_vendor/shared/index.d.ts +3 -1
  7. package/dist/_vendor/shared/my-kortix-agent.d.ts +40 -0
  8. package/dist/_vendor/shared/peer-message-prompt.d.ts +35 -0
  9. package/dist/_vendor/shared/pixel-mark.d.ts +11 -0
  10. package/dist/_vendor/shared/prompt-attachments.d.ts +1 -0
  11. package/dist/_vendor/shared/reminder-prompt.d.ts +8 -2
  12. package/dist/_vendor/shared/runtime-versions.d.ts +8 -0
  13. package/dist/artifacts/artifact-frame.d.ts +1 -0
  14. package/dist/artifacts/artifact-frame.js +18 -5
  15. package/dist/artifacts/frame-policy.d.ts +1 -1
  16. package/dist/artifacts/frame-policy.js +10 -5
  17. package/dist/browser/browser-panel.d.ts +2 -1
  18. package/dist/browser/browser-panel.js +12 -2
  19. package/dist/customize/agents/agent-access-text.d.ts +16 -0
  20. package/dist/customize/agents/agent-access-text.js +54 -0
  21. package/dist/customize/agents/agent-approval-rules.d.ts +8 -0
  22. package/dist/customize/agents/agent-approval-rules.js +26 -0
  23. package/dist/customize/agents/agent-authority-card.js +4 -1
  24. package/dist/customize/agents/agent-cover-card.d.ts +4 -1
  25. package/dist/customize/agents/agent-cover-card.js +2 -2
  26. package/dist/customize/agents/agent-detail-aside.d.ts +1 -2
  27. package/dist/customize/agents/agent-detail-aside.js +8 -11
  28. package/dist/customize/agents/agent-drives-section.d.ts +23 -7
  29. package/dist/customize/agents/agent-drives-section.js +107 -41
  30. package/dist/customize/agents/agent-instructions.d.ts +11 -0
  31. package/dist/customize/agents/agent-instructions.js +114 -0
  32. package/dist/customize/agents/agent-model-view.d.ts +17 -0
  33. package/dist/customize/agents/agent-model-view.js +67 -0
  34. package/dist/customize/agents/agent-overview.d.ts +53 -0
  35. package/dist/customize/agents/agent-overview.js +242 -0
  36. package/dist/customize/agents/agent-page-chrome.d.ts +128 -0
  37. package/dist/customize/agents/agent-page-chrome.js +145 -0
  38. package/dist/customize/agents/agent-page.d.ts +13 -1
  39. package/dist/customize/agents/agent-page.js +478 -367
  40. package/dist/customize/agents/agent-pin-button.d.ts +10 -0
  41. package/dist/customize/agents/agent-pin-button.js +20 -0
  42. package/dist/customize/agents/agent-policy-sets-section.d.ts +16 -0
  43. package/dist/customize/agents/agent-policy-sets-section.js +80 -0
  44. package/dist/customize/agents/agent-policy-sets.js +1 -1
  45. package/dist/customize/agents/agent-section-rail.d.ts +21 -0
  46. package/dist/customize/agents/agent-section-rail.js +23 -0
  47. package/dist/customize/agents/agent-share-control.d.ts +4 -3
  48. package/dist/customize/agents/agent-share-control.js +15 -16
  49. package/dist/customize/agents/{agent-people-section.d.ts → agent-share-dialog.d.ts} +3 -1
  50. package/dist/customize/agents/{agent-people-section.js → agent-share-dialog.js} +21 -21
  51. package/dist/customize/agents/agent-tabs.d.ts +95 -0
  52. package/dist/customize/agents/agent-tabs.js +199 -0
  53. package/dist/customize/agents/agents-page.d.ts +0 -21
  54. package/dist/customize/agents/agents-page.js +104 -118
  55. package/dist/customize/agents/connectors-required.d.ts +16 -0
  56. package/dist/customize/agents/connectors-required.js +19 -0
  57. package/dist/customize/agents/create-agent-modal.d.ts +19 -0
  58. package/dist/customize/agents/create-agent-modal.js +94 -0
  59. package/dist/customize/connectors/agent-access.d.ts +4 -4
  60. package/dist/customize/connectors/agent-access.js +7 -10
  61. package/dist/customize/connectors/connector-identity.d.ts +12 -0
  62. package/dist/customize/connectors/connector-identity.js +15 -2
  63. package/dist/customize/connectors/connector-routes.js +2 -2
  64. package/dist/customize/connectors/connectors-page.d.ts +14 -1
  65. package/dist/customize/connectors/connectors-page.js +101 -32
  66. package/dist/customize/connectors/detail/app-page.js +1 -1
  67. package/dist/customize/connectors/detail/connector-agents.js +0 -3
  68. package/dist/customize/connectors/detail/connector-page.d.ts +1 -1
  69. package/dist/customize/connectors/detail/connector-page.js +5 -2
  70. package/dist/customize/connectors/detail/connector-policy-sets.js +1 -1
  71. package/dist/customize/connectors/detail/connector-triggers.js +2 -2
  72. package/dist/customize/connectors/use-agent-access.d.ts +7 -5
  73. package/dist/customize/connectors/use-agent-access.js +2 -6
  74. package/dist/customize/models/models-page.d.ts +7 -1
  75. package/dist/customize/models/models-page.js +2 -2
  76. package/dist/customize/project-settings/project-admin-sections.d.ts +63 -0
  77. package/dist/customize/project-settings/project-admin-sections.js +80 -0
  78. package/dist/customize/project-settings/project-settings-page.d.ts +1 -1
  79. package/dist/customize/project-settings/project-settings-page.js +4 -13
  80. package/dist/customize/project-settings/project-settings-sections.d.ts +5 -5
  81. package/dist/customize/project-settings/project-settings-sections.js +6 -20
  82. package/dist/customize/providers/provider-accordion.js +29 -17
  83. package/dist/customize/providers/provider-connect.js +1 -1
  84. package/dist/customize/providers/provider-sheet.d.ts +4 -1
  85. package/dist/customize/providers/provider-sheet.js +15 -5
  86. package/dist/customize/secrets/secrets-page.d.ts +5 -1
  87. package/dist/customize/secrets/secrets-page.js +2 -2
  88. package/dist/customize/sections/gateway-view.d.ts +10 -2
  89. package/dist/customize/sections/gateway-view.js +16 -4
  90. package/dist/customize/sections/llm-provider/chatgpt-subscription-connect.d.ts +12 -5
  91. package/dist/customize/sections/llm-provider/chatgpt-subscription-connect.js +131 -8
  92. package/dist/customize/sections/llm-provider/claude-code-step.d.ts +10 -0
  93. package/dist/customize/sections/llm-provider/claude-code-step.js +32 -0
  94. package/dist/customize/sections/llm-provider/models-tab.js +5 -1
  95. package/dist/customize/sections/view/account-secret-resources-panel.d.ts +5 -3
  96. package/dist/customize/sections/view/account-secret-resources-panel.js +122 -19
  97. package/dist/customize/sections/view/agent-editor-access-fields.d.ts +1 -1
  98. package/dist/customize/sections/view/agent-editor-access-fields.js +8 -4
  99. package/dist/customize/sections/view/agent-editor-basics-fields.d.ts +4 -1
  100. package/dist/customize/sections/view/agent-editor-basics-fields.js +33 -4
  101. package/dist/customize/sections/view/agent-editor-catalog.d.ts +2 -2
  102. package/dist/customize/sections/view/agent-editor-catalog.js +10 -12
  103. package/dist/customize/sections/view/agent-editor-primitives.d.ts +1 -1
  104. package/dist/customize/sections/view/agent-editor-primitives.js +4 -4
  105. package/dist/customize/sections/view/agent-editor.d.ts +37 -26
  106. package/dist/customize/sections/view/agent-editor.js +19 -19
  107. package/dist/customize/sections/view/grant-mode-field.d.ts +8 -20
  108. package/dist/customize/sections/view/grant-mode-field.js +31 -57
  109. package/dist/customize/sections/view/permission-editor.d.ts +3 -1
  110. package/dist/customize/sections/view/permission-editor.js +19 -10
  111. package/dist/customize/sections/view/review-view.d.ts +8 -0
  112. package/dist/customize/sections/view/review-view.js +12 -1
  113. package/dist/customize/sections/view/secret-delivery.js +1 -4
  114. package/dist/customize/sections/view/secrets-view.d.ts +7 -1
  115. package/dist/customize/sections/view/secrets-view.js +42 -6
  116. package/dist/customize/settings/rail.js +2 -8
  117. package/dist/customize/settings/settings-tabs.d.ts +2 -2
  118. package/dist/customize/settings/settings-tabs.js +17 -19
  119. package/dist/customize/settings/tabs/experimental-tab.d.ts +3 -0
  120. package/dist/customize/settings/tabs/experimental-tab.js +6 -1
  121. package/dist/customize/settings/tabs/sandbox-tab.d.ts +4 -6
  122. package/dist/customize/settings/tabs/sandbox-tab.js +9 -9
  123. package/dist/customize/shared/access-list.d.ts +39 -0
  124. package/dist/customize/shared/access-list.js +62 -0
  125. package/dist/customize/shared/agent-resource-scope.d.ts +87 -0
  126. package/dist/customize/shared/agent-resource-scope.js +123 -0
  127. package/dist/customize/shared/capability-library.d.ts +41 -0
  128. package/dist/customize/shared/capability-library.js +271 -0
  129. package/dist/customize/shared/capability-page-shell.d.ts +18 -1
  130. package/dist/customize/shared/capability-page-shell.js +21 -1
  131. package/dist/customize/shared/catalog/catalog-space-tabs.d.ts +14 -0
  132. package/dist/customize/shared/catalog/catalog-space-tabs.js +20 -0
  133. package/dist/customize/shared/customize-tab-bar.d.ts +13 -0
  134. package/dist/customize/shared/customize-tab-bar.js +95 -0
  135. package/dist/customize/shared/entity/entity-modal.d.ts +17 -1
  136. package/dist/customize/shared/entity/entity-modal.js +10 -9
  137. package/dist/customize/shared/leave-guard.d.ts +23 -0
  138. package/dist/customize/shared/leave-guard.js +87 -0
  139. package/dist/customize/shared/standalone-settings-nav.js +4 -1
  140. package/dist/customize/shared/tool-rules.d.ts +11 -0
  141. package/dist/customize/shared/tool-rules.js +29 -0
  142. package/dist/customize/skills/builtin-skill-modal.d.ts +6 -0
  143. package/dist/customize/skills/builtin-skill-modal.js +41 -0
  144. package/dist/customize/skills/skills-page.d.ts +21 -18
  145. package/dist/customize/skills/skills-page.js +16 -110
  146. package/dist/customize/triggers/runtime-triggers.d.ts +17 -0
  147. package/dist/customize/triggers/runtime-triggers.js +57 -0
  148. package/dist/customize/triggers/schedule/event-trigger-copy.js +2 -2
  149. package/dist/customize/triggers/schedule/post-to-field.js +2 -2
  150. package/dist/customize/triggers/schedule/schedule-copy.d.ts +11 -6
  151. package/dist/customize/triggers/schedule/schedule-copy.js +29 -8
  152. package/dist/customize/triggers/schedule/schedule-detail-sheet.js +7 -3
  153. package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +26 -1
  154. package/dist/customize/triggers/schedule/trigger-composer-logic.js +64 -3
  155. package/dist/customize/triggers/schedule/trigger-composer.js +57 -20
  156. package/dist/customize/triggers/schedule/trigger-edit-logic.js +18 -5
  157. package/dist/customize/triggers/schedule/trigger-filter.d.ts +10 -0
  158. package/dist/customize/triggers/schedule/trigger-filter.js +16 -0
  159. package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
  160. package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
  161. package/dist/customize/triggers/schedule/use-trigger-mutations.d.ts +1 -1
  162. package/dist/customize/triggers/schedule/use-trigger-mutations.js +1 -1
  163. package/dist/customize/triggers/schedule/when-app.d.ts +15 -0
  164. package/dist/customize/triggers/schedule/when-app.js +21 -0
  165. package/dist/customize/triggers/schedule/when-change-request.d.ts +10 -0
  166. package/dist/customize/triggers/schedule/when-change-request.js +15 -0
  167. package/dist/customize/triggers/schedule-view.d.ts +17 -3
  168. package/dist/customize/triggers/schedule-view.js +46 -16
  169. package/dist/customize/triggers/triggers-page.d.ts +3 -3
  170. package/dist/customize/triggers/triggers-page.js +2 -2
  171. package/dist/customize/use-configure-thread.d.ts +8 -2
  172. package/dist/customize/use-configure-thread.js +30 -18
  173. package/dist/files/project/components/change-request-detail-dialog.js +2 -3
  174. package/dist/files/project/components/drive-explorer.js +6 -5
  175. package/dist/files/project/explorer-source.d.ts +3 -0
  176. package/dist/files/project/upload-batch.d.ts +3 -3
  177. package/dist/files/project/upload-batch.js +7 -6
  178. package/dist/files/runtime/sandbox-explorer-source.js +3 -3
  179. package/dist/i18n/en.d.ts +1331 -53
  180. package/dist/i18n/en.js +1423 -145
  181. package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +16 -7
  182. package/dist/internal/auth/auth-primitives.d.ts +1 -3
  183. package/dist/internal/auth/auth-primitives.js +2 -2
  184. package/dist/internal/billing/session-cost-format.d.ts +1 -0
  185. package/dist/internal/billing/session-cost-format.js +11 -0
  186. package/dist/internal/components/agent-mark.d.ts +12 -1
  187. package/dist/internal/components/agent-mark.js +34 -11
  188. package/dist/internal/components/nav-rail.d.ts +22 -0
  189. package/dist/internal/components/nav-rail.js +16 -0
  190. package/dist/internal/components/repository-disconnected.js +2 -2
  191. package/dist/internal/goals/goal-meta.d.ts +15 -1
  192. package/dist/internal/goals/goal-meta.js +42 -2
  193. package/dist/internal/hooks/projects/use-agent-config.d.ts +11 -7
  194. package/dist/internal/hooks/projects/use-agent-config.js +28 -11
  195. package/dist/internal/hooks/use-slash-focus.d.ts +7 -1
  196. package/dist/internal/hooks/use-slash-focus.js +9 -3
  197. package/dist/internal/layout/project-capability-nav.d.ts +24 -0
  198. package/dist/internal/layout/project-capability-nav.js +86 -0
  199. package/dist/internal/layout/project-page-header.d.ts +1 -1
  200. package/dist/internal/layout/project-page-header.js +1 -1
  201. package/dist/internal/layout/project-settings-nav.d.ts +3 -2
  202. package/dist/internal/layout/project-settings-nav.js +5 -3
  203. package/dist/internal/lib/browser-noise/rules/extensions.js +3 -0
  204. package/dist/internal/lib/browser-noise/rules/old-browsers.js +1 -1
  205. package/dist/internal/lib/capability-tab-routes.d.ts +34 -3
  206. package/dist/internal/lib/capability-tab-routes.js +76 -8
  207. package/dist/internal/lib/manifest-health.d.ts +10 -0
  208. package/dist/internal/lib/manifest-health.js +20 -0
  209. package/dist/internal/lib/pixel-mark.d.ts +4 -1
  210. package/dist/internal/lib/pixel-mark.js +33 -6
  211. package/dist/internal/lib/project-actions.d.ts +1 -1
  212. package/dist/internal/lib/project-actions.js +0 -4
  213. package/dist/internal/lib/provider-branding.js +2 -0
  214. package/dist/internal/lib/space-scope.d.ts +29 -0
  215. package/dist/internal/lib/space-scope.js +28 -0
  216. package/dist/internal/lib/use-project-feature-flags.js +3 -3
  217. package/dist/internal/lib/web-notifications.d.ts +74 -8
  218. package/dist/internal/lib/web-notifications.js +243 -117
  219. package/dist/internal/notifications/notification-rows.d.ts +14 -7
  220. package/dist/internal/notifications/notification-rows.js +21 -14
  221. package/dist/internal/notifications/session-toast-cards.d.ts +2 -2
  222. package/dist/internal/reminders/reminder-format.d.ts +6 -2
  223. package/dist/internal/reminders/reminder-format.js +7 -1
  224. package/dist/internal/stores/active-space-store.d.ts +35 -0
  225. package/dist/internal/stores/active-space-store.js +29 -0
  226. package/dist/internal/stores/kortix-computer-store.d.ts +2 -1
  227. package/dist/internal/stores/kortix-computer-store.js +18 -7
  228. package/dist/internal/stores/pinned-agents-store.d.ts +26 -0
  229. package/dist/internal/stores/pinned-agents-store.js +20 -0
  230. package/dist/internal/stores/session-panel-memory-store.js +3 -0
  231. package/dist/internal/stores/turn-attention-store.d.ts +5 -4
  232. package/dist/lib/routes.d.ts +16 -1
  233. package/dist/lib/routes.js +15 -3
  234. package/dist/markdown/doc-editor/doc-embed.d.ts +31 -0
  235. package/dist/markdown/doc-editor/doc-embed.js +168 -0
  236. package/dist/markdown/doc-editor/doc-extensions.d.ts +26 -0
  237. package/dist/markdown/doc-editor/doc-extensions.js +149 -0
  238. package/dist/markdown/doc-editor/doc-menus.d.ts +9 -0
  239. package/dist/markdown/doc-editor/doc-menus.js +56 -0
  240. package/dist/markdown/doc-editor/markdown.d.ts +12 -0
  241. package/dist/markdown/doc-editor/markdown.js +140 -0
  242. package/dist/markdown/genui/components/inline.d.ts +1 -1
  243. package/dist/primitives/badge.d.ts +1 -1
  244. package/dist/primitives/button.d.ts +1 -1
  245. package/dist/primitives/pixel-kortix-mark.d.ts +5 -4
  246. package/dist/primitives/pixel-kortix-mark.js +5 -15
  247. package/dist/primitives/tag.d.ts +1 -1
  248. package/dist/primitives/textarea.js +14 -0
  249. package/dist/primitives/toast.d.ts +2 -0
  250. package/dist/primitives/toast.js +4 -2
  251. package/dist/providers/ui-provider.d.ts +16 -0
  252. package/dist/session/actions/session-label.d.ts +1 -1
  253. package/dist/session/actions/session-label.js +3 -3
  254. package/dist/session/agents/agent-model.d.ts +92 -0
  255. package/dist/session/agents/agent-model.js +123 -0
  256. package/dist/session/agents/agent-state-mark.d.ts +10 -0
  257. package/dist/session/agents/agent-state-mark.js +22 -0
  258. package/dist/session/agents/agent-strip.d.ts +58 -0
  259. package/dist/session/agents/agent-strip.js +259 -0
  260. package/dist/session/agents/held-messages.d.ts +33 -0
  261. package/dist/session/agents/held-messages.js +50 -0
  262. package/dist/session/agents/legacy-subagent-chat.d.ts +11 -0
  263. package/dist/session/agents/legacy-subagent-chat.js +19 -0
  264. package/dist/session/agents/session-peek.d.ts +20 -0
  265. package/dist/session/agents/session-peek.js +67 -0
  266. package/dist/session/agents/session-prompt.d.ts +13 -0
  267. package/dist/session/agents/session-prompt.js +18 -0
  268. package/dist/session/agents/steer-session.d.ts +13 -0
  269. package/dist/session/agents/steer-session.js +29 -0
  270. package/dist/session/agents/subagent-dialog-content.d.ts +11 -0
  271. package/dist/session/agents/subagent-dialog-content.js +115 -0
  272. package/dist/session/agents/subagent-view.d.ts +8 -0
  273. package/dist/session/agents/subagent-view.js +18 -0
  274. package/dist/session/agents/tasks-panel.d.ts +13 -0
  275. package/dist/session/agents/tasks-panel.js +41 -0
  276. package/dist/session/agents/workflow-run-controls.d.ts +43 -0
  277. package/dist/session/agents/workflow-run-controls.js +141 -0
  278. package/dist/session/composer/ComposerCard.d.ts +1 -1
  279. package/dist/session/composer/ComposerCard.js +3 -3
  280. package/dist/session/composer/agent-selector.js +13 -19
  281. package/dist/session/composer/composer-underbar.d.ts +3 -1
  282. package/dist/session/composer/composer-underbar.js +2 -2
  283. package/dist/session/composer/composer.d.ts +5 -0
  284. package/dist/session/composer/composer.js +16 -10
  285. package/dist/session/composer/editor/composer-editor.js +19 -8
  286. package/dist/session/composer/editor/ultracode.d.ts +34 -0
  287. package/dist/session/composer/editor/ultracode.js +127 -0
  288. package/dist/session/composer/index.d.ts +1 -0
  289. package/dist/session/composer/index.js +1 -0
  290. package/dist/session/composer/send-blockers.d.ts +1 -11
  291. package/dist/session/composer/send-blockers.js +1 -11
  292. package/dist/session/composer/session-composer-readiness.d.ts +1 -28
  293. package/dist/session/composer/session-composer-readiness.js +5 -16
  294. package/dist/session/header/reminder-parts.d.ts +1 -1
  295. package/dist/session/header/session-site-header.js +6 -3
  296. package/dist/session/header/subagent-hover-card.d.ts +0 -2
  297. package/dist/session/header/subagent-hover-card.js +1 -4
  298. package/dist/session/models/claude-connection-slot.d.ts +11 -0
  299. package/dist/session/models/claude-connection-slot.js +30 -0
  300. package/dist/session/models/model-availability.d.ts +3 -1
  301. package/dist/session/models/model-availability.js +3 -0
  302. package/dist/session/models/model-selector.js +11 -12
  303. package/dist/session/models/model-tags.d.ts +9 -0
  304. package/dist/session/models/model-tags.js +8 -0
  305. package/dist/session/panel/easy/detail-view.js +7 -0
  306. package/dist/session/panel/easy/easy-panel.js +1 -1
  307. package/dist/session/panel/easy/step-icon.js +5 -1
  308. package/dist/session/panel/mobile-tool-drawer.js +7 -3
  309. package/dist/session/panel/open-session-quick-view.js +1 -1
  310. package/dist/session/panel/session-action-panel-column.js +1 -1
  311. package/dist/session/panel/session-desktop.js +41 -14
  312. package/dist/session/panel/session-panel-provider.d.ts +1 -1
  313. package/dist/session/panel/session-panel-provider.js +7 -11
  314. package/dist/session/prompts/question-prompt.js +3 -1
  315. package/dist/session/status/session-error-banner.js +4 -1
  316. package/dist/session/thread/session-chat.js +286 -296
  317. package/dist/session/thread/session-context-modal.js +29 -10
  318. package/dist/session/thread/session-context-spawned-sessions.d.ts +13 -0
  319. package/dist/session/thread/session-context-spawned-sessions.js +44 -0
  320. package/dist/session/thread/session-context-sub-sessions.js +3 -8
  321. package/dist/session/thread/transcript.d.ts +3 -0
  322. package/dist/session/thread/transcript.js +32 -8
  323. package/dist/session/tool/shared/full-view-action.d.ts +29 -0
  324. package/dist/session/tool/shared/full-view-action.js +43 -0
  325. package/dist/session/tool/tool-part-renderer.js +10 -2
  326. package/dist/session/tool/tools/agent-message-tool.js +2 -2
  327. package/dist/session/tool/tools/agent-spawn-tool.js +2 -2
  328. package/dist/session/tool/tools/agent-status-tool.js +2 -2
  329. package/dist/session/tool/tools/kortix-action-tool.d.ts +2 -0
  330. package/dist/session/tool/tools/kortix-action-tool.js +148 -0
  331. package/dist/session/tool/tools/kortix-tool-card.d.ts +83 -0
  332. package/dist/session/tool/tools/kortix-tool-card.js +186 -0
  333. package/dist/session/tool/tools/multi-agent-tool-bodies.d.ts +11 -0
  334. package/dist/session/tool/tools/multi-agent-tool-bodies.js +141 -0
  335. package/dist/session/tool/tools/multi-agent-tool-data.d.ts +63 -0
  336. package/dist/session/tool/tools/multi-agent-tool-data.js +118 -0
  337. package/dist/session/tool/tools/multi-agent-tools.d.ts +9 -0
  338. package/dist/session/tool/tools/multi-agent-tools.js +38 -0
  339. package/dist/session/tool/tools/question-tool.js +1 -1
  340. package/dist/session/tool/tools/register.d.ts +3 -0
  341. package/dist/session/tool/tools/register.js +3 -0
  342. package/dist/session/tool/tools/session-spawn-tool.js +2 -2
  343. package/dist/session/tool/tools/task-tool.d.ts +1 -1
  344. package/dist/session/tool/tools/task-tool.js +29 -41
  345. package/dist/session/tool/tools/workflow-progress.d.ts +34 -0
  346. package/dist/session/tool/tools/workflow-progress.js +186 -0
  347. package/dist/session/tool/tools/workflow-run.d.ts +128 -0
  348. package/dist/session/tool/tools/workflow-run.js +251 -0
  349. package/dist/session/tool/tools/workflow-tool.d.ts +9 -0
  350. package/dist/session/tool/tools/workflow-tool.js +253 -0
  351. package/dist/session/turn/notice-batch-group.d.ts +12 -0
  352. package/dist/session/turn/notice-batch-group.js +17 -0
  353. package/dist/session/turn/peer-message-row.d.ts +14 -0
  354. package/dist/session/turn/peer-message-row.js +57 -0
  355. package/dist/session/turn/subagent-notice-row.d.ts +4 -0
  356. package/dist/session/turn/subagent-notice-row.js +50 -0
  357. package/dist/session/turn/subagent-notice.d.ts +58 -0
  358. package/dist/session/turn/subagent-notice.js +111 -0
  359. package/dist/session/turn/user-message.d.ts +5 -4
  360. package/dist/session/turn/user-message.js +31 -10
  361. package/dist/styles/tokens.css +2 -0
  362. package/dist/styles.css +1 -1
  363. package/dist/terminal/session-terminal-connect-bar.js +1 -1
  364. package/dist/workspace/admin/project-admin-dashboard.d.ts +53 -0
  365. package/dist/workspace/admin/project-admin-dashboard.js +252 -0
  366. package/dist/workspace/admin/project-admin-nav.d.ts +20 -0
  367. package/dist/workspace/admin/project-admin-nav.js +41 -0
  368. package/dist/workspace/home/welcome-body.js +25 -3
  369. package/dist/workspace/index.d.ts +6 -2
  370. package/dist/workspace/index.js +12 -2
  371. package/dist/workspace/layout/new-session-create.js +3 -3
  372. package/dist/workspace/layout/project-home.js +3 -3
  373. package/dist/workspace/memory/memory-labels.js +5 -0
  374. package/dist/workspace/repository-disconnected.js +2 -2
  375. package/dist/workspace/sessions/board-dispatch.d.ts +52 -0
  376. package/dist/workspace/sessions/board-dispatch.js +110 -0
  377. package/dist/workspace/sessions/board-grouping.d.ts +63 -0
  378. package/dist/workspace/sessions/board-grouping.js +141 -0
  379. package/dist/workspace/sessions/board-peek.d.ts +15 -0
  380. package/dist/workspace/sessions/board-peek.js +54 -0
  381. package/dist/workspace/sessions/board-state-mark.d.ts +15 -0
  382. package/dist/workspace/sessions/board-state-mark.js +24 -0
  383. package/dist/workspace/sessions/project-sessions-view.js +42 -31
  384. package/dist/workspace/sessions/sessions-board.d.ts +12 -0
  385. package/dist/workspace/sessions/sessions-board.js +214 -0
  386. package/dist/workspace/sidebar/footer/project-manifest-issues-alert.d.ts +46 -0
  387. package/dist/workspace/sidebar/footer/project-manifest-issues-alert.js +85 -0
  388. package/dist/workspace/sidebar/footer/sidebar-alert.js +1 -1
  389. package/dist/workspace/sidebar/new-agent-modal-provider.d.ts +12 -0
  390. package/dist/workspace/sidebar/new-agent-modal-provider.js +19 -0
  391. package/dist/workspace/sidebar/project-nav-items.d.ts +3 -1
  392. package/dist/workspace/sidebar/project-nav-items.js +53 -5
  393. package/dist/workspace/sidebar/project-session-list.js +35 -12
  394. package/dist/workspace/sidebar/project-sidebar.js +6 -3
  395. package/dist/workspace/sidebar/session-filter-menu.js +2 -1
  396. package/dist/workspace/space/space-blocks.d.ts +25 -0
  397. package/dist/workspace/space/space-blocks.js +124 -0
  398. package/dist/workspace/space/space-filter-tabs.d.ts +17 -0
  399. package/dist/workspace/space/space-filter-tabs.js +31 -0
  400. package/dist/workspace/space/space-page.d.ts +24 -0
  401. package/dist/workspace/space/space-page.js +157 -0
  402. package/dist/workspace/space/space-room.d.ts +20 -0
  403. package/dist/workspace/space/space-room.js +27 -0
  404. package/dist/workspace/space/space-tab-menu.d.ts +14 -0
  405. package/dist/workspace/space/space-tab-menu.js +127 -0
  406. package/dist/workspace/space/space-tab-panels.d.ts +9 -0
  407. package/dist/workspace/space/space-tab-panels.js +203 -0
  408. package/dist/workspace/space/space-templates.d.ts +34 -0
  409. package/dist/workspace/space/space-templates.js +71 -0
  410. package/dist/workspace/space/use-space-filter.d.ts +10 -0
  411. package/dist/workspace/space/use-space-filter.js +40 -0
  412. package/dist/workspace/space/use-space-manifest.d.ts +8 -0
  413. package/dist/workspace/space/use-space-manifest.js +27 -0
  414. package/dist/workspace/spaces/space-timeline.js +2 -2
  415. package/package.json +56 -53
  416. package/skills/kortix-ui/SKILL.md +1 -1
  417. package/skills/kortix-ui/references/custom-dashboard.md +10 -4
  418. package/skills/kortix-ui/references/modules.md +11 -9
  419. package/dist/_vendor/shared/meta-agent.d.ts +0 -7
  420. package/dist/customize/agents/agent-grant-pages.d.ts +0 -37
  421. package/dist/customize/agents/agent-grant-pages.js +0 -226
  422. package/dist/customize/agents/agent-triggers-section.d.ts +0 -17
  423. package/dist/customize/agents/agent-triggers-section.js +0 -109
  424. package/dist/customize/migrate-to-v2/index.d.ts +0 -5
  425. package/dist/customize/migrate-to-v2/index.js +0 -5
  426. package/dist/customize/migrate-to-v2/migration-prompt.d.ts +0 -16
  427. package/dist/customize/migrate-to-v2/migration-prompt.js +0 -59
  428. package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +0 -30
  429. package/dist/customize/migrate-to-v2/upgrade-defs.js +0 -43
  430. package/dist/customize/migrate-to-v2/upgrade-view.d.ts +0 -32
  431. package/dist/customize/migrate-to-v2/upgrade-view.js +0 -152
  432. package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +0 -18
  433. package/dist/customize/migrate-to-v2/use-run-upgrade.js +0 -16
  434. package/dist/customize/shared/capability-tabs.d.ts +0 -3
  435. package/dist/customize/shared/capability-tabs.js +0 -137
  436. package/dist/customize/skills/skill-scope.d.ts +0 -14
  437. package/dist/customize/skills/skill-scope.js +0 -18
  438. package/dist/internal/lib/manifest-version.d.ts +0 -21
  439. package/dist/internal/lib/manifest-version.js +0 -55
  440. package/dist/session/composer/hooks/use-composer-escape-stop.d.ts +0 -6
  441. package/dist/session/composer/hooks/use-composer-escape-stop.js +0 -28
  442. package/dist/session/thread/sub-session-modal-content.d.ts +0 -8
  443. package/dist/session/thread/sub-session-modal-content.js +0 -23
  444. package/dist/session/thread/sub-session-modal.d.ts +0 -2
  445. package/dist/session/thread/sub-session-modal.js +0 -14
  446. package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.d.ts +0 -13
  447. package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +0 -48
@@ -0,0 +1,115 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { stopProjectSession } from '@kortix/sdk';
4
+ import { qk, useProjectSession } from '@kortix/sdk/react';
5
+ import { ArrowSquareOutIcon, CheckIcon, PaperPlaneRightIcon, SquareIcon, XIcon } from '@phosphor-icons/react';
6
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
7
+ import { useState } from 'react';
8
+ import { useTranslations } from '../../i18n/index.js';
9
+ import { agentDisplayName } from '../../internal/components/agent-mark.js';
10
+ import { uiRoutes } from '../../lib/routes.js';
11
+ import { cn } from '../../lib/utils.js';
12
+ import { Button } from '../../primitives/button.js';
13
+ import { ErrorState } from '../../primitives/error-state.js';
14
+ import { Hint } from '../../primitives/hint.js';
15
+ import { Input } from '../../primitives/input.js';
16
+ import Loading from '../../primitives/loading.js';
17
+ import { Modal, ModalContent, ModalDescription, ModalTitle } from '../../primitives/modal.js';
18
+ import { Skeleton } from '../../primitives/skeleton.js';
19
+ import { StatusDot } from '../../primitives/status.js';
20
+ import { errorToast, successToast } from '../../primitives/toast.js';
21
+ import { UiLink } from '../../providers/ui-provider.js';
22
+ import { useSessionIds } from '../../providers/session-ids.js';
23
+ import { agentRowOf, isActive, shortElapsed } from './agent-model.js';
24
+ import { LegacySubagentChat } from './legacy-subagent-chat.js';
25
+ import { SessionPeek } from './session-peek.js';
26
+ import { useSteerSession } from './steer-session.js';
27
+ import { useNow } from './workflow-run-controls.js';
28
+ const DOT_TONE = {
29
+ working: 'success',
30
+ needs_input: 'warning',
31
+ failed: 'destructive',
32
+ stopped: 'neutral',
33
+ };
34
+ /** The same state mark as the agents line: live dot, attention dot, check once its turn ended. */
35
+ function StateMark({ state }) {
36
+ return state === 'idle' || state === 'completed' ? (_jsx(CheckIcon, { "aria-hidden": true, weight: "bold", className: "text-kortix-green size-3 shrink-0" })) : (_jsx(StatusDot, { tone: DOT_TONE[state], pulse: state === 'working', className: "motion-reduce:animate-none" }));
37
+ }
38
+ /**
39
+ * Which body a child gets. A child that is its own project session (every
40
+ * sub-agent, teammate and workflow agent since each runs on its own computer)
41
+ * answers `GET /projects/:pid/sessions/:child` and reads its own log
42
+ * (`SessionPeek`). A child that answers 404 or 400 there is not a project
43
+ * session (an in-process `session: "same"` child, an old OpenCode subagent):
44
+ * its transcript lives in the lead's computer, so it keeps the legacy chat.
45
+ * Any other failure is a failed read of a real child: the dialog says so.
46
+ */
47
+ function bodyKind(row, projectId) {
48
+ if (!projectId)
49
+ return 'legacy';
50
+ if (row.data)
51
+ return 'peek';
52
+ if (row.isError) {
53
+ const status = row.error?.status;
54
+ return status === 404 || status === 400 ? 'legacy' : 'error';
55
+ }
56
+ return 'loading';
57
+ }
58
+ export function SubagentDialogContent({ open, onOpenChange, sessionId, title, projectId: projectIdProp }) {
59
+ const t = useTranslations('multiAgent.subagent');
60
+ const tStrip = useTranslations('multiAgent.strip');
61
+ const ids = useSessionIds();
62
+ const projectId = projectIdProp ?? ids.projectId ?? undefined;
63
+ const row = useProjectSession(projectId, sessionId, { enabled: open && !!projectId });
64
+ const kind = bodyKind(row, projectId);
65
+ const agent = row.data ? agentRowOf(row.data) : null;
66
+ const name = agent?.named ? agent.handle : title || agent?.handle || t('fallbackTitle');
67
+ const working = agent?.state === 'working';
68
+ const now = useNow(open && working);
69
+ const queryClient = useQueryClient();
70
+ // The header's state follows the transcript: a new message re-reads the row.
71
+ const refreshRow = () => projectId && void queryClient.invalidateQueries({ queryKey: qk.project.session(projectId, sessionId) });
72
+ const stop = useMutation({
73
+ mutationFn: () => stopProjectSession(projectId, sessionId),
74
+ onSettled: refreshRow,
75
+ onError: (error) => errorToast(tStrip('stopAgentFailed', { name }), { description: error instanceof Error ? error.message : undefined }),
76
+ });
77
+ const state = agent
78
+ ? agent.state === 'working' && agent.workingSinceMs !== null
79
+ ? tStrip('workingFor', { elapsed: shortElapsed(now - agent.workingSinceMs) })
80
+ : tStrip(`state.${agent.state}`)
81
+ : null;
82
+ return (_jsx(Modal, { open: open, onOpenChange: onOpenChange, children: _jsxs(ModalContent, { variant: "base", showCloseButton: false, "data-testid": "subagent-dialog", "data-body": kind, className: cn('flex flex-col gap-0 space-y-0 overflow-hidden p-0',
83
+ // lg:max-w-* is required: the base modal sets lg:max-w-lg, which
84
+ // tailwind-merge does not strip for an unprefixed override.
85
+ 'h-[80vh] max-h-[840px] lg:h-[80vh] lg:max-w-6xl',
86
+ // A small window gets the whole screen: no sheet edge to aim at.
87
+ 'max-[720px]:inset-0 max-[720px]:h-dvh max-[720px]:max-h-none max-[720px]:rounded-none'), children: [_jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b py-2 pr-2 pl-4", children: [agent && _jsx(StateMark, { state: agent.state }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 items-baseline gap-2", children: [_jsx(ModalTitle, { className: "min-w-0 truncate text-sm font-medium", children: name }), state && _jsx("span", { className: "text-muted-foreground shrink-0 text-xs tabular-nums", children: state })] }), _jsx(ModalDescription, { className: "text-muted-foreground truncate text-xs", children: agent?.agent && agent.named ? tStrip('runsAs', { agent: agentDisplayName(agent.agent) }) : null })] }), projectId && kind === 'peek' && (_jsx(Button, { asChild: true, variant: "ghost", size: "xs", className: "text-muted-foreground hover:text-foreground shrink-0", children: _jsxs(UiLink, { href: uiRoutes().session(projectId, sessionId), onClick: () => onOpenChange(false), children: [_jsx(ArrowSquareOutIcon, { className: "size-3.5 shrink-0" }), t('openPage')] }) })), agent && isActive(agent.state) && (_jsx(Hint, { label: tStrip('stopHint'), side: "bottom", children: _jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", "aria-label": tStrip('stopAgent', { name }), disabled: stop.isPending, onClick: () => stop.mutate(), className: "text-muted-foreground hover:text-foreground", children: stop.isPending ? _jsx(Loading, { className: "size-3" }) : _jsx(SquareIcon, { weight: "fill", className: "size-2.5" }) }) })), _jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", "aria-label": t('close'), onClick: () => onOpenChange(false), className: "text-muted-foreground hover:text-foreground hit-area-2 shrink-0", children: _jsx(XIcon, { className: "size-3.5" }) })] }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: kind === 'peek' && projectId ? (_jsx(SessionPeek, { projectId: projectId, sessionId: sessionId, working: working, onActivity: refreshRow })) : kind === 'legacy' ? (_jsx(LegacySubagentChat, { sessionId: sessionId })) : kind === 'error' ? (_jsx(SessionPeekRowError, { onRetry: () => void row.refetch() })) : (_jsxs("div", { className: "mx-auto w-full max-w-3xl space-y-4 px-7 pt-6", "aria-busy": "true", children: [_jsx(Skeleton, { className: "ml-auto h-9 w-2/5 rounded-xl" }), _jsx(Skeleton, { className: "h-4 w-4/5" }), _jsx(Skeleton, { className: "h-4 w-3/5" })] })) }), kind === 'peek' && projectId && _jsx(SubagentMessageBox, { projectId: projectId, sessionId: sessionId, name: name, onSent: refreshRow }, sessionId)] }) }));
88
+ }
89
+ function SessionPeekRowError({ onRetry }) {
90
+ const t = useTranslations('multiAgent.subagent');
91
+ return (_jsx("div", { className: "flex flex-1 items-center justify-center p-6", children: _jsx(ErrorState, { size: "sm", title: t('loadFailed'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: onRetry, children: t('retry') }) }) }));
92
+ }
93
+ /** One line under the transcript: a message to the child, as a steer. */
94
+ function SubagentMessageBox({ projectId, sessionId, name, onSent }) {
95
+ const t = useTranslations('multiAgent.subagent');
96
+ const [text, setText] = useState('');
97
+ const send = useSteerSession(projectId, {
98
+ onSent: () => {
99
+ setText('');
100
+ successToast(t('sent'));
101
+ onSent();
102
+ },
103
+ onError: (error) => errorToast(t('sendFailed'), { description: error instanceof Error ? error.message : undefined }),
104
+ });
105
+ const submit = () => {
106
+ const message = text.trim();
107
+ if (!message || send.isPending)
108
+ return;
109
+ send.mutate({ sessionId, text: message });
110
+ };
111
+ return (_jsxs("form", { className: "flex shrink-0 items-center gap-2 border-t px-4 py-3", onSubmit: (event) => {
112
+ event.preventDefault();
113
+ submit();
114
+ }, children: [_jsx(Input, { "data-testid": "subagent-dialog-message", value: text, onChange: (event) => setText(event.target.value), placeholder: t('messagePlaceholder', { name }), "aria-label": t('messageLabel', { name }), disabled: send.isPending, className: "min-w-0 flex-1" }), _jsxs(Button, { type: "submit", size: "sm", className: "shrink-0 gap-1.5", disabled: !text.trim() || send.isPending, children: [send.isPending ? _jsx(Loading, { className: "size-3.5 shrink-0" }) : _jsx(PaperPlaneRightIcon, { className: "size-3.5 shrink-0" }), t('send')] })] }));
115
+ }
@@ -0,0 +1,8 @@
1
+ import type { SubagentDialogProps } from './subagent-dialog-content.js';
2
+ export type { SubagentDialogProps } from './subagent-dialog-content.js';
3
+ /**
4
+ * THE dialog of a session another session started: a sub-agent, a teammate, a
5
+ * workflow agent or runner. Every entry point opens this one (the agents line,
6
+ * notice rows, the agent and workflow tool cards, the worker report card).
7
+ */
8
+ export declare function SubagentDialog(props: SubagentDialogProps): import("react").JSX.Element | null;
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useOpenedOnce } from '../../internal/hooks/use-opened-once.js';
4
+ import { lazyClient } from '../../lib/lazy-client.js';
5
+ // Tool rows, notices and the agents line render this dialog closed on every
6
+ // transcript (the marketing home demo too), so its body loads on first open.
7
+ const SubagentDialogContent = lazyClient(() => import('./subagent-dialog-content.js').then((mod) => mod.SubagentDialogContent));
8
+ /**
9
+ * THE dialog of a session another session started: a sub-agent, a teammate, a
10
+ * workflow agent or runner. Every entry point opens this one (the agents line,
11
+ * notice rows, the agent and workflow tool cards, the worker report card).
12
+ */
13
+ export function SubagentDialog(props) {
14
+ const opened = useOpenedOnce(props.open);
15
+ if (!opened)
16
+ return null;
17
+ return _jsx(SubagentDialogContent, { ...props });
18
+ }
@@ -0,0 +1,13 @@
1
+ import type { SessionTask, SessionTaskStatus } from '@kortix/sdk';
2
+ /**
3
+ * A team's shared task list (flag `agent_teams`), Claude Code's Ctrl+T task
4
+ * list: pending, in progress and completed, each task with its number, the
5
+ * teammate that owns it and the tasks it waits for. A blocked task says so;
6
+ * teammates do not claim it until those tasks complete.
7
+ */
8
+ export declare const TASK_GROUPS: readonly SessionTaskStatus[];
9
+ export declare function groupTasks(tasks: readonly SessionTask[]): Record<SessionTaskStatus, SessionTask[]>;
10
+ export declare function TasksPanel({ tasks, id }: {
11
+ tasks: readonly SessionTask[];
12
+ id?: string;
13
+ }): import("react").JSX.Element;
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Badge } from '../../primitives/badge.js';
4
+ import { CountBadge } from '../../primitives/count-badge.js';
5
+ import { useTranslations } from '../../i18n/index.js';
6
+ import { cn } from '../../lib/utils.js';
7
+ import { CheckIcon, CircleDashedIcon, CircleHalfIcon, LockSimpleIcon } from '@phosphor-icons/react';
8
+ /**
9
+ * A team's shared task list (flag `agent_teams`), Claude Code's Ctrl+T task
10
+ * list: pending, in progress and completed, each task with its number, the
11
+ * teammate that owns it and the tasks it waits for. A blocked task says so;
12
+ * teammates do not claim it until those tasks complete.
13
+ */
14
+ export const TASK_GROUPS = ['pending', 'in_progress', 'completed'];
15
+ export function groupTasks(tasks) {
16
+ const groups = { pending: [], in_progress: [], completed: [] };
17
+ for (const task of tasks)
18
+ groups[task.status]?.push(task);
19
+ for (const list of Object.values(groups))
20
+ list.sort((a, b) => a.seq - b.seq);
21
+ return groups;
22
+ }
23
+ function TaskGlyph({ task }) {
24
+ if (task.status === 'completed')
25
+ return _jsx(CheckIcon, { "aria-hidden": true, className: "text-kortix-green size-3 shrink-0" });
26
+ if (task.status === 'in_progress')
27
+ return _jsx(CircleHalfIcon, { "aria-hidden": true, className: "text-foreground size-3 shrink-0" });
28
+ if (task.blocked)
29
+ return _jsx(LockSimpleIcon, { "aria-hidden": true, className: "text-muted-foreground size-3 shrink-0" });
30
+ return _jsx(CircleDashedIcon, { "aria-hidden": true, className: "text-muted-foreground size-3 shrink-0" });
31
+ }
32
+ function TaskRow({ task }) {
33
+ const t = useTranslations('multiAgent.tasks');
34
+ const done = task.status === 'completed';
35
+ return (_jsxs("li", { "data-task-seq": task.seq, className: "flex min-w-0 items-center gap-2 rounded-sm px-2 py-1 text-xs", children: [_jsx(TaskGlyph, { task: task }), _jsxs("span", { className: "text-muted-foreground shrink-0 tabular-nums", children: ["#", task.seq] }), _jsx("span", { className: cn('min-w-0 flex-1 truncate', done ? 'text-muted-foreground line-through' : 'text-foreground'), title: task.description || task.subject, children: task.subject }), task.blocked && !done && task.blocked_by.length > 0 && (_jsx("span", { className: "text-muted-foreground shrink-0 tabular-nums", children: t('blockedBy', { tasks: task.blocked_by.map((seq) => `#${seq}`).join(', ') }) })), task.owner_handle ? (_jsxs(Badge, { variant: "outline", size: "sm", className: "max-w-32 shrink-0 truncate", children: ["@", task.owner_handle] })) : (!done && (_jsx(Badge, { variant: "muted", size: "sm", className: "shrink-0", children: t('unowned') })))] }));
36
+ }
37
+ export function TasksPanel({ tasks, id }) {
38
+ const t = useTranslations('multiAgent.tasks');
39
+ const groups = groupTasks(tasks);
40
+ return (_jsx("section", { id: id, "aria-label": t('label'), className: "space-y-1", children: tasks.length === 0 ? (_jsx("p", { className: "text-muted-foreground px-2 py-1 text-xs", children: t('empty') })) : (TASK_GROUPS.map((status) => groups[status].length === 0 ? null : (_jsxs("div", { children: [_jsxs("div", { className: "text-muted-foreground flex items-center gap-1.5 px-2 pt-1 text-xs font-medium", children: [t(`group.${status}`), _jsx(CountBadge, { count: groups[status].length })] }), _jsx("ul", { children: groups[status].map((task) => (_jsx(TaskRow, { task: task }, task.seq))) })] }, status)))) }));
41
+ }
@@ -0,0 +1,43 @@
1
+ import { type WorkflowRun, type WorkflowRunAgent } from '../tool/tools/workflow-run.js';
2
+ /**
3
+ * One workflow run's controls, for the run card in the chat and the strip's
4
+ * "Workflows" group: Claude Code's `/workflows` keys as buttons. Pause or
5
+ * resume (`p`), stop the run (`x`), save its script as a workflow (`s`), and,
6
+ * per agent row, restart (`r`). Every control goes to the box that runs the
7
+ * run: the session that called `workflow`, or a background run's runner.
8
+ */
9
+ /** A run's large-run warning: more agents than Claude Code's "Large workflow" threshold, or the run says so. */
10
+ export declare function isLargeRun(run: Pick<WorkflowRun, 'agents' | 'large' | 'maxAgents'>): boolean;
11
+ /** The file name a run saves as: its saved name, else its title in kebab case. */
12
+ export declare function workflowFileName(run: Pick<WorkflowRun, 'name' | 'title'>): string;
13
+ /**
14
+ * The live copy of a run: a background run's progress lives on its runner's box,
15
+ * so it is read from there (`useSessionWorkflows(project, runner)`, polled while it
16
+ * runs) and keeps updating after this session's turn ended. A foreground run is the
17
+ * card's own metadata. `controlSessionId` is the session whose box takes the controls.
18
+ */
19
+ export declare function useLiveWorkflowRun(projectId: string | undefined, sessionId: string | undefined, run: WorkflowRun | null): {
20
+ run: WorkflowRun | null;
21
+ controlSessionId: string | undefined;
22
+ fromRunner: boolean;
23
+ };
24
+ /** The current time, every second while `active`: a live run's elapsed labels tick. */
25
+ export declare function useNow(active: boolean): number;
26
+ /** The prompt "Save" sends to the session that owns the run. */
27
+ export declare function useSaveWorkflowPrompt(): (run: WorkflowRun) => string;
28
+ export declare function LargeRunBadge(): import("react").JSX.Element;
29
+ export interface WorkflowRunControlsProps {
30
+ projectId: string | undefined;
31
+ /** The box that runs the run (the runner of a background run). */
32
+ controlSessionId: string | undefined;
33
+ /** The session the "Save as workflow" prompt goes to: the one that started the run. */
34
+ ownerSessionId: string | undefined;
35
+ run: WorkflowRun;
36
+ }
37
+ export declare function WorkflowRunControls({ projectId, controlSessionId, ownerSessionId, run }: WorkflowRunControlsProps): import("react").JSX.Element | null;
38
+ /** `restart_agent` for one agent row of a run, on the box that runs it. */
39
+ export declare function useRestartAgent(projectId: string | undefined, controlSessionId: string | undefined, run: WorkflowRun | null): {
40
+ enabled: boolean;
41
+ restarting: string | undefined;
42
+ restart: (agent: WorkflowRunAgent) => void;
43
+ };
@@ -0,0 +1,141 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { Badge } from '../../primitives/badge.js';
4
+ import { Button } from '../../primitives/button.js';
5
+ import { ButtonGroup } from '../../primitives/button-group.js';
6
+ import { Hint } from '../../primitives/hint.js';
7
+ import Loading from '../../primitives/loading.js';
8
+ import { errorToast, successToast } from '../../primitives/toast.js';
9
+ import { useTranslations } from '../../i18n/index.js';
10
+ import { FloppyDiskIcon, PauseIcon, PlayIcon, SquareIcon, WarningIcon } from '@phosphor-icons/react';
11
+ import { useEffect, useMemo, useState } from 'react';
12
+ import { WORKFLOW_LARGE_AGENT_COUNT } from '@kortix/sdk';
13
+ import { useSessionWorkflows } from '@kortix/sdk/react';
14
+ import { parseWorkflowRun } from '../tool/tools/workflow-run.js';
15
+ import { useSessionPromptSend } from './session-prompt.js';
16
+ /**
17
+ * One workflow run's controls, for the run card in the chat and the strip's
18
+ * "Workflows" group: Claude Code's `/workflows` keys as buttons. Pause or
19
+ * resume (`p`), stop the run (`x`), save its script as a workflow (`s`), and,
20
+ * per agent row, restart (`r`). Every control goes to the box that runs the
21
+ * run: the session that called `workflow`, or a background run's runner.
22
+ */
23
+ /** A run's large-run warning: more agents than Claude Code's "Large workflow" threshold, or the run says so. */
24
+ export function isLargeRun(run) {
25
+ return run.large === true || run.agents.length > WORKFLOW_LARGE_AGENT_COUNT;
26
+ }
27
+ /** The file name a run saves as: its saved name, else its title in kebab case. */
28
+ export function workflowFileName(run) {
29
+ const base = (run.name || run.title || '')
30
+ .toLowerCase()
31
+ .normalize('NFKD')
32
+ .replace(/[^a-z0-9]+/g, '-')
33
+ .replace(/^-+|-+$/g, '')
34
+ .slice(0, 48)
35
+ .replace(/-+$/g, '');
36
+ return base || 'workflow';
37
+ }
38
+ /**
39
+ * The live copy of a run: a background run's progress lives on its runner's box,
40
+ * so it is read from there (`useSessionWorkflows(project, runner)`, polled while it
41
+ * runs) and keeps updating after this session's turn ended. A foreground run is the
42
+ * card's own metadata. `controlSessionId` is the session whose box takes the controls.
43
+ */
44
+ export function useLiveWorkflowRun(projectId, sessionId, run) {
45
+ const runner = run?.background?.sessionId;
46
+ const { data } = useSessionWorkflows(projectId, runner, { enabled: !!projectId && !!runner });
47
+ const live = useMemo(() => {
48
+ if (!run || !runner || !data)
49
+ return null;
50
+ const match = data.find((candidate) => candidate.runId === run.runId) ?? (run.runId ? undefined : data[0]);
51
+ const parsed = match ? parseWorkflowRun(match) : null;
52
+ // The runner runs it in the foreground; this card still knows it as a background run.
53
+ return parsed ? { ...parsed, background: run.background } : null;
54
+ }, [run, runner, data]);
55
+ if (!run)
56
+ return { run: null, controlSessionId: undefined, fromRunner: false };
57
+ if (runner)
58
+ return { run: live ?? run, controlSessionId: runner, fromRunner: !!live };
59
+ return { run, controlSessionId: sessionId, fromRunner: false };
60
+ }
61
+ /** The current time, every second while `active`: a live run's elapsed labels tick. */
62
+ export function useNow(active) {
63
+ const [now, setNow] = useState(() => Date.now());
64
+ useEffect(() => {
65
+ if (!active)
66
+ return;
67
+ const timer = setInterval(() => setNow(Date.now()), 1_000);
68
+ return () => clearInterval(timer);
69
+ }, [active]);
70
+ return now;
71
+ }
72
+ /** The prompt "Save" sends to the session that owns the run. */
73
+ export function useSaveWorkflowPrompt() {
74
+ const t = useTranslations('multiAgent.workflow');
75
+ return (run) => t('savePrompt', { title: run.title || run.name || run.runId, runId: run.runId, file: `.kortix/workflows/${workflowFileName(run)}.js` });
76
+ }
77
+ export function LargeRunBadge() {
78
+ const t = useTranslations('multiAgent.workflow');
79
+ return (_jsx(Hint, { label: t('largeHint'), side: "top", children: _jsxs(Badge, { variant: "warning", size: "sm", children: [_jsx(WarningIcon, { weight: "fill", "aria-hidden": true }), t('large')] }) }));
80
+ }
81
+ export function WorkflowRunControls({ projectId, controlSessionId, ownerSessionId, run }) {
82
+ const t = useTranslations('multiAgent.workflow');
83
+ const { control } = useSessionWorkflows(projectId, controlSessionId, { enabled: false });
84
+ const send = useSessionPromptSend(ownerSessionId);
85
+ const savePrompt = useSaveWorkflowPrompt();
86
+ const running = run.status === 'running';
87
+ const canControl = !!projectId && !!controlSessionId && !!run.runId && running;
88
+ const pending = control.isPending ? control.variables?.body.action : undefined;
89
+ const act = (action) => control.mutate({ runId: run.runId, body: { action } }, {
90
+ onError: (error) => errorToast(t(`failed.${action}`), { description: error instanceof Error ? error.message : undefined }),
91
+ });
92
+ const save = async () => {
93
+ if (!send)
94
+ return;
95
+ try {
96
+ await send(savePrompt(run));
97
+ successToast(t('saveSent'));
98
+ }
99
+ catch (error) {
100
+ errorToast(t('saveFailed'), { description: error instanceof Error ? error.message : undefined });
101
+ }
102
+ };
103
+ const buttons = [
104
+ canControl && (_jsx(Hint, { label: run.paused ? t('resumeHint') : t('pauseHint'), side: "top", children: _jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", "aria-label": run.paused ? t('resume') : t('pause'), disabled: !!pending, onClick: (event) => {
105
+ event.stopPropagation();
106
+ act(run.paused ? 'resume' : 'pause');
107
+ }, children: pending === 'pause' || pending === 'resume' ? (_jsx(Loading, { className: "size-3 shrink-0" })) : run.paused ? (_jsx(PlayIcon, { weight: "fill", className: "size-3 shrink-0" })) : (_jsx(PauseIcon, { weight: "fill", className: "size-3 shrink-0" })) }) }, "pause")),
108
+ canControl && (_jsx(Hint, { label: t('stopHint'), side: "top", children: _jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", "aria-label": t('stop'), disabled: !!pending, onClick: (event) => {
109
+ event.stopPropagation();
110
+ act('stop');
111
+ }, children: pending === 'stop' ? _jsx(Loading, { className: "size-3 shrink-0" }) : _jsx(SquareIcon, { weight: "fill", className: "size-2.5 shrink-0" }) }) }, "stop")),
112
+ // A saved workflow is a file already; any other run can become one.
113
+ !run.name && send && run.runId && (_jsx(Hint, { label: t('saveHint'), side: "top", children: _jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", "aria-label": t('save'), onClick: (event) => {
114
+ event.stopPropagation();
115
+ void save();
116
+ }, children: _jsx(FloppyDiskIcon, { className: "size-3 shrink-0" }) }) }, "save")),
117
+ ].filter(Boolean);
118
+ if (buttons.length === 0)
119
+ return null;
120
+ return buttons.length === 1 ? _jsx(_Fragment, { children: buttons }) : _jsx(ButtonGroup, { children: buttons });
121
+ }
122
+ /** `restart_agent` for one agent row of a run, on the box that runs it. */
123
+ export function useRestartAgent(projectId, controlSessionId, run) {
124
+ const t = useTranslations('multiAgent.workflow');
125
+ const { control } = useSessionWorkflows(projectId, controlSessionId, { enabled: false });
126
+ const enabled = !!projectId && !!controlSessionId && !!run?.runId && run.status === 'running';
127
+ const restarting = control.isPending && control.variables?.body.action === 'restart_agent' ? control.variables.body.session_id : undefined;
128
+ return {
129
+ enabled,
130
+ restarting,
131
+ restart: (agent) => {
132
+ if (!enabled || !agent.sessionId || !run)
133
+ return;
134
+ control.mutate({ runId: run.runId, body: { action: 'restart_agent', session_id: agent.sessionId } }, {
135
+ onError: (error) => errorToast(t('failed.restart', { label: agent.label }), {
136
+ description: error instanceof Error ? error.message : undefined,
137
+ }),
138
+ });
139
+ },
140
+ };
141
+ }
@@ -71,4 +71,4 @@ export interface ComposerCardDerived {
71
71
  noModelsConnected: boolean;
72
72
  }
73
73
  export type ComposerCardProps = SessionChatInputProps & ComposerCardDerived;
74
- export declare function ComposerCard({ tHardcodedUi, isDragOver, handleDragEnter, handleDragOver, handleDragLeave, handleDropFiles, attachedFiles, promptAttachmentItems, removeAttachedFile, retryAttachedFile, pastes, removePaste, onOpenPastedContent, commandAttachmentPlan, editorDisabled, editorRef, setEditorRef, editorPlaceholder, animatePlaceholder, handleSubmit, handleArrowUpAtStart, setIsEmpty, handleDocChange, allSessions, slashActions, handleSelectAction, dockId, setMenuOpen, fileInputRef, handleFileSelect, sessionId, handleAttachClick, primaryAgents, availableSelectedModel, agentMenuOpen, setAgentMenuOpen, modelMenuOpen, setModelMenuOpen, reasoningMenuOpen, setReasoningMenuOpen, isEmpty, canSubmit, submitDisabled, attachmentFailed, modelRejectingImages, imagesUnsupportedReason, modelUnavailable, agentUnavailable, noModelsConnected, agents, commands, slashFiles, models, notice, disabled, lockForQuestion, lockForApproval, questionButtonLabel, questionActive, submitLabel, questionCanAct, escCount, isBusy, isSending, onStop, stopDisabled, canStop, modelsLoading, modelRequired, onModelChange, modelDefaultControls, providers, variants, selectedVariant, onVariantChange, projectId, toolbarSlot, rewind, selectedAgent, onAgentChange, noAccessibleAgents, onContextClick, messages, underbarPlacement, agentPickerCompact, slashMenuPlacement, cardClassName, onArrowUpAtStart, }: ComposerCardProps): import("react").JSX.Element;
74
+ export declare function ComposerCard({ tHardcodedUi, isDragOver, handleDragEnter, handleDragOver, handleDragLeave, handleDropFiles, attachedFiles, promptAttachmentItems, removeAttachedFile, retryAttachedFile, pastes, removePaste, onOpenPastedContent, commandAttachmentPlan, editorDisabled, editorRef, setEditorRef, editorPlaceholder, animatePlaceholder, handleSubmit, handleArrowUpAtStart, setIsEmpty, handleDocChange, allSessions, slashActions, handleSelectAction, dockId, setMenuOpen, fileInputRef, handleFileSelect, sessionId, handleAttachClick, primaryAgents, availableSelectedModel, agentMenuOpen, setAgentMenuOpen, modelMenuOpen, setModelMenuOpen, reasoningMenuOpen, setReasoningMenuOpen, isEmpty, canSubmit, submitDisabled, attachmentFailed, modelRejectingImages, imagesUnsupportedReason, modelUnavailable, agentUnavailable, noModelsConnected, agents, commands, slashFiles, models, notice, disabled, lockForQuestion, lockForApproval, questionButtonLabel, questionActive, submitLabel, questionCanAct, escCount, isBusy, isSending, onStop, stopDisabled, canStop, modelsLoading, modelRequired, onModelChange, modelDefaultControls, providers, variants, selectedVariant, onVariantChange, projectId, toolbarSlot, underbarSlot, rewind, selectedAgent, onAgentChange, noAccessibleAgents, onContextClick, messages, underbarPlacement, agentPickerCompact, slashMenuPlacement, cardClassName, onArrowUpAtStart, }: ComposerCardProps): import("react").JSX.Element;
@@ -21,7 +21,7 @@ export function ComposerCard({ tHardcodedUi, isDragOver, handleDragEnter, handle
21
21
  // Raw props the moved JSX reads; `{...props}` carries the rest. These
22
22
  // defaults mirror `ComposerImpl`'s, because the spread passes the raw
23
23
  // values, not the component's defaulted locals.
24
- agents = EMPTY_AGENTS, commands = EMPTY_COMMANDS, slashFiles = EMPTY_SLASH_FILES, models = EMPTY_MODELS, notice = null, disabled = false, lockForQuestion = false, lockForApproval = false, questionButtonLabel = null, questionActive = false, submitLabel = null, questionCanAct = true, escCount = 0, isBusy = false, isSending = false, onStop, stopDisabled = false, canStop = true, modelsLoading = false, modelRequired = false, onModelChange, modelDefaultControls, providers, variants = EMPTY_VARIANTS, selectedVariant = null, onVariantChange, projectId, toolbarSlot, rewind, selectedAgent = null, onAgentChange, noAccessibleAgents = false, onContextClick, messages, underbarPlacement = 'below', agentPickerCompact = false, slashMenuPlacement = 'above', cardClassName, onArrowUpAtStart, }) {
24
+ agents = EMPTY_AGENTS, commands = EMPTY_COMMANDS, slashFiles = EMPTY_SLASH_FILES, models = EMPTY_MODELS, notice = null, disabled = false, lockForQuestion = false, lockForApproval = false, questionButtonLabel = null, questionActive = false, submitLabel = null, questionCanAct = true, escCount = 0, isBusy = false, isSending = false, onStop, stopDisabled = false, canStop = true, modelsLoading = false, modelRequired = false, onModelChange, modelDefaultControls, providers, variants = EMPTY_VARIANTS, selectedVariant = null, onVariantChange, projectId, toolbarSlot, underbarSlot, rewind, selectedAgent = null, onAgentChange, noAccessibleAgents = false, onContextClick, messages, underbarPlacement = 'below', agentPickerCompact = false, slashMenuPlacement = 'above', cardClassName, onArrowUpAtStart, }) {
25
25
  const cardRef = useRef(null);
26
26
  const { attachAccept } = useUiHostConfig();
27
27
  const inlineUnderbar = underbarPlacement === 'inline';
@@ -51,7 +51,7 @@ agents = EMPTY_AGENTS, commands = EMPTY_COMMANDS, slashFiles = EMPTY_SLASH_FILES
51
51
  // the div and immediately fights the caret we are placing.
52
52
  e.preventDefault();
53
53
  editorRef.current?.focus();
54
- }, children: [_jsx(AnimatedComposerPlaceholder, { placeholder: editorPlaceholder, active: animatePlaceholder }), _jsx(Suspense, { fallback: _jsx(ComposerEditorFallback, {}), children: _jsx(ComposerEditorLazy, { ref: setEditorRef, placeholder: animatePlaceholder ? '' : editorPlaceholder, disabled: editorDisabled, onSubmit: handleSubmit, onArrowUpAtStart: onArrowUpAtStart ? handleArrowUpAtStart : undefined, onEmptyChange: setIsEmpty, onDocChange: handleDocChange, agents: agents, sessions: allSessions ?? [], currentSessionId: sessionId, commands: commands, actions: slashActions, files: slashFiles, onSelectAction: handleSelectAction, slashDockSelector: `#${dockId}`, onMenuOpenChange: setMenuOpen }) })] }), _jsx("input", { ref: fileInputRef, type: "file", accept: attachAccept ?? DEFAULT_ATTACH_ACCEPT, multiple: true, className: "hidden", onChange: handleFileSelect }), _jsx(ComposerToolbar, { leading: inlineUnderbar ? (_jsx(ComposerUnderbar, { variant: "inline", agentPickerCompact: agentPickerCompact, onAttachClick: handleAttachClick, agents: primaryAgents, selectedAgent: selectedAgent, onAgentChange: onAgentChange, agentMenuOpen: agentMenuOpen, onAgentMenuOpenChange: setAgentMenuOpen, noAccessibleAgents: noAccessibleAgents, messages: messages, models: models, selectedModel: availableSelectedModel, onContextClick: onContextClick })) : null, modelsLoading: modelsLoading, models: models, selectedModel: availableSelectedModel, onModelChange: onModelChange, modelDefaultControls: modelDefaultControls, providers: providers, modelRequired: modelRequired, modelMenuOpen: modelMenuOpen, onModelMenuOpenChange: setModelMenuOpen, reasoningMenuOpen: reasoningMenuOpen, onReasoningMenuOpenChange: setReasoningMenuOpen, variants: variants, selectedVariant: selectedVariant, onVariantChange: onVariantChange, projectId: projectId,
54
+ }, children: [_jsx(AnimatedComposerPlaceholder, { placeholder: editorPlaceholder, active: animatePlaceholder }), _jsx(Suspense, { fallback: _jsx(ComposerEditorFallback, {}), children: _jsx(ComposerEditorLazy, { ref: setEditorRef, placeholder: animatePlaceholder ? '' : editorPlaceholder, disabled: editorDisabled, onSubmit: handleSubmit, onArrowUpAtStart: onArrowUpAtStart ? handleArrowUpAtStart : undefined, onEmptyChange: setIsEmpty, onDocChange: handleDocChange, agents: agents, sessions: allSessions ?? [], currentSessionId: sessionId, commands: commands, actions: slashActions, files: slashFiles, onSelectAction: handleSelectAction, slashDockSelector: `#${dockId}`, onMenuOpenChange: setMenuOpen }) })] }), _jsx("input", { ref: fileInputRef, type: "file", accept: attachAccept ?? DEFAULT_ATTACH_ACCEPT, multiple: true, className: "hidden", onChange: handleFileSelect }), _jsx(ComposerToolbar, { leading: inlineUnderbar ? (_jsx(ComposerUnderbar, { variant: "inline", agentPickerCompact: agentPickerCompact, onAttachClick: handleAttachClick, agents: primaryAgents, selectedAgent: selectedAgent, onAgentChange: onAgentChange, agentMenuOpen: agentMenuOpen, onAgentMenuOpenChange: setAgentMenuOpen, noAccessibleAgents: noAccessibleAgents, messages: messages, models: models, selectedModel: availableSelectedModel, onContextClick: onContextClick, agentsSlot: underbarSlot })) : null, modelsLoading: modelsLoading, models: models, selectedModel: availableSelectedModel, onModelChange: onModelChange, modelDefaultControls: modelDefaultControls, providers: providers, modelRequired: modelRequired, modelMenuOpen: modelMenuOpen, onModelMenuOpenChange: setModelMenuOpen, reasoningMenuOpen: reasoningMenuOpen, onReasoningMenuOpenChange: setReasoningMenuOpen, variants: variants, selectedVariant: selectedVariant, onVariantChange: onVariantChange, projectId: projectId,
55
55
  // Inline placement has no under-row, so the slot (the session
56
56
  // overrides gear, meta indicator) rides the toolbar itself. With
57
57
  // the 'below' placement the ComposerUnderbar further down renders
@@ -59,5 +59,5 @@ agents = EMPTY_AGENTS, commands = EMPTY_COMMANDS, slashFiles = EMPTY_SLASH_FILES
59
59
  toolbarSlot: inlineUnderbar ? toolbarSlot : undefined, rewind: rewind, isSending: isSending, isBusy: isBusy, onStop: onStop, stopDisabled: stopDisabled, canStop: canStop, escCount: escCount, lockForQuestion: lockForQuestion, questionButtonLabel: questionButtonLabel, submitLabel: submitLabel, questionCanAct: questionCanAct, hasText: !isEmpty, canSubmit: canSubmit, submitDisabled: submitDisabled ||
60
60
  attachmentFailed ||
61
61
  modelRejectingImages !== null ||
62
- commandAttachmentPlan.kind === 'refuse', attachmentFailed: attachmentFailed, attachmentUnsupported: imagesUnsupportedReason, disabled: disabled, modelUnavailable: modelUnavailable, agentUnavailable: agentUnavailable, onSubmit: () => handleSubmit() })] })] })] }), _jsx(ModelConnectionBar, { show: noModelsConnected }), _jsx(ImagesUnsupportedBar, { modelName: noModelsConnected ? null : modelRejectingImages }), inlineUnderbar ? null : (_jsx(ComposerUnderbar, { onAttachClick: handleAttachClick, agents: primaryAgents, selectedAgent: selectedAgent, onAgentChange: onAgentChange, agentMenuOpen: agentMenuOpen, onAgentMenuOpenChange: setAgentMenuOpen, noAccessibleAgents: noAccessibleAgents, messages: messages, models: models, selectedModel: availableSelectedModel, onContextClick: onContextClick, toolbarSlot: toolbarSlot })), slashMenuPlacement === 'below' && (_jsx("div", { id: dockId, className: "absolute top-full right-4 left-4 z-99 mt-3.5" }))] }));
62
+ commandAttachmentPlan.kind === 'refuse', attachmentFailed: attachmentFailed, attachmentUnsupported: imagesUnsupportedReason, disabled: disabled, modelUnavailable: modelUnavailable, agentUnavailable: agentUnavailable, onSubmit: () => handleSubmit() })] })] })] }), _jsx(ModelConnectionBar, { show: noModelsConnected }), _jsx(ImagesUnsupportedBar, { modelName: noModelsConnected ? null : modelRejectingImages }), inlineUnderbar ? null : (_jsx(ComposerUnderbar, { onAttachClick: handleAttachClick, agents: primaryAgents, selectedAgent: selectedAgent, onAgentChange: onAgentChange, agentMenuOpen: agentMenuOpen, onAgentMenuOpenChange: setAgentMenuOpen, noAccessibleAgents: noAccessibleAgents, messages: messages, models: models, selectedModel: availableSelectedModel, onContextClick: onContextClick, toolbarSlot: toolbarSlot, agentsSlot: underbarSlot })), slashMenuPlacement === 'below' && (_jsx("div", { id: dockId, className: "absolute top-full right-4 left-4 z-99 mt-3.5" }))] }));
63
63
  }
@@ -1,6 +1,5 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { Badge } from '../../primitives/badge.js';
4
3
  import { Button } from '../../primitives/button.js';
5
4
  import { CommandGroup, CommandInput, CommandItem, CommandList, CommandPopover, CommandPopoverContent, CommandPopoverTrigger, CommandSeparator, } from '../../primitives/command.js';
6
5
  import Hint from '../../primitives/hint.js';
@@ -8,7 +7,7 @@ import { useTranslations } from '../../i18n/index.js';
8
7
  import { useUiHostConfig } from '../../providers/ui-provider.js';
9
8
  import { cn } from '../../lib/utils.js';
10
9
  import { TRIGGER_CARET_CLASS, triggerVariants } from '../../primitives/trigger-variants.js';
11
- import { capitalizeWords, isMetaAgentName, META_AGENT_DISPLAY_NAME } from '../../_vendor/kortix-shared.js';
10
+ import { capitalizeWords, isMyKortixAgentName, MY_KORTIX_DISPLAY_NAME } from '../../_vendor/kortix-shared.js';
12
11
  import { CaretDownIcon, CheckIcon } from '@phosphor-icons/react';
13
12
  import { AgentMark } from '../../internal/components/agent-mark.js';
14
13
  import { createContext, useContext, useEffect, useMemo, useState } from 'react';
@@ -42,7 +41,7 @@ export function agentDisplayLabel(agents, selectedAgent) {
42
41
  const name = resolveDisplayedAgentName(composerSelectableAgents(agents), selectedAgent);
43
42
  if (!name)
44
43
  return 'Agent';
45
- return isMetaAgentName(name) ? META_AGENT_DISPLAY_NAME : capitalizeWords(name);
44
+ return isMyKortixAgentName(name) ? MY_KORTIX_DISPLAY_NAME : capitalizeWords(name);
46
45
  }
47
46
  export function AgentSelector({ agents, selectedAgent, onSelect, disabled = false, triggerLabelClassName, unavailableHint, open: controlledOpen, onOpenChange, compact = false, appearance = 'chip', }) {
48
47
  const tHardcodedUi = useTranslations('hardcodedUi');
@@ -60,7 +59,7 @@ export function AgentSelector({ agents, selectedAgent, onSelect, disabled = fals
60
59
  return agents.filter((a) => offeredNames.has(a.name));
61
60
  }, [agents, offeredAgents]);
62
61
  const primaryAgents = useMemo(() => composerSelectableAgents(offered), [offered]);
63
- const label = (name) => agentLabels?.[name] ?? (isMetaAgentName(name) ? META_AGENT_DISPLAY_NAME : capitalizeWords(name));
62
+ const label = (name) => agentLabels?.[name] ?? (isMyKortixAgentName(name) ? MY_KORTIX_DISPLAY_NAME : capitalizeWords(name));
64
63
  // A `flash` state, a `prevAgentRef` feeding it, two effects and a 400ms
65
64
  // timer used to live here. Nothing ever READ `flash` — it was written on
66
65
  // every agent change and rendered nowhere, so the whole apparatus bought a
@@ -77,8 +76,8 @@ export function AgentSelector({ agents, selectedAgent, onSelect, disabled = fals
77
76
  (agentLabels?.[a.name] ?? '').toLowerCase().includes(q) ||
78
77
  (a.description || '').toLowerCase().includes(q));
79
78
  }, [primaryAgents, search, agentLabels]);
80
- const filteredMeta = useMemo(() => filteredPrimary.filter((a) => isMetaAgentName(a.name)), [filteredPrimary]);
81
- const filteredProject = useMemo(() => filteredPrimary.filter((a) => !isMetaAgentName(a.name)), [filteredPrimary]);
79
+ const filteredMeta = useMemo(() => filteredPrimary.filter((a) => isMyKortixAgentName(a.name)), [filteredPrimary]);
80
+ const filteredProject = useMemo(() => filteredPrimary.filter((a) => !isMyKortixAgentName(a.name)), [filteredPrimary]);
82
81
  // The place's agents, in its order, then every other agent.
83
82
  const featured = useContext(FeaturedAgentsContext);
84
83
  const filteredFeatured = useMemo(() => (featured?.names ?? []).flatMap((name) => {
@@ -106,16 +105,11 @@ export function AgentSelector({ agents, selectedAgent, onSelect, disabled = fals
106
105
  const field = appearance === 'field';
107
106
  const fieldTrigger = (caret, props) => (_jsxs("button", { type: "button", className: cn(triggerVariants(), 'h-9 w-full'), ...props, children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [triggerMark, _jsx("span", { className: "truncate", children: displayName })] }), caret ? _jsx(CaretDownIcon, { className: cn(TRIGGER_CARET_CLASS, 'size-4') }) : null] }));
108
107
  /**
109
- * One agent: name, its type, its description, and a check when it is the
110
- * one in use.
108
+ * One agent: its mark, name and description (My Kortix: what picking it
109
+ * does), and a check when it is the one in use.
111
110
  *
112
- * The type is a `Badge` on the row rather than a `CommandGroup` heading.
113
- * Headings only earn their place when there is more than one section to
114
- * tell apart, and there usually is not — most projects have no meta agents
115
- * at all, so the list rendered a lone "Agents" label over a single group,
116
- * captioning something that needed no caption. A badge says the same thing
117
- * where it is actually useful (on the row that differs) and disappears
118
- * entirely when every agent is the same kind.
111
+ * No type badge and no group heading: My Kortix sorts first, a separator
112
+ * follows it, and its own line says what it does.
119
113
  *
120
114
  * Selection is shown ONCE, by the check plus the tinted row. It used to be
121
115
  * said three times — check, tinted row, AND a heavier font weight on the
@@ -131,7 +125,7 @@ export function AgentSelector({ agents, selectedAgent, onSelect, disabled = fals
131
125
  className: cn('items-start gap-2 py-2', isSelected && 'bg-primary/[0.06]'), onSelect: () => {
132
126
  onSelect(agent.name);
133
127
  setOpen(false);
134
- }, children: [agent.description ? (_jsx(AgentMark, { slug: agent.name, size: 28, tile: 36 })) : (_jsx(AgentMark, { slug: agent.name, size: 14 })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [_jsx("span", { className: "text-foreground truncate text-sm font-medium", children: label(agent.name) }), meta && (_jsx(Badge, { variant: "outline", size: "xs", className: "shrink-0 font-normal", children: tHardcodedUi.raw('i18nComplete.textc78ffe195710') }))] }), agent.description && (_jsx("p", { className: "text-muted-foreground truncate text-xs", children: agent.description }))] }), isSelected && (
128
+ }, children: [agent.description || meta ? (_jsx(AgentMark, { slug: agent.name, size: 28, tile: 36 })) : (_jsx(AgentMark, { slug: agent.name, size: 14 })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "text-foreground block truncate text-sm font-medium", children: label(agent.name) }), meta ? (_jsx("p", { className: "text-muted-foreground text-xs", children: t('myKortixRoutes') })) : agent.description ? (_jsx("p", { className: "text-muted-foreground line-clamp-2 text-xs text-pretty", children: agent.description })) : null] }), isSelected && (
135
129
  // `mt-0.5` optically centres the 16px check against the first line
136
130
  // rather than the top edge of the text box.
137
131
  _jsx(CheckIcon, { className: "text-foreground mt-0.5 size-4 shrink-0" }))] }, agent.name));
@@ -173,11 +167,11 @@ export function AgentSelector({ agents, selectedAgent, onSelect, disabled = fals
173
167
  // The mark alone: the name is the tooltip and the menu's checked row.
174
168
  // A placeholder name has no mark, so it shows as text.
175
169
  triggerMark ?? _jsx("span", { className: cn('max-w-[100px] truncate', triggerLabelClassName), children: displayName })) : (_jsxs(_Fragment, { children: [triggerMark, _jsx("span", { className: cn('max-w-[100px] truncate', triggerLabelClassName), children: displayName }), _jsx(CaretDownIcon, { className: cn('size-3 transition-transform duration-moderate ease-out', open && 'rotate-180') })] })) })) }));
176
- return (_jsxs(CommandPopover, { open: open, onOpenChange: setOpen, children: [compact ? (_jsx(Hint, { side: "top", label: displayName, children: trigger })) : (trigger), _jsxs(CommandPopoverContent, { side: "top", align: "start", sideOffset: 8, className: "w-[min(300px,calc(100vw-1.5rem))]", children: [_jsx("div", { className: showSearch ? undefined : 'sr-only', children: _jsx(CommandInput, { compact: true, placeholder: tHardcodedUi.raw('componentsSessionSessionChatInput.line231JsxAttrPlaceholderSearchAgents'), value: search, onValueChange: setSearch }) }), _jsxs(CommandList, { className: "max-h-[320px]", children: [filteredFeatured.length > 0 && featured ? (
170
+ return (_jsxs(CommandPopover, { open: open, onOpenChange: setOpen, children: [compact ? (_jsx(Hint, { side: "top", label: displayName, children: trigger })) : (trigger), _jsxs(CommandPopoverContent, { side: "top", align: "start", sideOffset: 8, className: "w-[min(340px,calc(100vw-1.5rem))]", children: [_jsx("div", { className: showSearch ? undefined : 'sr-only', children: _jsx(CommandInput, { compact: true, placeholder: tHardcodedUi.raw('componentsSessionSessionChatInput.line231JsxAttrPlaceholderSearchAgents'), value: search, onValueChange: setSearch }) }), _jsxs(CommandList, { className: "max-h-[320px]", children: [filteredFeatured.length > 0 && featured ? (
177
171
  // Two groups, so each earns its heading: the place's agents, then the rest.
178
- _jsxs(_Fragment, { children: [_jsx(CommandGroup, { forceMount: true, heading: featured.label, className: "[&_[cmdk-group-items]]:flex [&_[cmdk-group-items]]:flex-col [&_[cmdk-group-items]]:gap-px", children: filteredFeatured.map((agent) => renderAgentItem(agent, isMetaAgentName(agent.name))) }), filteredPrimary.length > filteredFeatured.length && (_jsx(CommandGroup, { forceMount: true, heading: featured.restLabel, className: "[&_[cmdk-group-items]]:flex [&_[cmdk-group-items]]:flex-col [&_[cmdk-group-items]]:gap-px", children: filteredPrimary
172
+ _jsxs(_Fragment, { children: [_jsx(CommandGroup, { forceMount: true, heading: featured.label, className: "[&_[cmdk-group-items]]:flex [&_[cmdk-group-items]]:flex-col [&_[cmdk-group-items]]:gap-px", children: filteredFeatured.map((agent) => renderAgentItem(agent, isMyKortixAgentName(agent.name))) }), filteredPrimary.length > filteredFeatured.length && (_jsx(CommandGroup, { forceMount: true, heading: featured.restLabel, className: "[&_[cmdk-group-items]]:flex [&_[cmdk-group-items]]:flex-col [&_[cmdk-group-items]]:gap-px", children: filteredPrimary
179
173
  .filter((agent) => !filteredFeatured.includes(agent))
180
- .map((agent) => renderAgentItem(agent, isMetaAgentName(agent.name))) }))] })) : filteredPrimary.length > 0 && (
174
+ .map((agent) => renderAgentItem(agent, isMyKortixAgentName(agent.name))) }))] })) : filteredPrimary.length > 0 && (
181
175
  // `gap-px` between rows: a selected row and a hovered row next to it
182
176
  // otherwise draw one merged grey block.
183
177
  _jsxs(CommandGroup, { forceMount: true, className: "[&_[cmdk-group-items]]:flex [&_[cmdk-group-items]]:flex-col [&_[cmdk-group-items]]:gap-px", children: [filteredMeta.map((agent) => renderAgentItem(agent, true)), filteredMeta.length > 0 && filteredProject.length > 0 && (_jsx(CommandSeparator, { className: "my-1" })), filteredProject.map((agent) => renderAgentItem(agent, false))] })), filteredPrimary.length === 0 && search.trim() && (_jsxs("div", { className: "text-muted-foreground py-8 text-center text-xs", children: [tHardcodedUi.raw('componentsSessionSessionChatInput.line273JsxTextNoAgentsMatchLdquo'), search.trim(), tHardcodedUi.raw('componentsSessionSessionChatInput.line273JsxTextRdquo')] }))] })] })] }));
@@ -52,5 +52,7 @@ export interface ComposerUnderbarProps {
52
52
  /** See `SessionChatInputProps.agentPickerCompact`. */
53
53
  agentPickerCompact?: boolean;
54
54
  toolbarSlot?: React.ReactNode;
55
+ /** Right of the agent picker: the session's agents line. Same row, no added height. */
56
+ agentsSlot?: React.ReactNode;
55
57
  }
56
- export declare function ComposerUnderbar({ onAttachClick, agents, selectedAgent, agentMenuOpen, onAgentMenuOpenChange, onAgentChange, noAccessibleAgents, messages, models, selectedModel, onContextClick, variant, agentPickerCompact, toolbarSlot, }: ComposerUnderbarProps): import("react").JSX.Element;
58
+ export declare function ComposerUnderbar({ onAttachClick, agents, selectedAgent, agentMenuOpen, onAgentMenuOpenChange, onAgentChange, noAccessibleAgents, messages, models, selectedModel, onContextClick, variant, agentPickerCompact, toolbarSlot, agentsSlot, }: ComposerUnderbarProps): import("react").JSX.Element;
@@ -14,7 +14,7 @@ import { TokenProgress } from './token-progress.js';
14
14
  const NO_AGENT_SELECT = () => { };
15
15
  /** Stable identity so the empty roster doesn't remount the picker per render. */
16
16
  const EMPTY_AGENTS = [];
17
- export function ComposerUnderbar({ onAttachClick, agents, selectedAgent, agentMenuOpen, onAgentMenuOpenChange, onAgentChange, noAccessibleAgents = false, messages, models, selectedModel, onContextClick, variant = 'row', agentPickerCompact = false, toolbarSlot, }) {
17
+ export function ComposerUnderbar({ onAttachClick, agents, selectedAgent, agentMenuOpen, onAgentMenuOpenChange, onAgentChange, noAccessibleAgents = false, messages, models, selectedModel, onContextClick, variant = 'row', agentPickerCompact = false, toolbarSlot, agentsSlot, }) {
18
18
  const t = useTranslations('threads');
19
19
  const { contextMeterEnabled } = useUiHostConfig();
20
20
  /*
@@ -55,5 +55,5 @@ export function ComposerUnderbar({ onAttachClick, agents, selectedAgent, agentMe
55
55
  : 'kortix-composer-underbar flex items-center justify-between gap-2 px-px pt-1.5 pb-2', children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1", children: [_jsx(Hint, { side: "top", label: t('attachFiles'), children: _jsx(Button, { type: "button", variant: "ghost", size: "icon-base", onClick: onAttachClick, "aria-label": t('attachFiles'),
56
56
  // `hit-area-3` — the ≈29px ghost chip clears the 44px mobile tap
57
57
  // floor only with the shared pseudo-element extension.
58
- className: "text-muted-foreground hit-area-3 rounded-lg", children: _jsx(Paperclip, { className: "size-4 shrink-0" }) }) }), _jsx(AgentSelector, { compact: agentPickerCompact, agents: noAccessibleAgents ? EMPTY_AGENTS : agents, selectedAgent: selectedAgent, open: agentMenuOpen, onOpenChange: onAgentMenuOpenChange, onSelect: onAgentChange ?? NO_AGENT_SELECT, triggerLabelClassName: "max-w-[7rem]", unavailableHint: noAccessibleAgents ? NO_AGENT_ACCESS_MESSAGE : undefined })] }), _jsxs("div", { className: "flex items-center gap-1", children: [(inline && !messages) || !contextMeterEnabled ? null : (_jsx(TokenProgress, { messages: messages, models: models, selectedModel: selectedModel, onContextClick: onContextClick })), toolbarSlot] })] }));
58
+ className: "text-muted-foreground hit-area-3 rounded-lg", children: _jsx(Paperclip, { className: "size-4 shrink-0" }) }) }), _jsx(AgentSelector, { compact: agentPickerCompact, agents: noAccessibleAgents ? EMPTY_AGENTS : agents, selectedAgent: selectedAgent, open: agentMenuOpen, onOpenChange: onAgentMenuOpenChange, onSelect: onAgentChange ?? NO_AGENT_SELECT, triggerLabelClassName: "max-w-[7rem]", unavailableHint: noAccessibleAgents ? NO_AGENT_ACCESS_MESSAGE : undefined }), agentsSlot] }), _jsxs("div", { className: "flex items-center gap-1", children: [(inline && !messages) || !contextMeterEnabled ? null : (_jsx(TokenProgress, { messages: messages, models: models, selectedModel: selectedModel, onContextClick: onContextClick })), toolbarSlot] })] }));
59
59
  }
@@ -234,6 +234,11 @@ export interface SessionChatInputProps {
234
234
  aboveSlot?: React.ReactNode;
235
235
  inputSlot?: React.ReactNode;
236
236
  toolbarSlot?: React.ReactNode;
237
+ /**
238
+ * Rides the under-row right of the agent picker, in both placements: the
239
+ * session's agents line (`AgentsLine`). It must not add height to the row.
240
+ */
241
+ underbarSlot?: React.ReactNode;
237
242
  /**
238
243
  * Where the under-row's controls live — attach, the agent picker and the
239
244
  * context ring.