@kortix/ui 0.14.12 → 0.14.14

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 (438) 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/customize/agents/agent-access-text.d.ts +16 -0
  18. package/dist/customize/agents/agent-access-text.js +54 -0
  19. package/dist/customize/agents/agent-approval-rules.d.ts +8 -0
  20. package/dist/customize/agents/agent-approval-rules.js +26 -0
  21. package/dist/customize/agents/agent-authority-card.js +4 -1
  22. package/dist/customize/agents/agent-cover-card.d.ts +4 -1
  23. package/dist/customize/agents/agent-cover-card.js +2 -2
  24. package/dist/customize/agents/agent-detail-aside.d.ts +1 -2
  25. package/dist/customize/agents/agent-detail-aside.js +8 -11
  26. package/dist/customize/agents/agent-drives-section.d.ts +23 -7
  27. package/dist/customize/agents/agent-drives-section.js +107 -41
  28. package/dist/customize/agents/agent-instructions.d.ts +11 -0
  29. package/dist/customize/agents/agent-instructions.js +114 -0
  30. package/dist/customize/agents/agent-model-view.d.ts +17 -0
  31. package/dist/customize/agents/agent-model-view.js +67 -0
  32. package/dist/customize/agents/agent-overview.d.ts +53 -0
  33. package/dist/customize/agents/agent-overview.js +242 -0
  34. package/dist/customize/agents/agent-page-chrome.d.ts +128 -0
  35. package/dist/customize/agents/agent-page-chrome.js +145 -0
  36. package/dist/customize/agents/agent-page.d.ts +13 -1
  37. package/dist/customize/agents/agent-page.js +478 -367
  38. package/dist/customize/agents/agent-pin-button.d.ts +10 -0
  39. package/dist/customize/agents/agent-pin-button.js +20 -0
  40. package/dist/customize/agents/agent-policy-sets-section.d.ts +16 -0
  41. package/dist/customize/agents/agent-policy-sets-section.js +80 -0
  42. package/dist/customize/agents/agent-policy-sets.js +1 -1
  43. package/dist/customize/agents/agent-section-rail.d.ts +21 -0
  44. package/dist/customize/agents/agent-section-rail.js +23 -0
  45. package/dist/customize/agents/agent-share-control.d.ts +4 -3
  46. package/dist/customize/agents/agent-share-control.js +15 -16
  47. package/dist/customize/agents/{agent-people-section.d.ts → agent-share-dialog.d.ts} +3 -1
  48. package/dist/customize/agents/{agent-people-section.js → agent-share-dialog.js} +21 -21
  49. package/dist/customize/agents/agent-tabs.d.ts +95 -0
  50. package/dist/customize/agents/agent-tabs.js +199 -0
  51. package/dist/customize/agents/agents-page.d.ts +0 -21
  52. package/dist/customize/agents/agents-page.js +104 -118
  53. package/dist/customize/agents/connectors-required.d.ts +16 -0
  54. package/dist/customize/agents/connectors-required.js +19 -0
  55. package/dist/customize/agents/create-agent-modal.d.ts +19 -0
  56. package/dist/customize/agents/create-agent-modal.js +94 -0
  57. package/dist/customize/connectors/agent-access.d.ts +4 -4
  58. package/dist/customize/connectors/agent-access.js +7 -10
  59. package/dist/customize/connectors/connector-identity.d.ts +12 -0
  60. package/dist/customize/connectors/connector-identity.js +15 -2
  61. package/dist/customize/connectors/connector-routes.js +2 -2
  62. package/dist/customize/connectors/connectors-page.d.ts +14 -1
  63. package/dist/customize/connectors/connectors-page.js +101 -32
  64. package/dist/customize/connectors/detail/app-page.js +1 -1
  65. package/dist/customize/connectors/detail/connector-agents.js +0 -3
  66. package/dist/customize/connectors/detail/connector-page.d.ts +1 -1
  67. package/dist/customize/connectors/detail/connector-page.js +5 -2
  68. package/dist/customize/connectors/detail/connector-policy-sets.js +1 -1
  69. package/dist/customize/connectors/detail/connector-triggers.js +2 -2
  70. package/dist/customize/connectors/use-agent-access.d.ts +7 -5
  71. package/dist/customize/connectors/use-agent-access.js +2 -6
  72. package/dist/customize/models/models-page.d.ts +7 -1
  73. package/dist/customize/models/models-page.js +2 -2
  74. package/dist/customize/project-settings/project-admin-sections.d.ts +63 -0
  75. package/dist/customize/project-settings/project-admin-sections.js +80 -0
  76. package/dist/customize/project-settings/project-settings-page.d.ts +1 -1
  77. package/dist/customize/project-settings/project-settings-page.js +4 -13
  78. package/dist/customize/project-settings/project-settings-sections.d.ts +5 -5
  79. package/dist/customize/project-settings/project-settings-sections.js +6 -20
  80. package/dist/customize/providers/provider-accordion.js +29 -17
  81. package/dist/customize/providers/provider-connect.js +1 -1
  82. package/dist/customize/providers/provider-sheet.d.ts +4 -1
  83. package/dist/customize/providers/provider-sheet.js +15 -5
  84. package/dist/customize/secrets/secrets-page.d.ts +5 -1
  85. package/dist/customize/secrets/secrets-page.js +2 -2
  86. package/dist/customize/sections/gateway-view.d.ts +10 -2
  87. package/dist/customize/sections/gateway-view.js +16 -4
  88. package/dist/customize/sections/llm-provider/chatgpt-subscription-connect.d.ts +12 -5
  89. package/dist/customize/sections/llm-provider/chatgpt-subscription-connect.js +131 -8
  90. package/dist/customize/sections/llm-provider/claude-code-step.d.ts +10 -0
  91. package/dist/customize/sections/llm-provider/claude-code-step.js +32 -0
  92. package/dist/customize/sections/llm-provider/models-tab.js +5 -1
  93. package/dist/customize/sections/view/account-secret-resources-panel.d.ts +5 -3
  94. package/dist/customize/sections/view/account-secret-resources-panel.js +122 -19
  95. package/dist/customize/sections/view/agent-editor-access-fields.d.ts +1 -1
  96. package/dist/customize/sections/view/agent-editor-access-fields.js +8 -4
  97. package/dist/customize/sections/view/agent-editor-basics-fields.d.ts +4 -1
  98. package/dist/customize/sections/view/agent-editor-basics-fields.js +33 -4
  99. package/dist/customize/sections/view/agent-editor-catalog.d.ts +2 -2
  100. package/dist/customize/sections/view/agent-editor-catalog.js +10 -12
  101. package/dist/customize/sections/view/agent-editor-primitives.d.ts +1 -1
  102. package/dist/customize/sections/view/agent-editor-primitives.js +4 -4
  103. package/dist/customize/sections/view/agent-editor.d.ts +37 -26
  104. package/dist/customize/sections/view/agent-editor.js +19 -19
  105. package/dist/customize/sections/view/grant-mode-field.d.ts +8 -20
  106. package/dist/customize/sections/view/grant-mode-field.js +31 -57
  107. package/dist/customize/sections/view/permission-editor.d.ts +3 -1
  108. package/dist/customize/sections/view/permission-editor.js +19 -10
  109. package/dist/customize/sections/view/review-view.d.ts +8 -0
  110. package/dist/customize/sections/view/review-view.js +12 -1
  111. package/dist/customize/sections/view/secret-delivery.js +1 -4
  112. package/dist/customize/sections/view/secrets-view.d.ts +7 -1
  113. package/dist/customize/sections/view/secrets-view.js +42 -6
  114. package/dist/customize/settings/rail.js +2 -8
  115. package/dist/customize/settings/settings-tabs.d.ts +2 -2
  116. package/dist/customize/settings/settings-tabs.js +17 -19
  117. package/dist/customize/settings/tabs/experimental-tab.d.ts +3 -0
  118. package/dist/customize/settings/tabs/experimental-tab.js +6 -1
  119. package/dist/customize/settings/tabs/sandbox-tab.d.ts +4 -6
  120. package/dist/customize/settings/tabs/sandbox-tab.js +9 -9
  121. package/dist/customize/shared/access-list.d.ts +39 -0
  122. package/dist/customize/shared/access-list.js +62 -0
  123. package/dist/customize/shared/agent-resource-scope.d.ts +87 -0
  124. package/dist/customize/shared/agent-resource-scope.js +123 -0
  125. package/dist/customize/shared/capability-library.d.ts +41 -0
  126. package/dist/customize/shared/capability-library.js +271 -0
  127. package/dist/customize/shared/capability-page-shell.d.ts +18 -1
  128. package/dist/customize/shared/capability-page-shell.js +21 -1
  129. package/dist/customize/shared/catalog/catalog-space-tabs.d.ts +14 -0
  130. package/dist/customize/shared/catalog/catalog-space-tabs.js +20 -0
  131. package/dist/customize/shared/customize-tab-bar.d.ts +13 -0
  132. package/dist/customize/shared/customize-tab-bar.js +95 -0
  133. package/dist/customize/shared/entity/entity-modal.d.ts +17 -1
  134. package/dist/customize/shared/entity/entity-modal.js +10 -9
  135. package/dist/customize/shared/leave-guard.d.ts +23 -0
  136. package/dist/customize/shared/leave-guard.js +87 -0
  137. package/dist/customize/shared/standalone-settings-nav.js +4 -1
  138. package/dist/customize/shared/tool-rules.d.ts +11 -0
  139. package/dist/customize/shared/tool-rules.js +29 -0
  140. package/dist/customize/skills/builtin-skill-modal.d.ts +6 -0
  141. package/dist/customize/skills/builtin-skill-modal.js +41 -0
  142. package/dist/customize/skills/skills-page.d.ts +21 -18
  143. package/dist/customize/skills/skills-page.js +16 -110
  144. package/dist/customize/triggers/runtime-triggers.d.ts +17 -0
  145. package/dist/customize/triggers/runtime-triggers.js +57 -0
  146. package/dist/customize/triggers/schedule/event-trigger-copy.js +2 -2
  147. package/dist/customize/triggers/schedule/post-to-field.js +2 -2
  148. package/dist/customize/triggers/schedule/schedule-copy.d.ts +11 -6
  149. package/dist/customize/triggers/schedule/schedule-copy.js +29 -8
  150. package/dist/customize/triggers/schedule/schedule-detail-sheet.js +7 -3
  151. package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +26 -1
  152. package/dist/customize/triggers/schedule/trigger-composer-logic.js +64 -3
  153. package/dist/customize/triggers/schedule/trigger-composer.js +57 -20
  154. package/dist/customize/triggers/schedule/trigger-edit-logic.js +18 -5
  155. package/dist/customize/triggers/schedule/trigger-filter.d.ts +10 -0
  156. package/dist/customize/triggers/schedule/trigger-filter.js +16 -0
  157. package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
  158. package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
  159. package/dist/customize/triggers/schedule/use-trigger-mutations.d.ts +1 -1
  160. package/dist/customize/triggers/schedule/use-trigger-mutations.js +1 -1
  161. package/dist/customize/triggers/schedule/when-app.d.ts +15 -0
  162. package/dist/customize/triggers/schedule/when-app.js +21 -0
  163. package/dist/customize/triggers/schedule/when-change-request.d.ts +10 -0
  164. package/dist/customize/triggers/schedule/when-change-request.js +15 -0
  165. package/dist/customize/triggers/schedule-view.d.ts +17 -3
  166. package/dist/customize/triggers/schedule-view.js +46 -16
  167. package/dist/customize/triggers/triggers-page.d.ts +3 -3
  168. package/dist/customize/triggers/triggers-page.js +2 -2
  169. package/dist/customize/use-configure-thread.d.ts +8 -2
  170. package/dist/customize/use-configure-thread.js +30 -18
  171. package/dist/files/project/components/change-request-detail-dialog.js +2 -3
  172. package/dist/files/project/components/drive-explorer.js +6 -5
  173. package/dist/files/project/explorer-source.d.ts +3 -0
  174. package/dist/files/project/upload-batch.d.ts +3 -3
  175. package/dist/files/project/upload-batch.js +7 -6
  176. package/dist/files/runtime/sandbox-explorer-source.js +3 -3
  177. package/dist/i18n/en.d.ts +1330 -53
  178. package/dist/i18n/en.js +1422 -145
  179. package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +16 -7
  180. package/dist/internal/auth/auth-primitives.d.ts +1 -3
  181. package/dist/internal/auth/auth-primitives.js +2 -2
  182. package/dist/internal/billing/session-cost-format.d.ts +1 -0
  183. package/dist/internal/billing/session-cost-format.js +11 -0
  184. package/dist/internal/components/agent-mark.d.ts +12 -1
  185. package/dist/internal/components/agent-mark.js +34 -11
  186. package/dist/internal/components/nav-rail.d.ts +22 -0
  187. package/dist/internal/components/nav-rail.js +16 -0
  188. package/dist/internal/components/repository-disconnected.js +2 -2
  189. package/dist/internal/goals/goal-meta.d.ts +15 -1
  190. package/dist/internal/goals/goal-meta.js +42 -2
  191. package/dist/internal/hooks/projects/use-agent-config.d.ts +11 -7
  192. package/dist/internal/hooks/projects/use-agent-config.js +28 -11
  193. package/dist/internal/hooks/use-slash-focus.d.ts +7 -1
  194. package/dist/internal/hooks/use-slash-focus.js +9 -3
  195. package/dist/internal/layout/project-capability-nav.d.ts +24 -0
  196. package/dist/internal/layout/project-capability-nav.js +86 -0
  197. package/dist/internal/layout/project-page-header.d.ts +1 -1
  198. package/dist/internal/layout/project-page-header.js +1 -1
  199. package/dist/internal/layout/project-settings-nav.d.ts +3 -2
  200. package/dist/internal/layout/project-settings-nav.js +5 -3
  201. package/dist/internal/lib/browser-noise/rules/old-browsers.js +1 -1
  202. package/dist/internal/lib/capability-tab-routes.d.ts +34 -3
  203. package/dist/internal/lib/capability-tab-routes.js +76 -8
  204. package/dist/internal/lib/manifest-health.d.ts +10 -0
  205. package/dist/internal/lib/manifest-health.js +20 -0
  206. package/dist/internal/lib/pixel-mark.d.ts +4 -1
  207. package/dist/internal/lib/pixel-mark.js +33 -6
  208. package/dist/internal/lib/project-actions.d.ts +1 -1
  209. package/dist/internal/lib/project-actions.js +0 -4
  210. package/dist/internal/lib/provider-branding.js +2 -0
  211. package/dist/internal/lib/space-scope.d.ts +29 -0
  212. package/dist/internal/lib/space-scope.js +28 -0
  213. package/dist/internal/lib/use-project-feature-flags.js +3 -3
  214. package/dist/internal/lib/web-notifications.d.ts +74 -8
  215. package/dist/internal/lib/web-notifications.js +243 -117
  216. package/dist/internal/notifications/notification-rows.d.ts +14 -7
  217. package/dist/internal/notifications/notification-rows.js +21 -14
  218. package/dist/internal/notifications/session-toast-cards.d.ts +2 -2
  219. package/dist/internal/reminders/reminder-format.d.ts +6 -2
  220. package/dist/internal/reminders/reminder-format.js +7 -1
  221. package/dist/internal/stores/active-space-store.d.ts +35 -0
  222. package/dist/internal/stores/active-space-store.js +29 -0
  223. package/dist/internal/stores/kortix-computer-store.js +13 -4
  224. package/dist/internal/stores/pinned-agents-store.d.ts +26 -0
  225. package/dist/internal/stores/pinned-agents-store.js +20 -0
  226. package/dist/internal/stores/session-panel-memory-store.js +3 -0
  227. package/dist/internal/stores/turn-attention-store.d.ts +5 -4
  228. package/dist/lib/routes.d.ts +16 -1
  229. package/dist/lib/routes.js +15 -3
  230. package/dist/markdown/doc-editor/doc-embed.d.ts +31 -0
  231. package/dist/markdown/doc-editor/doc-embed.js +168 -0
  232. package/dist/markdown/doc-editor/doc-extensions.d.ts +26 -0
  233. package/dist/markdown/doc-editor/doc-extensions.js +149 -0
  234. package/dist/markdown/doc-editor/doc-menus.d.ts +9 -0
  235. package/dist/markdown/doc-editor/doc-menus.js +56 -0
  236. package/dist/markdown/doc-editor/markdown.d.ts +12 -0
  237. package/dist/markdown/doc-editor/markdown.js +140 -0
  238. package/dist/markdown/genui/components/inline.d.ts +1 -1
  239. package/dist/primitives/badge.d.ts +1 -1
  240. package/dist/primitives/button.d.ts +1 -1
  241. package/dist/primitives/pixel-kortix-mark.d.ts +5 -4
  242. package/dist/primitives/pixel-kortix-mark.js +5 -15
  243. package/dist/primitives/tag.d.ts +1 -1
  244. package/dist/primitives/textarea.js +14 -0
  245. package/dist/primitives/toast.d.ts +2 -0
  246. package/dist/primitives/toast.js +4 -2
  247. package/dist/providers/ui-provider.d.ts +16 -0
  248. package/dist/session/actions/session-label.d.ts +1 -1
  249. package/dist/session/actions/session-label.js +3 -3
  250. package/dist/session/agents/agent-model.d.ts +92 -0
  251. package/dist/session/agents/agent-model.js +123 -0
  252. package/dist/session/agents/agent-state-mark.d.ts +10 -0
  253. package/dist/session/agents/agent-state-mark.js +22 -0
  254. package/dist/session/agents/agent-strip.d.ts +58 -0
  255. package/dist/session/agents/agent-strip.js +259 -0
  256. package/dist/session/agents/held-messages.d.ts +33 -0
  257. package/dist/session/agents/held-messages.js +50 -0
  258. package/dist/session/agents/legacy-subagent-chat.d.ts +11 -0
  259. package/dist/session/agents/legacy-subagent-chat.js +19 -0
  260. package/dist/session/agents/session-peek.d.ts +20 -0
  261. package/dist/session/agents/session-peek.js +67 -0
  262. package/dist/session/agents/session-prompt.d.ts +13 -0
  263. package/dist/session/agents/session-prompt.js +18 -0
  264. package/dist/session/agents/steer-session.d.ts +13 -0
  265. package/dist/session/agents/steer-session.js +29 -0
  266. package/dist/session/agents/subagent-dialog-content.d.ts +11 -0
  267. package/dist/session/agents/subagent-dialog-content.js +115 -0
  268. package/dist/session/agents/subagent-view.d.ts +8 -0
  269. package/dist/session/agents/subagent-view.js +18 -0
  270. package/dist/session/agents/tasks-panel.d.ts +13 -0
  271. package/dist/session/agents/tasks-panel.js +41 -0
  272. package/dist/session/agents/workflow-run-controls.d.ts +43 -0
  273. package/dist/session/agents/workflow-run-controls.js +141 -0
  274. package/dist/session/composer/ComposerCard.d.ts +1 -1
  275. package/dist/session/composer/ComposerCard.js +3 -3
  276. package/dist/session/composer/agent-selector.js +13 -19
  277. package/dist/session/composer/composer-underbar.d.ts +3 -1
  278. package/dist/session/composer/composer-underbar.js +2 -2
  279. package/dist/session/composer/composer.d.ts +5 -0
  280. package/dist/session/composer/composer.js +16 -10
  281. package/dist/session/composer/editor/composer-editor.js +19 -8
  282. package/dist/session/composer/editor/ultracode.d.ts +34 -0
  283. package/dist/session/composer/editor/ultracode.js +127 -0
  284. package/dist/session/composer/send-blockers.d.ts +1 -11
  285. package/dist/session/composer/send-blockers.js +1 -11
  286. package/dist/session/composer/session-composer-readiness.d.ts +1 -28
  287. package/dist/session/composer/session-composer-readiness.js +5 -16
  288. package/dist/session/header/reminder-parts.d.ts +1 -1
  289. package/dist/session/header/session-site-header.js +6 -3
  290. package/dist/session/header/subagent-hover-card.d.ts +0 -2
  291. package/dist/session/header/subagent-hover-card.js +1 -4
  292. package/dist/session/models/claude-connection-slot.d.ts +11 -0
  293. package/dist/session/models/claude-connection-slot.js +30 -0
  294. package/dist/session/models/model-availability.d.ts +3 -1
  295. package/dist/session/models/model-availability.js +3 -0
  296. package/dist/session/models/model-selector.js +11 -12
  297. package/dist/session/models/model-tags.d.ts +9 -0
  298. package/dist/session/models/model-tags.js +8 -0
  299. package/dist/session/panel/easy/easy-panel.js +1 -1
  300. package/dist/session/panel/easy/step-icon.js +5 -1
  301. package/dist/session/panel/mobile-tool-drawer.js +1 -1
  302. package/dist/session/panel/session-action-panel-column.js +1 -1
  303. package/dist/session/panel/session-desktop.js +41 -14
  304. package/dist/session/panel/session-panel-provider.d.ts +1 -1
  305. package/dist/session/panel/session-panel-provider.js +7 -11
  306. package/dist/session/prompts/question-prompt.js +3 -1
  307. package/dist/session/status/session-error-banner.js +4 -1
  308. package/dist/session/thread/session-chat.js +286 -296
  309. package/dist/session/thread/session-context-modal.js +29 -10
  310. package/dist/session/thread/session-context-spawned-sessions.d.ts +13 -0
  311. package/dist/session/thread/session-context-spawned-sessions.js +44 -0
  312. package/dist/session/thread/session-context-sub-sessions.js +3 -8
  313. package/dist/session/thread/transcript.d.ts +3 -0
  314. package/dist/session/thread/transcript.js +32 -8
  315. package/dist/session/tool/shared/full-view-action.d.ts +29 -0
  316. package/dist/session/tool/shared/full-view-action.js +43 -0
  317. package/dist/session/tool/tool-part-renderer.js +10 -2
  318. package/dist/session/tool/tools/agent-message-tool.js +2 -2
  319. package/dist/session/tool/tools/agent-spawn-tool.js +2 -2
  320. package/dist/session/tool/tools/agent-status-tool.js +2 -2
  321. package/dist/session/tool/tools/kortix-action-tool.d.ts +2 -0
  322. package/dist/session/tool/tools/kortix-action-tool.js +148 -0
  323. package/dist/session/tool/tools/kortix-tool-card.d.ts +83 -0
  324. package/dist/session/tool/tools/kortix-tool-card.js +186 -0
  325. package/dist/session/tool/tools/multi-agent-tool-bodies.d.ts +11 -0
  326. package/dist/session/tool/tools/multi-agent-tool-bodies.js +141 -0
  327. package/dist/session/tool/tools/multi-agent-tool-data.d.ts +63 -0
  328. package/dist/session/tool/tools/multi-agent-tool-data.js +118 -0
  329. package/dist/session/tool/tools/multi-agent-tools.d.ts +9 -0
  330. package/dist/session/tool/tools/multi-agent-tools.js +38 -0
  331. package/dist/session/tool/tools/question-tool.js +1 -1
  332. package/dist/session/tool/tools/register.d.ts +3 -0
  333. package/dist/session/tool/tools/register.js +3 -0
  334. package/dist/session/tool/tools/session-spawn-tool.js +2 -2
  335. package/dist/session/tool/tools/task-tool.d.ts +1 -1
  336. package/dist/session/tool/tools/task-tool.js +29 -41
  337. package/dist/session/tool/tools/workflow-progress.d.ts +34 -0
  338. package/dist/session/tool/tools/workflow-progress.js +186 -0
  339. package/dist/session/tool/tools/workflow-run.d.ts +128 -0
  340. package/dist/session/tool/tools/workflow-run.js +251 -0
  341. package/dist/session/tool/tools/workflow-tool.d.ts +9 -0
  342. package/dist/session/tool/tools/workflow-tool.js +253 -0
  343. package/dist/session/turn/notice-batch-group.d.ts +12 -0
  344. package/dist/session/turn/notice-batch-group.js +17 -0
  345. package/dist/session/turn/peer-message-row.d.ts +14 -0
  346. package/dist/session/turn/peer-message-row.js +57 -0
  347. package/dist/session/turn/subagent-notice-row.d.ts +4 -0
  348. package/dist/session/turn/subagent-notice-row.js +50 -0
  349. package/dist/session/turn/subagent-notice.d.ts +58 -0
  350. package/dist/session/turn/subagent-notice.js +111 -0
  351. package/dist/session/turn/user-message.js +24 -5
  352. package/dist/styles/tokens.css +2 -0
  353. package/dist/styles.css +1 -1
  354. package/dist/terminal/session-terminal-connect-bar.js +1 -1
  355. package/dist/workspace/admin/project-admin-dashboard.d.ts +53 -0
  356. package/dist/workspace/admin/project-admin-dashboard.js +252 -0
  357. package/dist/workspace/admin/project-admin-nav.d.ts +20 -0
  358. package/dist/workspace/admin/project-admin-nav.js +41 -0
  359. package/dist/workspace/home/welcome-body.js +25 -3
  360. package/dist/workspace/index.d.ts +6 -2
  361. package/dist/workspace/index.js +12 -2
  362. package/dist/workspace/layout/new-session-create.js +3 -3
  363. package/dist/workspace/layout/project-home.js +3 -3
  364. package/dist/workspace/memory/memory-labels.js +5 -0
  365. package/dist/workspace/repository-disconnected.js +2 -2
  366. package/dist/workspace/sessions/board-dispatch.d.ts +52 -0
  367. package/dist/workspace/sessions/board-dispatch.js +110 -0
  368. package/dist/workspace/sessions/board-grouping.d.ts +63 -0
  369. package/dist/workspace/sessions/board-grouping.js +141 -0
  370. package/dist/workspace/sessions/board-peek.d.ts +15 -0
  371. package/dist/workspace/sessions/board-peek.js +54 -0
  372. package/dist/workspace/sessions/board-state-mark.d.ts +15 -0
  373. package/dist/workspace/sessions/board-state-mark.js +24 -0
  374. package/dist/workspace/sessions/project-sessions-view.js +42 -31
  375. package/dist/workspace/sessions/sessions-board.d.ts +12 -0
  376. package/dist/workspace/sessions/sessions-board.js +214 -0
  377. package/dist/workspace/sidebar/footer/project-manifest-issues-alert.d.ts +46 -0
  378. package/dist/workspace/sidebar/footer/project-manifest-issues-alert.js +85 -0
  379. package/dist/workspace/sidebar/footer/sidebar-alert.js +1 -1
  380. package/dist/workspace/sidebar/new-agent-modal-provider.d.ts +12 -0
  381. package/dist/workspace/sidebar/new-agent-modal-provider.js +19 -0
  382. package/dist/workspace/sidebar/project-nav-items.d.ts +3 -1
  383. package/dist/workspace/sidebar/project-nav-items.js +53 -5
  384. package/dist/workspace/sidebar/project-session-list.js +35 -12
  385. package/dist/workspace/sidebar/project-sidebar.js +6 -3
  386. package/dist/workspace/sidebar/session-filter-menu.js +2 -1
  387. package/dist/workspace/space/space-blocks.d.ts +25 -0
  388. package/dist/workspace/space/space-blocks.js +124 -0
  389. package/dist/workspace/space/space-filter-tabs.d.ts +17 -0
  390. package/dist/workspace/space/space-filter-tabs.js +31 -0
  391. package/dist/workspace/space/space-page.d.ts +24 -0
  392. package/dist/workspace/space/space-page.js +157 -0
  393. package/dist/workspace/space/space-room.d.ts +20 -0
  394. package/dist/workspace/space/space-room.js +27 -0
  395. package/dist/workspace/space/space-tab-menu.d.ts +14 -0
  396. package/dist/workspace/space/space-tab-menu.js +127 -0
  397. package/dist/workspace/space/space-tab-panels.d.ts +9 -0
  398. package/dist/workspace/space/space-tab-panels.js +203 -0
  399. package/dist/workspace/space/space-templates.d.ts +34 -0
  400. package/dist/workspace/space/space-templates.js +71 -0
  401. package/dist/workspace/space/use-space-filter.d.ts +10 -0
  402. package/dist/workspace/space/use-space-filter.js +40 -0
  403. package/dist/workspace/space/use-space-manifest.d.ts +8 -0
  404. package/dist/workspace/space/use-space-manifest.js +27 -0
  405. package/dist/workspace/spaces/space-timeline.js +2 -2
  406. package/package.json +56 -53
  407. package/skills/kortix-ui/SKILL.md +1 -1
  408. package/skills/kortix-ui/references/custom-dashboard.md +10 -4
  409. package/skills/kortix-ui/references/modules.md +10 -8
  410. package/dist/_vendor/shared/meta-agent.d.ts +0 -7
  411. package/dist/customize/agents/agent-grant-pages.d.ts +0 -37
  412. package/dist/customize/agents/agent-grant-pages.js +0 -226
  413. package/dist/customize/agents/agent-triggers-section.d.ts +0 -17
  414. package/dist/customize/agents/agent-triggers-section.js +0 -109
  415. package/dist/customize/migrate-to-v2/index.d.ts +0 -5
  416. package/dist/customize/migrate-to-v2/index.js +0 -5
  417. package/dist/customize/migrate-to-v2/migration-prompt.d.ts +0 -16
  418. package/dist/customize/migrate-to-v2/migration-prompt.js +0 -59
  419. package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +0 -30
  420. package/dist/customize/migrate-to-v2/upgrade-defs.js +0 -43
  421. package/dist/customize/migrate-to-v2/upgrade-view.d.ts +0 -32
  422. package/dist/customize/migrate-to-v2/upgrade-view.js +0 -152
  423. package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +0 -18
  424. package/dist/customize/migrate-to-v2/use-run-upgrade.js +0 -16
  425. package/dist/customize/shared/capability-tabs.d.ts +0 -3
  426. package/dist/customize/shared/capability-tabs.js +0 -137
  427. package/dist/customize/skills/skill-scope.d.ts +0 -14
  428. package/dist/customize/skills/skill-scope.js +0 -18
  429. package/dist/internal/lib/manifest-version.d.ts +0 -21
  430. package/dist/internal/lib/manifest-version.js +0 -55
  431. package/dist/session/composer/hooks/use-composer-escape-stop.d.ts +0 -6
  432. package/dist/session/composer/hooks/use-composer-escape-stop.js +0 -28
  433. package/dist/session/thread/sub-session-modal-content.d.ts +0 -8
  434. package/dist/session/thread/sub-session-modal-content.js +0 -23
  435. package/dist/session/thread/sub-session-modal.d.ts +0 -2
  436. package/dist/session/thread/sub-session-modal.js +0 -14
  437. package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.d.ts +0 -13
  438. package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +0 -48
@@ -0,0 +1,94 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * New agent. Three ways to start, the agent-first one first: describe the
5
+ * work to My Kortix (it drafts the agent with only the access the work
6
+ * needs), start blank, or copy another agent. Each one opens a session of My
7
+ * Kortix that writes `agents.<name>` and opens a change request: there is no
8
+ * write path that skips review, so the modal never claims one.
9
+ *
10
+ * From `lg` the modal has two panes: the form, and a live preview of the
11
+ * agent it makes (its mark, name, `agents.<name>` key, description, and what
12
+ * it starts with). Below `lg` it is a bottom sheet capped at 90% of the
13
+ * window, form only. Its body scrolls and its footer stays pinned, so Create
14
+ * agent is reachable at 720×480.
15
+ */
16
+ import { slugifySlug } from '../../_vendor/kortix-shared.js';
17
+ import { isMyKortixAgentName } from '../../_vendor/kortix-shared.js';
18
+ import { useState } from 'react';
19
+ import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
20
+ import { AgentMark, agentDisplayName } from '../../internal/components/agent-mark.js';
21
+ import { cn } from '../../internal/lib/utils.js';
22
+ import { Button } from '../../primitives/button.js';
23
+ import { Input } from '../../primitives/input.js';
24
+ import { Label } from '../../primitives/label.js';
25
+ import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalTitle, } from '../../primitives/modal.js';
26
+ import { RadioGroup, RadioGroupItem } from '../../primitives/radio-group.js';
27
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../primitives/select.js';
28
+ import { StatusDot } from '../../primitives/status.js';
29
+ import { Textarea } from '../../primitives/textarea.js';
30
+ import { useConfigureThread } from '../use-configure-thread.js';
31
+ /** A phone's footer clears the home indicator: the device inset, at least the footer's own py-3. */
32
+ const FOOTER_SAFE_AREA = 'max-lg:pb-[max(0.75rem,env(safe-area-inset-bottom))]'; // audit:allow device safe-area inset, not a spacing step
33
+ /** The request My Kortix receives. English, like every configure prompt. */
34
+ export function createAgentPrompt(input) {
35
+ const review = 'Then open a change request so I can review and merge it.';
36
+ const desc = input.description.trim();
37
+ if (input.start === 'duplicate' && input.from) {
38
+ return (`Create a new agent named "${input.name}" in kortix.yaml as a copy of the "${input.from.name}" agent ` +
39
+ `(its config lives at \`${input.from.path}\`)${desc ? `, with the description "${desc}"` : ''}. ${review}`);
40
+ }
41
+ if (input.start === 'blank') {
42
+ return (`Create a new agent named "${input.name}" in kortix.yaml${desc ? ` with the description "${desc}"` : ''}, ` +
43
+ `no grants (write \`tools: none\`) and empty instructions. ${review}`);
44
+ }
45
+ return (`Create a new agent named "${input.name}" in kortix.yaml. What it does: ${desc || 'ask me.'} ` +
46
+ `Write its instructions and give it only the tools, skills, connectors, secrets and permissions this work needs. ` +
47
+ `Always write its \`tools:\` key: a list of the tools it needs, or \`all\`. ${review}`);
48
+ }
49
+ /** One fact of the preview: a label left, its value right. */
50
+ function PreviewFact({ label, children }) {
51
+ return (_jsxs("div", { className: "flex items-center justify-between gap-3 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: label }), _jsx("span", { className: "text-foreground flex min-w-0 items-center gap-1.5 truncate", children: children })] }));
52
+ }
53
+ export function CreateAgentModal({ open, onOpenChange, projectId, config, }) {
54
+ const t = useI18nTranslations('agentEditor.tabs');
55
+ const tPage = useI18nTranslations('agentEditor.page');
56
+ const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
57
+ const configure = useConfigureThread(projectId);
58
+ const agents = (config?.agents ?? []).filter((a) => !a.platform);
59
+ const [start, setStart] = useState('describe');
60
+ const [name, setName] = useState('');
61
+ const [description, setDescription] = useState('');
62
+ const [from, setFrom] = useState('');
63
+ const slug = name.trim() ? slugifySlug(name, '') : '';
64
+ // Every declared agent and the built-in ones: a new agent can never take a
65
+ // platform agent's key. `agents` (the Duplicate sources) leaves them out.
66
+ const taken = (config?.agents ?? []).some((a) => a.name === slug) || isMyKortixAgentName(slug);
67
+ const source = agents.find((a) => a.name === from);
68
+ const ready = slug.length > 0 && !taken && (start !== 'duplicate' || source !== undefined);
69
+ const submit = () => {
70
+ if (!ready || configure.pending)
71
+ return;
72
+ configure.start(createAgentPrompt({
73
+ start,
74
+ name: slug,
75
+ description,
76
+ from: source ? { name: source.name, path: source.path } : undefined,
77
+ }));
78
+ };
79
+ const choices = [
80
+ { key: 'describe', title: t('startDescribe'), help: t('startDescribeHelp') },
81
+ { key: 'blank', title: t('startBlank'), help: t('startBlankHelp') },
82
+ { key: 'duplicate', title: t('startDuplicate'), help: t('startDuplicateHelp') },
83
+ ];
84
+ // What the new agent starts with, per way to start.
85
+ const startsWith = {
86
+ describe: { instructions: t('previewDrafted'), access: t('previewAccessScoped') },
87
+ blank: { instructions: t('previewEmpty'), access: t('previewAccessNone') },
88
+ duplicate: { instructions: t('previewCopied'), access: t('previewCopied') },
89
+ }[start];
90
+ return (_jsx(Modal, { open: open, onOpenChange: onOpenChange, children: _jsx(ModalContent, { className: "flex flex-col space-y-0 overflow-hidden lg:max-w-4xl", children: _jsxs("form", { className: "flex min-h-0 flex-1 flex-col", onSubmit: (event) => {
91
+ event.preventDefault();
92
+ submit();
93
+ }, children: [_jsxs("div", { className: "flex min-h-0 flex-1", children: [_jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [_jsx(ModalHeader, { className: "shrink-0 pb-4", children: _jsx(ModalTitle, { children: t('newAgent') }) }), _jsxs(ModalBody, { className: "min-h-0 overflow-y-auto", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "new-agent-name", children: t('name') }), _jsx(Input, { id: "new-agent-name", value: name, placeholder: t('namePlaceholder'), onChange: (e) => setName(e.target.value), autoFocus: true }), taken ? (_jsxs("p", { className: "text-foreground flex items-center gap-1.5 text-xs", children: [_jsx(StatusDot, { tone: "destructive" }), t('nameTaken')] })) : null] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("p", { className: "text-foreground text-sm font-medium", children: t('howToStart') }), _jsx(RadioGroup, { "aria-label": t('howToStart'), value: start, onValueChange: (next) => setStart(next), className: "gap-1", children: choices.map((choice) => (_jsx(RadioGroupItem, { value: choice.key, label: choice.title, description: choice.help, size: "lg" }, choice.key))) })] }), start === 'duplicate' ? (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: t('copyOf') }), _jsxs(Select, { value: from, onValueChange: setFrom, children: [_jsx(SelectTrigger, { "aria-label": t('copyOf'), className: "w-full", children: _jsx(SelectValue, { placeholder: t('pickAgent') }) }), _jsx(SelectContent, { children: agents.map((agent) => (_jsx(SelectItem, { value: agent.name, children: _jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx(AgentMark, { slug: agent.name }), _jsx("span", { className: "truncate", children: agentDisplayName(agent.name) })] }) }, agent.name))) })] })] })) : null, _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "new-agent-description", children: start === 'describe' ? t('whatItDoes') : tI18nComplete.raw('text526e0087cc3f') }), _jsx(Textarea, { id: "new-agent-description", value: description, placeholder: start === 'describe' ? t('whatItDoesPlaceholder') : t('descriptionPlaceholderShort'), onChange: (e) => setDescription(e.target.value), minHeight: start === 'describe' ? 90 : 52 })] })] })] }), _jsxs("aside", { "aria-label": t('preview'), className: "bg-background hidden w-96 shrink-0 flex-col gap-4 overflow-y-auto border-l p-5 lg:flex", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t('preview') }), _jsxs("div", { className: "space-y-1", children: [_jsx("div", { className: "pb-3", children: _jsx(AgentMark, { slug: slug || 'new-agent', size: 42 }) }), _jsx("p", { className: cn('truncate text-lg font-medium', slug ? 'text-foreground' : 'text-muted-foreground'), children: agentDisplayName(slug || t('namePlaceholder')) }), _jsx("p", { className: "text-muted-foreground truncate font-mono text-xs", children: `agents.${slug || t('namePlaceholder')}` }), description.trim() ? (_jsx("p", { className: "text-foreground line-clamp-3 pt-1 text-sm text-pretty", children: description.trim() })) : null] }), _jsxs("div", { className: "space-y-2.5 border-t pt-4", children: [start === 'duplicate' && source ? (_jsxs(PreviewFact, { label: t('copyOf'), children: [_jsx(AgentMark, { slug: source.name }), _jsx("span", { className: "truncate", children: agentDisplayName(source.name) })] })) : null, _jsx(PreviewFact, { label: tPage('instructions'), children: startsWith.instructions }), _jsx(PreviewFact, { label: t('tabAccess'), children: startsWith.access })] })] })] }), _jsxs(ModalFooter, { className: cn('shrink-0 border-t py-3', FOOTER_SAFE_AREA), children: [_jsx("p", { className: "text-muted-foreground mr-auto hidden text-xs sm:block", children: t('composerNote') }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full sm:w-auto", onClick: () => onOpenChange(false), children: tI18nComplete.raw('text19766ed6ccb2') }), _jsx(Button, { type: "submit", size: "sm", className: "w-full sm:w-auto", disabled: !ready || configure.pending, "aria-busy": configure.pending || undefined, children: t('createAgent') })] })] }) }) }));
94
+ }
@@ -1,7 +1,7 @@
1
1
  import type { AgentGrantSet } from '@kortix/sdk';
2
2
  /**
3
3
  * Which agents can use which connector, and with which rule set, read from
4
- * the root kortix.yaml (v2/v3): `agents.<a>.connectors` is the grant and
4
+ * the root kortix.yaml: `agents.<a>.connectors` is the grant and
5
5
  * `agents.<a>.policy_sets.<slug>` the set. The connector page's Agents tab and
6
6
  * the Rules matrix both read this, and both write through `setAgentScope`.
7
7
  *
@@ -14,12 +14,12 @@ export interface AgentConnectorAccess {
14
14
  policySet: string | null;
15
15
  }
16
16
  export interface AgentGrants {
17
- /** `all`, or the granted slugs. An absent grant is none (v2 denies by default). */
17
+ /** `all`, or the granted slugs. An absent grant is none (deny by default). */
18
18
  connectors: 'all' | string[];
19
19
  policySets: Record<string, string>;
20
20
  }
21
- /** Every declared agent's connector grant and sets, by agent name. Null when the manifest is not v2/v3 YAML. */
22
- export declare function manifestAgentGrants(manifestRaw: string | null | undefined): Record<string, AgentGrants> | null;
21
+ /** Every declared agent's connector grant and sets, by agent name. Empty when there is no manifest or it does not parse. */
22
+ export declare function manifestAgentGrants(manifestRaw: string | null | undefined): Record<string, AgentGrants>;
23
23
  export declare function agentConnectorAccess(grants: AgentGrants | undefined, slug: string): AgentConnectorAccess;
24
24
  /**
25
25
  * The agent's connector grant after giving or taking one connector. Taking one
@@ -1,19 +1,16 @@
1
1
  import { parseManifestText } from '../../_vendor/kortix-shared.js';
2
- /** Every declared agent's connector grant and sets, by agent name. Null when the manifest is not v2/v3 YAML. */
2
+ /** Every declared agent's connector grant and sets, by agent name. Empty when there is no manifest or it does not parse. */
3
3
  export function manifestAgentGrants(manifestRaw) {
4
4
  if (!manifestRaw)
5
- return null;
5
+ return {};
6
6
  let manifest;
7
7
  try {
8
- manifest = parseManifestText(manifestRaw, 'yaml');
8
+ manifest = parseManifestText(manifestRaw);
9
9
  }
10
10
  catch {
11
- return null;
11
+ return {};
12
12
  }
13
- const version = Number(manifest.kortix_version);
14
13
  const agents = manifest.agents;
15
- if (!(version >= 2))
16
- return null;
17
14
  if (!agents || typeof agents !== 'object' || Array.isArray(agents))
18
15
  return {};
19
16
  const out = Object.create(null);
@@ -53,12 +50,12 @@ export function withConnectorGrant(grants, slug, on, allSlugs) {
53
50
  }
54
51
  /** Each connector's rule sets (`connectors[].policy_sets`) with their agent count, by slug. */
55
52
  export function connectorRuleSetUsage(manifestRaw) {
56
- const grants = manifestAgentGrants(manifestRaw);
57
- if (!grants || !manifestRaw)
53
+ if (!manifestRaw)
58
54
  return {};
55
+ const grants = manifestAgentGrants(manifestRaw);
59
56
  let manifest;
60
57
  try {
61
- manifest = parseManifestText(manifestRaw, 'yaml');
58
+ manifest = parseManifestText(manifestRaw);
62
59
  }
63
60
  catch {
64
61
  return {};
@@ -1,4 +1,5 @@
1
1
  import type { AdminConnector } from '@kortix/sdk';
2
+ import type { ConnectorLogoSource } from '../../internal/connector-logo/connector-logo-source.js';
2
3
  /**
3
4
  * How a connector presents its status — the connected mark and the status
4
5
  * pill. Its logo is `ConnectorLogo` (`connector-logo.tsx`), shared by every
@@ -31,3 +32,14 @@ export declare function ConnectorStatusBadge({ connector, accountCount, }: {
31
32
  connector: AdminConnector;
32
33
  accountCount?: number;
33
34
  }): import("react").JSX.Element | null;
35
+ /**
36
+ * A project connector's logo with its state on it, the way a Slack or Teams
37
+ * app tile shows one: a dot on the bottom-right corner (green Connected,
38
+ * orange Needs account, red Error). The word is for screen readers; the dot
39
+ * carries it on screen.
40
+ */
41
+ export declare function ConnectorStatusLogo({ connector, source, accountCount, }: {
42
+ connector: AdminConnector;
43
+ source: ConnectorLogoSource;
44
+ accountCount?: number;
45
+ }): import("react").JSX.Element;
@@ -1,7 +1,9 @@
1
1
  'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { CheckIcon, } from '@phosphor-icons/react';
4
- import { connectorStatusTone } from './detail/connector-status.js';
4
+ import { useTranslations } from '../../i18n/index.js';
5
+ import { ConnectorLogo } from '../../internal/connector-logo/connector-logo.js';
6
+ import { STATUS_DOT, STATUS_WORD, connectorStatusTone } from './detail/connector-status.js';
5
7
  import { ConnectorStatusBadge as ToneBadge } from './detail/status-badge.js';
6
8
  import { cn } from '../../internal/lib/utils.js';
7
9
  /**
@@ -36,3 +38,14 @@ export function ConnectorStatusBadge({ connector, accountCount, }) {
36
38
  const tone = connectorStatusTone(connector, accountCount);
37
39
  return tone === 'connected' ? null : _jsx(ToneBadge, { tone: tone });
38
40
  }
41
+ /**
42
+ * A project connector's logo with its state on it, the way a Slack or Teams
43
+ * app tile shows one: a dot on the bottom-right corner (green Connected,
44
+ * orange Needs account, red Error). The word is for screen readers; the dot
45
+ * carries it on screen.
46
+ */
47
+ export function ConnectorStatusLogo({ connector, source, accountCount, }) {
48
+ const t = useTranslations('connectorPages');
49
+ const tone = connectorStatusTone(connector, accountCount);
50
+ return (_jsxs("span", { className: "relative flex shrink-0", children: [_jsx(ConnectorLogo, { source: source, size: "lg" }), _jsx("span", { "aria-hidden": true, className: "bg-background absolute -right-1 -bottom-1 flex size-3 items-center justify-center rounded-full", children: _jsx("span", { className: cn('size-2 rounded-full', STATUS_DOT[tone]) }) }), _jsx("span", { className: "sr-only", children: t(STATUS_WORD[tone]) })] }));
51
+ }
@@ -1,4 +1,4 @@
1
- import { customizePath } from '../../lib/routes.js';
1
+ import { adminPath } from '../../lib/routes.js';
2
2
  /**
3
3
  * The app segment of a connector reached without an app: the Connected tab, a
4
4
  * custom connector, a computer. Its back link goes to the Connected tab.
@@ -7,7 +7,7 @@ export const CONNECTED_APP_SEGMENT = 'connected';
7
7
  /** The id of the native Computer entry: it has its own page (`ComputerAppPage`). */
8
8
  export const COMPUTER_APP_ID = 'native:computer';
9
9
  function base(projectId) {
10
- return customizePath(encodeURIComponent(projectId), 'connectors');
10
+ return adminPath(encodeURIComponent(projectId), 'connectors');
11
11
  }
12
12
  function withQuery(path, params) {
13
13
  const query = params.toString();
@@ -1,3 +1,5 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type AgentGrant, type ResourceScope } from '../shared/agent-resource-scope.js';
1
3
  /**
2
4
  * /projects/[id]/connectors — the standalone Connectors catalogue.
3
5
  *
@@ -35,6 +37,17 @@
35
37
  * `legacyDetailRedirect` forwards it, so an OAuth grant that started before
36
38
  * the change still lands on the right connector.
37
39
  */
38
- export declare function ConnectorsPage({ projectId }: {
40
+ export declare function ConnectorsPage({ projectId, surface, grant, agentPanel, rowControl, }: {
39
41
  projectId: string;
42
+ /** `global` (default) is the project catalogue; `agent` scopes the same page
43
+ * to one agent and turns each connector card into a grant control. */
44
+ surface?: ResourceScope;
45
+ /** Required in `agent` scope: the agent's `connectors` grant, driven by the
46
+ * page's draft. Ignored in `global` scope. */
47
+ grant?: AgentGrant;
48
+ /** Agent scope only: agent settings that belong with its connectors (the
49
+ * per-connector policy sets), shown above the catalogue. */
50
+ agentPanel?: ReactNode;
51
+ /** Agent scope only: a granted connector's own rule control (its policy-set picker), in its row. */
52
+ rowControl?: (slug: string) => ReactNode | undefined;
40
53
  }): import("react").JSX.Element;
@@ -5,7 +5,7 @@ import { newConfigPrompt, useConfigureThread, } from '../use-configure-thread.js
5
5
  import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
6
6
  import { getProjectDetail, listConnectors } from '@kortix/sdk';
7
7
  import { contract, FRESHNESS, qk, useProjectAccountId } from '@kortix/sdk/react';
8
- import { CaretDownIcon, MagnifyingGlassIcon, PlugIcon, PlugsConnectedIcon } from '@phosphor-icons/react';
8
+ import { CaretDownIcon, MagnifyingGlassIcon, PlugsConnectedIcon, ShieldIcon } from '@phosphor-icons/react';
9
9
  import { useQuery, useQueryClient } from '@tanstack/react-query';
10
10
  import { lazyClient } from '../../lib/lazy-client.js';
11
11
  import { useUiPathname, useUiRouter, useUiSearchParams, useUiShallowNavigate, } from '../../providers/ui-provider.js';
@@ -23,21 +23,26 @@ import { Skeleton } from '../../primitives/skeleton.js';
23
23
  import { SplitSheet, SplitSheetBody, SplitSheetContent, SplitSheetDescription, SplitSheetHeader, SplitSheetMain, SplitSheetTitle, } from '../../primitives/split-sheet.js';
24
24
  import { Tabs, TabsList, TabsTrigger } from '../../primitives/tabs.js';
25
25
  import { EmptyState } from '../../primitives/empty-state.js';
26
- import { connectorConnectionQueryKeys, connectorSetupStatus, } from '../sections/connector-connection-form.js';
26
+ import { connectorConnectionQueryKeys, } from '../sections/connector-connection-form.js';
27
27
  import { PROJECT_ACTIONS } from '../../internal/lib/project-actions.js';
28
28
  import { useProjectCan } from '../../internal/lib/use-project-can.js';
29
- import { ConnectorConnectedMark, ConnectorStatusBadge } from './connector-identity.js';
29
+ import { ConnectorStatusBadge, ConnectorStatusLogo } from './connector-identity.js';
30
+ import { CatalogCard } from '../shared/catalog/catalog-card.js';
31
+ import { DENSE_GRID_CLASSNAME, DENSE_GRID_CONTAINER_CLASSNAME } from '../shared/catalog/catalog-grid-tokens.js';
30
32
  import { ConnectorLogo } from '../../internal/connector-logo/connector-logo.js';
31
33
  import { installedConnectorLogoSource } from '../../internal/connector-logo/connector-logo-source.js';
32
34
  import { providerLabel } from './provider-label.js';
33
35
  import { connectedCatalogKeys, } from './catalog/catalog-entry.js';
34
36
  import { ConnectorBrowse } from './catalog/connector-browse.js';
35
37
  import { useCatalog } from './catalog/use-catalog.js';
36
- import { CapabilityPageShell } from '../shared/capability-page-shell.js';
37
- import { CatalogCard } from '../shared/catalog/catalog-card.js';
38
+ import { GrantModeTabs, withCatalog } from '../shared/agent-resource-scope.js';
39
+ import { CapabilityPageShell, useCapabilityShellEmbed } from '../shared/capability-page-shell.js';
40
+ import { plainGrantSwitch } from '../shared/access-list.js';
41
+ import { EditorList } from '../sections/view/agent-editor-primitives.js';
42
+ import { ErrorState } from '../../primitives/error-state.js';
43
+ import { EmptyArt } from '../../primitives/empty-art.js';
38
44
  import { catalogEmptyKind } from '../shared/catalog/catalog-empty.js';
39
45
  import { CatalogNoMatch } from '../shared/catalog/catalog-empty-state.js';
40
- import { CatalogGrid } from '../shared/catalog/catalog-grid.js';
41
46
  import { useTunnelConnections } from '@kortix/sdk/react';
42
47
  import { useSlashFocus } from '../../internal/hooks/index.js';
43
48
  import { connectorDisplayName, connectorSummary, filterConnectors, } from './connector-filter.js';
@@ -173,8 +178,14 @@ function parseScope(value) {
173
178
  * `legacyDetailRedirect` forwards it, so an OAuth grant that started before
174
179
  * the change still lands on the right connector.
175
180
  */
176
- export function ConnectorsPage({ projectId }) {
181
+ export function ConnectorsPage({ projectId, surface = { kind: 'global' }, grant, agentPanel, rowControl, }) {
177
182
  const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
183
+ const tAgentScope = useI18nTranslations('agentScope');
184
+ const tTabs = useI18nTranslations('agentEditor.tabs');
185
+ const agentScoped = surface.kind === 'agent' && grant !== undefined;
186
+ // The agent page's rail layout: Add sits in the footer card, not the header.
187
+ const embed = useCapabilityShellEmbed();
188
+ const railLayout = agentScoped && embed?.titled === true;
178
189
  // `accountId` comes off the detail this page already loads. Without it
179
190
  // `useProjectCan` fetches the project a second time under its own key AND
180
191
  // holds the IAM probe disabled until that lands — so Add and every write
@@ -269,7 +280,11 @@ export function ConnectorsPage({ projectId }) {
269
280
  // form. Channels has its own primary action already — the Slack hero owns
270
281
  // it — so it needs neither, and leaving them on screen would offer to search
271
282
  // a list that is not there.
272
- const channelsActive = scope === 'channels';
283
+ // Channels is the inbound side (who can reach the agent), not a connector
284
+ // the agent is granted — so it is not part of the agent-scoped view.
285
+ const channelsActive = scope === 'channels' && !agentScoped;
286
+ // Channels is a project-wide inbound surface, so an agent's page leaves it out.
287
+ const visibleScopes = SCOPES.filter((s) => !agentScoped || s !== 'channels');
273
288
  // The machine list answers 503 on a deployment with computers disabled, so
274
289
  // the Computer card shows only where a computer can be connected.
275
290
  const computersEnabled = useTunnelConnections({ refetchInterval: false }).isSuccess;
@@ -287,9 +302,38 @@ export function ConnectorsPage({ projectId }) {
287
302
  // already carries them (and a machineless one is not in `connectors`).
288
303
  const ownMatches = useMemo(() => filtered.filter((connector) => connector.provider !== 'computer'), [filtered]);
289
304
  const emptyKind = catalogEmptyKind(connectors.length, filtered.length);
290
- // One card shape for the project's own connectors: the Connected tab's grid
291
- // and the All tab's "Your connectors" section (KRTX-2531) render it alike.
292
- const ownConnectorCard = (connector) => (_jsx(CatalogCard, { variant: "plain", leading: _jsx(ConnectorLogo, { source: installedConnectorLogoSource(connector), size: "lg" }), title: connectorDisplayName(connector), subtitle: _jsx("span", { className: "text-muted-foreground text-xs", children: describeConnector(connector) }), badges: _jsx(ConnectorStatusBadge, { connector: connector }), trailing: connectorSetupStatus(connector) === 'connected' ? _jsx(ConnectorConnectedMark, {}) : undefined, href: connectorHref(projectId, connector.slug) }, connector.slug));
305
+ // One row shape for the project's connectors in both modes (the shared
306
+ // Access row): logo, name, what it is, the exception mark, and in agent
307
+ // mode the switch that grants it. The name opens the connector's page.
308
+ const connectorRows = (list) => {
309
+ const slugs = connectors.map((connector) => connector.slug);
310
+ const toggle = agentScoped && grant?.set ? plainGrantSwitch(grant.value, slugs, grant.set) : null;
311
+ return list.map((connector) => {
312
+ const switched = toggle ? toggle(connector.slug) : {};
313
+ return {
314
+ id: connector.slug,
315
+ title: connectorDisplayName(connector),
316
+ leading: _jsx(ConnectorLogo, { source: installedConnectorLogoSource(connector), size: "sm" }),
317
+ description: describeConnector(connector),
318
+ status: _jsx(ConnectorStatusBadge, { connector: connector }),
319
+ onOpen: () => router.push(connectorHref(projectId, connector.slug)),
320
+ ...switched,
321
+ ...(rowControl ? { control: (switched.checked && rowControl(connector.slug)) || '—' } : {}),
322
+ };
323
+ });
324
+ };
325
+ // The project's own connectors, the way All apps shows the catalogue: logo
326
+ // tiles in a grid, the state as a dot on the logo (`ConnectorStatusLogo`)
327
+ // instead of a pill. In an agent's view each tile also carries the grant
328
+ // switch and, while granted, its policy set, beside the link.
329
+ const ownConnectors = (list) => {
330
+ const rows = new Map(connectorRows(list).map((row) => [row.id, row]));
331
+ return (_jsx("div", { className: DENSE_GRID_CONTAINER_CLASSNAME, children: _jsx("div", { className: DENSE_GRID_CLASSNAME, children: list.map((connector) => {
332
+ const row = rows.get(connector.slug);
333
+ const toggle = agentScoped && row?.onCheckedChange ? (_jsxs("span", { className: "flex items-center gap-2", children: [row.checked && row.control && row.control !== '—' ? row.control : null, _jsx(Switch, { "aria-label": connectorDisplayName(connector), checked: row.checked === true, onCheckedChange: row.onCheckedChange, disabled: row.disabled })] })) : undefined;
334
+ return (_jsx(CatalogCard, { variant: "plain", href: connectorHref(projectId, connector.slug), leading: _jsx(ConnectorStatusLogo, { connector: connector, source: installedConnectorLogoSource(connector) }), title: connectorDisplayName(connector), subtitle: _jsx("span", { className: "text-muted-foreground truncate text-xs", children: describeConnector(connector) }), trailing: toggle, trailingInteractive: toggle !== undefined, className: cn(agentScoped && row?.checked === false && 'opacity-60 hover:opacity-100') }, connector.slug));
335
+ }) }) }));
336
+ };
293
337
  // Quiet on purpose: a filter, not a second tab strip.
294
338
  const catalogFilters = (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "text", size: "sm", className: cn('gap-1 px-0 transition-colors', kindFilter !== 'all' && 'text-foreground'), "aria-label": tPages('typeFilterLabel'), children: [kindFilter === 'all'
295
339
  ? tPages('typeFilterAll')
@@ -309,11 +353,50 @@ export function ConnectorsPage({ projectId }) {
309
353
  // jumps back to it (`useSlashFocus`).
310
354
  const searchRef = useRef(null);
311
355
  useSlashFocus(searchRef, !channelsActive && !rulesOpen);
356
+ // The catalogue scope strip. Rendered immediately, not behind `settled`:
357
+ // static labels over a scope read out of the URL have nothing to wait for.
358
+ // Project scope shows it in the filter row; agent scope shows it on the
359
+ // heading of the list it narrows, below the grant sentence.
360
+ const scopeTabs = visibleScopes.length > 1 ? (_jsx(Tabs, { value: scope, onValueChange: (value) => setScope(value), children: _jsx(TabsList, { children: visibleScopes.map((value) => (_jsx(TabsTrigger, { value: value, children: SCOPE_LABEL[value] }, value))) }) })) : null;
361
+ // The project's connectors as rows, with the page-level states: loading,
362
+ // a failed load, nothing yet, nothing matching.
363
+ const listBody = (list) => {
364
+ if (!settled) {
365
+ return (_jsx(EditorList, { children: [0, 1, 2].map((i) => (_jsxs("li", { className: "flex min-h-12 items-center gap-3 px-4 py-2", children: [_jsx(Skeleton, { className: "size-6 rounded-sm" }), _jsx(Skeleton, { className: "h-4 w-40 rounded-sm" })] }, i))) }));
366
+ }
367
+ if (isError) {
368
+ return (_jsx(ErrorState, { size: "sm", title: tI18nComplete.raw('text51ae0a7e3783'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: retry, children: tPages('retry') }) }));
369
+ }
370
+ if (list.length > 0)
371
+ return ownConnectors(list);
372
+ if (query.trim())
373
+ return _jsx(CatalogNoMatch, { query: query });
374
+ return (_jsx(EmptyState, { media: _jsx(EmptyArt, { icon: PlugsConnectedIcon }), title: tI18nComplete.raw('text51ae0a7e3783'), description: tI18nComplete.raw('texta3487dfc2132') }));
375
+ };
376
+ // The project's connectors over the whole catalogue: the All tab in
377
+ // project mode, and the agent view in agent mode (rows carry its switch).
378
+ const catalogSection = (_jsxs(_Fragment, { children: [ownMatches.length > 0 ? (_jsxs("div", { className: "space-y-3", children: [_jsx("h2", { className: "text-sm font-medium", children: tPages('yourConnectors') }), ownConnectors(ownMatches)] })) : null, _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-2", children: [_jsx("h2", { className: "text-sm font-medium", children: tPages('allApps') }), _jsx("div", { className: "flex flex-wrap items-center gap-4", children: catalogFilters })] }), _jsx(ConnectorBrowse, { state: catalog, connectedKeys: connectedKeys, hrefFor: catalogHref, install: catalogInstall, emptyTitle: tI18nComplete.raw('text3a63271cafc1'), emptyDescription: tI18nComplete.raw('textf652a621153e'),
379
+ // A slug search that only the project's own connector answers
380
+ // must not ALSO read "No matches" under its card (KRTX-2531).
381
+ suppressNoMatch: ownMatches.length > 0 })] }));
382
+ const addMenu = canWrite && !channelsActive ? (_jsx(NewEntityMenu, { label: railLayout ? tTabs('addConnector') : tI18nComplete.raw('text18fdd549b2ed'), pending: configure.pending, onChat: () => configure.start(newConfigPrompt('connector')), quick: {
383
+ icon: PlugsConnectedIcon,
384
+ label: tPages('addMcpMenu'),
385
+ description: tPages('addMcpMenuHint'),
386
+ onSelect: () => {
387
+ setMcpApp(null);
388
+ setPanel('mcp');
389
+ },
390
+ }, manual: {
391
+ label: tI18nComplete.raw('text90ccaee30bdc'),
392
+ description: tI18nComplete.raw('textb0fbe9dc1fcc'),
393
+ onSelect: () => setPanel('custom'),
394
+ } })) : undefined;
312
395
  return (
313
396
  // Global rules open in a SplitSheet: the page narrows to make room instead
314
397
  // of being covered. `PoliciesPanel` is a long CRUD list whose save bar
315
398
  // sticks to the body's bottom edge, so the body is the only scroller.
316
- _jsxs(SplitSheet, { open: rulesOpen, onOpenChange: setRulesOpen, size: "lg", className: "flex-1", children: [_jsx(SplitSheetMain, { children: _jsxs(CapabilityPageShell, { title: tI18nComplete.raw('textc3d2e79ebdd0'), description: SCOPE_DESCRIPTION[scope], search: channelsActive ? undefined : (_jsxs(InputGroupSearch, { children: [_jsx(InputGroupSearchIcon, { children: _jsx(MagnifyingGlassIcon, {}) }), _jsx(InputGroupSearchInput, { ref: searchRef, placeholder: tI18nComplete.raw('textc386cb852691'), value: query, onChange: (event) => setQuery(event.target.value), variant: "popover", size: "sm" })] })), action:
399
+ _jsxs(SplitSheet, { open: rulesOpen, onOpenChange: setRulesOpen, size: "lg", className: "flex-1", children: [_jsx(SplitSheetMain, { children: _jsxs(CapabilityPageShell, { title: tI18nComplete.raw('textc3d2e79ebdd0'), description: agentScoped ? tAgentScope('connectorsDescription') : SCOPE_DESCRIPTION[scope], search: channelsActive ? undefined : (_jsxs(InputGroupSearch, { children: [_jsx(InputGroupSearchIcon, { children: _jsx(MagnifyingGlassIcon, {}) }), _jsx(InputGroupSearchInput, { ref: searchRef, placeholder: agentScoped ? tAgentScope('connectorsSearch') : tI18nComplete.raw('textc386cb852691'), value: query, onChange: (event) => setQuery(event.target.value), variant: "popover", size: "sm" })] })), action:
317
400
  /* The page's one header action, and it carries its label: a bare `+`
318
401
  square made the reader guess, and what it opens — a custom-connector
319
402
  form, not the catalogue — is not guessable from a glyph. Default
@@ -321,29 +404,15 @@ export function ConnectorsPage({ projectId }) {
321
404
  lines up with the search field beside it. `aria-label` keeps the
322
405
  full sentence for screen readers; it opens with the visible "Add",
323
406
  so the accessible name still contains the visible label. */
324
- canWrite && !channelsActive ? (_jsx(NewEntityMenu, { label: tI18nComplete.raw('text18fdd549b2ed'), pending: configure.pending, onChat: () => configure.start(newConfigPrompt('connector')), quick: {
325
- icon: PlugsConnectedIcon,
326
- label: tPages('addMcpMenu'),
327
- description: tPages('addMcpMenuHint'),
328
- onSelect: () => {
329
- setMcpApp(null);
330
- setPanel('mcp');
331
- },
332
- }, manual: {
333
- label: tI18nComplete.raw('text90ccaee30bdc'),
334
- description: tI18nComplete.raw('textb0fbe9dc1fcc'),
335
- onSelect: () => setPanel('custom'),
336
- } })) : undefined, filters: (_jsxs(_Fragment, { children: [_jsx(Tabs, { value: scope, onValueChange: (value) => setScope(value), children: _jsx(TabsList, { children: SCOPES.map((value) => (_jsx(TabsTrigger, { value: value, children: SCOPE_LABEL[value] }, value))) }) }), _jsx(Button, { type: "button", variant: "text", size: "sm", onClick: () => setRulesOpen(true), className: "ml-auto px-0 transition-colors", children: tI18nComplete.raw('text1d59a5e09714') })] })), children: [channelsActive ? (
407
+ railLayout ? undefined : addMenu, filters: agentScoped && grant ? (_jsx(GrantModeTabs, { grant: withCatalog(grant, connectors.map((c) => c.slug)), label: tAgentScope('connectorsAccess') })) : visibleScopes.length > 1 ? (_jsxs(_Fragment, { children: [scopeTabs, _jsx(Button, { type: "button", variant: "text", size: "sm", onClick: () => setRulesOpen(true), className: "ml-auto px-0 transition-colors", children: tI18nComplete.raw('text1d59a5e09714') })] })) : undefined, children: [agentScoped ? (
408
+ /* Agent mode: the same catalogue as project mode (the project's
409
+ connectors, one switch each, then every app), then the agent's
410
+ rule sets. One library, two modes (Marko, 2026-10-28). */
411
+ _jsxs("div", { className: "space-y-6", children: [settled && !isError ? catalogSection : listBody(ownMatches), agentPanel, railLayout ? (_jsxs("div", { className: "bg-popover flex items-center gap-3 rounded-lg px-4 py-3", children: [_jsx(ShieldIcon, { className: "text-muted-foreground size-4 shrink-0" }), _jsx("p", { className: "text-muted-foreground min-w-0 flex-1 text-xs text-pretty", children: tTabs.rich('policySetsNote', { file: () => _jsx("code", { className: "text-foreground font-mono", children: "kortix.yaml" }) }) }), addMenu] })) : null] })) : channelsActive ? (
337
412
  /* The whole of what used to be `/projects/<id>/channels`, minus the
338
413
  shell it used to bring — this page's `CapabilityPageShell` is the
339
414
  one column, the one heading and the one scroll container now. */
340
- _jsx(ChannelsSection, { projectId: projectId })) : catalogActive ? (_jsxs(_Fragment, { children: [ownMatches.length > 0 ? (_jsxs("div", { className: "space-y-3", children: [_jsx("h2", { className: "text-sm font-medium", children: tPages('yourConnectors') }), _jsx(CatalogGrid, { dense: true, isLoading: false, isError: false, onRetry: retry, isEmpty: false, empty: null, children: ownMatches.map(ownConnectorCard) })] })) : null, _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-2", children: [_jsx("h2", { className: "text-sm font-medium", children: tPages('allApps') }), catalogFilters] }), _jsx(ConnectorBrowse, { state: catalog, connectedKeys: connectedKeys, hrefFor: catalogHref, install: catalogInstall, emptyTitle: tI18nComplete.raw('text3a63271cafc1'), emptyDescription: tI18nComplete.raw('textf652a621153e'),
341
- // A slug search that only the project's own connector answers
342
- // must not ALSO read "No matches" under its card (KRTX-2531).
343
- suppressNoMatch: ownMatches.length > 0 })] })) : (_jsxs(_Fragment, { children: [_jsx(ConnectorMovesBanner, { projectId: projectId }), _jsx(CatalogGrid, { dense: true,
344
- // `!settled`, not `connectorsQuery.isLoading`: the empty state's
345
- // wording depends on `projectQuery` too. Same gate as the filter row.
346
- isLoading: !settled, isError: isError, error: connectorsQuery.error ?? projectQuery.error, onRetry: retry, isEmpty: emptyKind !== null, empty: emptyKind === 'no-match' ? (_jsx(CatalogNoMatch, { query: query })) : (_jsx(EmptyState, { icon: PlugIcon, size: "sm", title: tI18nComplete.raw('text51ae0a7e3783'), description: tI18nComplete.raw('texta3487dfc2132'), action: _jsx(Button, { size: "sm", variant: "secondary", onClick: () => setScope('all'), children: tI18nComplete.raw('text45bfe4f17af7') }) })), children: filtered.map(ownConnectorCard) })] })), _jsx(AddMcpServerDialog, { projectId: projectId, app: mcpApp, open: panel === 'mcp', onOpenChange: (open) => setPanel(open ? 'mcp' : null), takenSlugs: connectors.map((connector) => connector.slug), onAdded: invalidate }, mcpApp?.url ?? 'paste'), installRequest ? (_jsx(InstallDialog, { appName: installRequest.target.appName, way: installRequest.way, open: true, pending: false, onOpenChange: (open) => !open && setInstallRequest(null), onConfirm: confirmInstall }, installRequest.target.appName)) : null, _jsx(Modal, { open: panel === 'custom', onOpenChange: (open) => !open && setPanel(null), children: _jsxs(ModalContent, { className: "lg:max-w-3xl", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: tI18nComplete.raw('text90ccaee30bdc') }), _jsx(ModalDescription, { children: tI18nComplete.raw('textd2f3be0047c4') })] }), _jsx(ModalBody, { className: "max-h-[75vh] overflow-y-auto", children: _jsx(CustomConnectorForm, { projectId: projectId, onAdded: (slug, { addAccount }) => {
415
+ _jsx(ChannelsSection, { projectId: projectId })) : catalogActive ? (catalogSection) : (_jsxs(_Fragment, { children: [_jsx(ConnectorMovesBanner, { projectId: projectId }), listBody(filtered)] })), _jsx(AddMcpServerDialog, { projectId: projectId, app: mcpApp, open: panel === 'mcp', onOpenChange: (open) => setPanel(open ? 'mcp' : null), takenSlugs: connectors.map((connector) => connector.slug), onAdded: invalidate }, mcpApp?.url ?? 'paste'), installRequest ? (_jsx(InstallDialog, { appName: installRequest.target.appName, way: installRequest.way, open: true, pending: false, onOpenChange: (open) => !open && setInstallRequest(null), onConfirm: confirmInstall }, installRequest.target.appName)) : null, _jsx(Modal, { open: panel === 'custom', onOpenChange: (open) => !open && setPanel(null), children: _jsxs(ModalContent, { className: "lg:max-w-3xl", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: tI18nComplete.raw('text90ccaee30bdc') }), _jsx(ModalDescription, { children: tI18nComplete.raw('textd2f3be0047c4') })] }), _jsx(ModalBody, { className: "max-h-[75vh] overflow-y-auto", children: _jsx(CustomConnectorForm, { projectId: projectId, onAdded: (slug, { addAccount }) => {
347
416
  invalidate();
348
417
  setPanel(null);
349
418
  router.push(connectorHref(projectId, slug, { addAccount }));
@@ -47,7 +47,7 @@ const surfaceLabel = (kind) => wayKindLabel(kind);
47
47
  /** Tools shown before "Show all". */
48
48
  const TOOLS_PREVIEW = 40;
49
49
  /**
50
- * `/projects/<id>/customize/connectors/<app>` — one catalogue app: what it is,
50
+ * `/projects/<id>/admin/connectors/<app>` — one catalogue app: what it is,
51
51
  * the one Install button, the connectors this project already has for it, and
52
52
  * the other ways to connect it.
53
53
  *
@@ -51,9 +51,6 @@ export function ConnectorAgents({ projectId, connector }) {
51
51
  if (access.isError) {
52
52
  return (_jsx(ErrorState, { size: "sm", title: t('agentsLoadFailed'), description: access.error instanceof Error ? access.error.message : undefined, action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => void access.refetch(), children: tSets('retry') }) }));
53
53
  }
54
- if (!access.supported) {
55
- return _jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: t('agentsNeedsV2') });
56
- }
57
54
  if (access.agents.length === 0) {
58
55
  return _jsx(EmptyState, { icon: RobotIcon, size: "sm", title: t('agentsEmpty') });
59
56
  }
@@ -3,7 +3,7 @@ import { type ReactNode } from 'react';
3
3
  import { type AppRef } from '../connector-routes.js';
4
4
  /** The column `CapabilityPageShell` gives the list page beside this one. */
5
5
  /**
6
- * `/projects/<id>/customize/connectors/<app>/<connector>` — one connector, as
6
+ * `/projects/<id>/admin/connectors/<app>/<connector>` — one connector, as
7
7
  * a page: its accounts, its tools, its settings.
8
8
  *
9
9
  * `appSegment` is navigation context only. It decides where Back goes: the
@@ -43,7 +43,7 @@ import { ConnectorStatusBadge } from './status-badge.js';
43
43
  import { useConnectorDetail } from './use-connector-detail.js';
44
44
  /** The column `CapabilityPageShell` gives the list page beside this one. */
45
45
  /**
46
- * `/projects/<id>/customize/connectors/<app>/<connector>` — one connector, as
46
+ * `/projects/<id>/admin/connectors/<app>/<connector>` — one connector, as
47
47
  * a page: its accounts, its tools, its settings.
48
48
  *
49
49
  * `appSegment` is navigation context only. It decides where Back goes: the
@@ -89,7 +89,10 @@ export function ConnectorPage({ projectId, appSegment, connectorSlug, }) {
89
89
  isError: connectorsQuery.isError,
90
90
  });
91
91
  if (state === 'loading') {
92
- return (_jsxs(DetailPageShell, { busy: true, children: [_jsx(Skeleton, { className: "h-4 w-24 rounded-sm py-0" }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Skeleton, { className: "size-10 py-0" }), _jsx(Skeleton, { className: "h-6 w-48 rounded-sm py-0" })] }), _jsx(Skeleton, { className: "h-8 w-64 py-0" }), _jsx(Skeleton, { className: "h-20 w-full py-0" }), _jsx(Skeleton, { className: "h-20 w-full py-0" })] }));
92
+ return (
93
+ // Grouped, in the loaded page's order: back link, name, the status card,
94
+ // the tab row, the tab body. One block per group, no line per field.
95
+ _jsxs(DetailPageShell, { busy: true, children: [_jsx(Skeleton, { className: "h-4 w-24 rounded-sm py-0" }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Skeleton, { className: "size-10 shrink-0 rounded-md py-0" }), _jsx(Skeleton, { className: "h-6 w-40 rounded-sm py-0" })] }), _jsx(Skeleton, { className: "h-36 w-full rounded-md py-0" }), _jsx(Skeleton, { className: "h-10 w-96 max-w-full rounded-lg py-0" }), _jsx(Skeleton, { className: "h-48 w-full rounded-md py-0" })] }));
93
96
  }
94
97
  if (state === 'error') {
95
98
  return (_jsx(DetailPageShell, { children: _jsx(ErrorState, { size: "sm", title: tI18nComplete.raw('textbda9de7688c0'), description: connectorsQuery.error instanceof Error
@@ -118,7 +118,7 @@ export function ConnectorPolicySetBar({ projectId, slug, canWrite, value, onChan
118
118
  const ruleTotal = selected ? selected.policies.length : (baseQuery.data?.policies.length ?? 0);
119
119
  // Agents that can take this set: every agent not on it yet.
120
120
  const giveTo = selected ? access.agents.filter((agent) => !agents.includes(agent)) : [];
121
- return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("div", { className: "min-w-0 overflow-x-auto", children: _jsx(Tabs, { value: value ?? BASE_VALUE, onValueChange: (next) => onChange(next === BASE_VALUE ? null : next), children: _jsxs(TabsListCompact, { "aria-label": t('rulesFor'), children: [_jsx(TabsTriggerCompact, { value: BASE_VALUE, children: t('baseRules') }), sets.map((set) => (_jsxs(TabsTriggerCompact, { value: set.name, title: set.name, children: [policySetLabel(set.name), _jsxs("span", { className: "text-muted-foreground", children: [' · ', t('agentCount', { count: set.agents.length })] })] }, set.name)))] }) }) }), _jsxs(Button, { variant: "ghost", size: "sm", className: "shrink-0", onClick: () => setEditor({ mode: 'create' }), children: [_jsx(PlusIcon, { className: "size-3.5 shrink-0" }), t('createTitle')] })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-1", children: [_jsxs("p", { className: "text-muted-foreground min-w-0 text-xs text-pretty", children: [selected ? (_jsxs(_Fragment, { children: [selected.description ? `${selected.description} · ` : null, agents.length > 0 ? (_jsxs(_Fragment, { children: [t('usedByLead'), ' ', agents.map((agent, index) => (_jsxs(Fragment, { children: [index > 0 ? ', ' : null, _jsx(Link, { href: `${agentHref(projectId, agent)}?section=connectors`, className: "text-foreground underline-offset-4 hover:underline", children: agent })] }, agent)))] })) : (_jsxs(_Fragment, { children: [t('unusedLead'), ' ', _jsx(Link, { href: capabilityTabHref(projectId, 'agent'), className: "text-foreground underline-offset-4 hover:underline", children: t('unusedLink') })] }))] })) : (t('baseContext')), ' · ', t('ruleCount', { count: ruleTotal })] }), selected ? (_jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [access.supported && access.canEdit && giveTo.length > 0 ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "xs", disabled: access.pending !== null, children: [t('giveToAgent'), _jsx(CaretDownIcon, { className: "size-3 shrink-0" })] }) }), _jsxs(DropdownMenuContent, { align: "end", className: "min-w-48", children: [_jsx(DropdownMenuLabel, { children: t('giveToAgentLabel', { name: policySetLabel(selected.name) }) }), giveTo.map((agent) => {
121
+ return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("div", { className: "min-w-0 overflow-x-auto", children: _jsx(Tabs, { value: value ?? BASE_VALUE, onValueChange: (next) => onChange(next === BASE_VALUE ? null : next), children: _jsxs(TabsListCompact, { "aria-label": t('rulesFor'), children: [_jsx(TabsTriggerCompact, { value: BASE_VALUE, children: t('baseRules') }), sets.map((set) => (_jsxs(TabsTriggerCompact, { value: set.name, title: set.name, children: [policySetLabel(set.name), _jsxs("span", { className: "text-muted-foreground", children: [' · ', t('agentCount', { count: set.agents.length })] })] }, set.name)))] }) }) }), _jsxs(Button, { variant: "ghost", size: "sm", className: "shrink-0", onClick: () => setEditor({ mode: 'create' }), children: [_jsx(PlusIcon, { className: "size-3.5 shrink-0" }), t('createTitle')] })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-1", children: [_jsxs("p", { className: "text-muted-foreground min-w-0 text-xs text-pretty", children: [selected ? (_jsxs(_Fragment, { children: [selected.description ? `${selected.description} · ` : null, agents.length > 0 ? (_jsxs(_Fragment, { children: [t('usedByLead'), ' ', agents.map((agent, index) => (_jsxs(Fragment, { children: [index > 0 ? ', ' : null, _jsx(Link, { href: `${agentHref(projectId, agent)}?section=connectors`, className: "text-foreground underline-offset-4 hover:underline", children: agent })] }, agent)))] })) : (_jsxs(_Fragment, { children: [t('unusedLead'), ' ', _jsx(Link, { href: capabilityTabHref(projectId, 'agent'), className: "text-foreground underline-offset-4 hover:underline", children: t('unusedLink') })] }))] })) : (t('baseContext')), ' · ', t('ruleCount', { count: ruleTotal })] }), selected ? (_jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [access.canEdit && giveTo.length > 0 ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "xs", disabled: access.pending !== null, children: [t('giveToAgent'), _jsx(CaretDownIcon, { className: "size-3 shrink-0" })] }) }), _jsxs(DropdownMenuContent, { align: "end", className: "min-w-48", children: [_jsx(DropdownMenuLabel, { children: t('giveToAgentLabel', { name: policySetLabel(selected.name) }) }), giveTo.map((agent) => {
122
122
  const current = agentConnectorAccess(access.grantsOf(agent), slug);
123
123
  return (_jsxs(DropdownMenuItem, { onSelect: () => void access
124
124
  .setPolicySet(agent, slug, selected.name, allSlugs)
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { customizePath } from '../../../lib/routes.js';
3
+ import { adminPath } from '../../../lib/routes.js';
4
4
  import { useProjectTriggerEventApps, useProjectTriggers } from '@kortix/sdk/react';
5
5
  import { PlusIcon } from '@phosphor-icons/react';
6
6
  import { UiLink as Link } from '../../../providers/ui-provider.js';
@@ -53,5 +53,5 @@ export function ConnectorTriggers({ projectId, connector, displayName, }) {
53
53
  return null;
54
54
  return (_jsxs("section", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Label, { children: tI18nComplete.raw('textea56119b98e2') }), controls.canCreate ? (_jsxs(Button, { size: "sm", variant: "secondary", className: "gap-1.5", onClick: () => setCreating(true), children: [_jsx(PlusIcon, { className: "size-4 shrink-0" }), tI18nComplete.raw('text1ee2cf623464')] })) : null] }), isLoading ? (_jsx(Skeleton, { className: "h-14 rounded-md" })) : rows.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-xs text-pretty", children: tI18nComplete('text974e43358191', {
55
55
  name: displayName,
56
- }) })) : (_jsx("ul", { className: "space-y-2", children: rows.map((trigger) => (_jsxs("li", { className: "bg-popover flex items-center gap-3 rounded-md border px-4 py-2", children: [_jsx(TriggerTile, { trigger: trigger, surface: "bg-popover" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Link, { href: customizePath(projectId, `triggers?id=${encodeURIComponent(trigger.slug)}`), className: "min-w-0 truncate text-sm font-medium hover:underline", children: triggerName(trigger) }), _jsx(TriggerStatusBadge, { trigger: trigger })] }), _jsx("span", { className: "text-muted-foreground block truncate text-xs", children: describeWhen(trigger, eventNames) }), trigger.event ? (_jsx("span", { className: "text-muted-foreground block truncate text-xs", children: describeEventSource(trigger.event, tI18nComplete, appIndex) })) : null] })] }, trigger.slug))) })), _jsx(TriggerComposer, { projectId: projectId, open: creating, onOpenChange: setCreating, onCreated: () => setCreating(false), initialKind: "event", initialConnector: { slug: connector.slug, name: displayName } })] }));
56
+ }) })) : (_jsx("ul", { className: "space-y-2", children: rows.map((trigger) => (_jsxs("li", { className: "bg-popover flex items-center gap-3 rounded-md border px-4 py-2", children: [_jsx(TriggerTile, { trigger: trigger, surface: "bg-popover" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Link, { href: adminPath(projectId, `triggers?id=${encodeURIComponent(trigger.slug)}`), className: "min-w-0 truncate text-sm font-medium hover:underline", children: triggerName(trigger) }), _jsx(TriggerStatusBadge, { trigger: trigger })] }), _jsx("span", { className: "text-muted-foreground block truncate text-xs", children: describeWhen(trigger, eventNames) }), trigger.event ? (_jsx("span", { className: "text-muted-foreground block truncate text-xs", children: describeEventSource(trigger.event, tI18nComplete, appIndex) })) : null] })] }, trigger.slug))) })), _jsx(TriggerComposer, { projectId: projectId, open: creating, onOpenChange: setCreating, onCreated: () => setCreating(false), initialKind: "event", initialConnector: { slug: connector.slug, name: displayName } })] }));
57
57
  }