@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,87 @@
1
+ /**
2
+ * The one scope contract every resource catalog takes, so a single component
3
+ * serves two surfaces (Marko, 2026-10-24):
4
+ *
5
+ * - **global** — the full project catalog, the Customize/Project-Admin tab.
6
+ * Every connector, skill, model the project has. No grant.
7
+ * - **agent** — the SAME catalog scoped to one agent on its config page. Each
8
+ * card carries a grant control; toggling it grants or revokes the resource
9
+ * for THIS agent by writing `agents.<name>.<set>` in kortix.yaml.
10
+ *
11
+ * A page reads `scope.kind` to pick its heading, and in `agent` scope reads the
12
+ * `AgentGrant` to draw and drive the per-card checkbox. One component, two
13
+ * variants — not two pages that drift.
14
+ */
15
+ import type { AgentCapabilityGrant, AgentGrantSetV2 } from '@kortix/sdk';
16
+ /** Which surface a resource catalog renders for. */
17
+ export type ResourceScope = {
18
+ kind: 'global';
19
+ } | {
20
+ kind: 'agent';
21
+ agentName: string;
22
+ };
23
+ /**
24
+ * All · Specific · None, the agent's grant over one resource set. `all` and
25
+ * `none` decide every row; `specific` is the explicit pick list. `undefined`,
26
+ * `'none'` and `[]` all read as None.
27
+ */
28
+ export type GrantMode = 'all' | 'specific' | 'none';
29
+ export interface AgentGrant {
30
+ /** The raw stored value (`agents.<name>.connectors` etc.). */
31
+ value: AgentGrantSetV2 | undefined;
32
+ mode: GrantMode;
33
+ /** Is `id` granted right now — true for every id in `all` mode. */
34
+ isGranted: (id: string) => boolean;
35
+ /** Add or remove one id from the pick list (only meaningful in `specific`). */
36
+ toggle: (id: string) => void;
37
+ setMode: (mode: GrantMode) => void;
38
+ /** Write the whole grant (a row switch under All keeps the rest: `plainGrantSwitch`). */
39
+ set?: (next: AgentGrantSetV2) => void;
40
+ }
41
+ /**
42
+ * Drives an {@link AgentGrant} off a draft value and its setter. Mirrors
43
+ * `GrantModeField`'s transitions, including the empty-pick nuance: switching to
44
+ * Specific with nothing picked stays Specific (not None) via a local intent
45
+ * flag, so the checklist is reachable before the first pick.
46
+ */
47
+ export declare function useAgentGrant(value: AgentGrantSetV2 | undefined, onChange: (next: AgentGrantSetV2) => void): AgentGrant;
48
+ /**
49
+ * The grant over a known catalog: All → Specific keeps every id that is on
50
+ * (all of them), instead of an empty pick list that reads back as None.
51
+ */
52
+ export declare function withCatalog(grant: AgentGrant, ids: readonly string[]): AgentGrant;
53
+ /**
54
+ * The ids a Specific grant names that the catalog no longer holds: a resource
55
+ * deleted or renamed after the grant was written. The agent page lists them
56
+ * beside the catalog with a Missing mark, so the editor can see each one and
57
+ * revoke it. All and None name no id, so they have none.
58
+ */
59
+ export declare function grantOrphans(value: AgentGrantSetV2 | undefined, known: Iterable<string>): string[];
60
+ /**
61
+ * The agent's grant-mode selector, the catalog's primary control in `agent`
62
+ * scope: one All · Specific · None segmented control, then one muted line
63
+ * that says what the mode means, so the decision never reads as a list
64
+ * filter. It takes its own row: a catalog's list filters (All | Connected)
65
+ * sit with the list they filter, never beside it. `agentName` names the agent
66
+ * in the control's label outside an embedded resource screen.
67
+ */
68
+ export declare function GrantModeTabs({ grant, label, agentName, }: {
69
+ grant: AgentGrant;
70
+ label: string;
71
+ agentName?: string;
72
+ }): import("react").JSX.Element;
73
+ /**
74
+ * A grant in the plain All · Specific · None form. `{ exclude }` exists only
75
+ * on skills and extensions, which the capability switches edit; a screen
76
+ * without switches reads it as All.
77
+ */
78
+ export declare function plainGrant(value: AgentCapabilityGrant | undefined): AgentGrantSetV2 | undefined;
79
+ /**
80
+ * One switch over a plain grant (connectors, secrets, Apps): All reads every
81
+ * row on, and turning one off under All keeps every other id, so the grant
82
+ * becomes Specific instead of losing the rest. The last one off is None.
83
+ */
84
+ export declare function plainGrantSwitch(value: AgentGrantSetV2 | undefined, ids: readonly string[], onChange: (next: AgentGrantSetV2) => void): (id: string) => {
85
+ checked: boolean;
86
+ onCheckedChange: (on: boolean) => void;
87
+ };
@@ -0,0 +1,123 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from 'react';
4
+ import { useTranslations } from '../../i18n/index.js';
5
+ import { agentDisplayName } from '../../internal/components/agent-mark.js';
6
+ import { Tabs, TabsList, TabsTrigger } from '../../primitives/tabs.js';
7
+ import { useCapabilityShellEmbed } from './capability-page-shell.js';
8
+ /**
9
+ * Drives an {@link AgentGrant} off a draft value and its setter. Mirrors
10
+ * `GrantModeField`'s transitions, including the empty-pick nuance: switching to
11
+ * Specific with nothing picked stays Specific (not None) via a local intent
12
+ * flag, so the checklist is reachable before the first pick.
13
+ */
14
+ export function useAgentGrant(value, onChange) {
15
+ const [wantSpecific, setWantSpecific] = useState(() => Array.isArray(value) && value.length > 0);
16
+ const mode = value === 'all'
17
+ ? 'all'
18
+ : Array.isArray(value) && (value.length > 0 || wantSpecific)
19
+ ? 'specific'
20
+ : 'none';
21
+ const selected = new Set(Array.isArray(value) ? value : []);
22
+ return {
23
+ value,
24
+ mode,
25
+ isGranted: (id) => (mode === 'all' ? true : selected.has(id)),
26
+ toggle: (id) => {
27
+ const next = new Set(selected);
28
+ if (next.has(id))
29
+ next.delete(id);
30
+ else
31
+ next.add(id);
32
+ onChange([...next]);
33
+ },
34
+ setMode: (next) => {
35
+ setWantSpecific(next === 'specific');
36
+ if (next === 'all')
37
+ return onChange('all');
38
+ if (next === 'none')
39
+ return onChange('none');
40
+ onChange(Array.isArray(value) ? value : []);
41
+ },
42
+ set: (next) => {
43
+ setWantSpecific(Array.isArray(next) && next.length > 0);
44
+ onChange(next);
45
+ },
46
+ };
47
+ }
48
+ /**
49
+ * The grant over a known catalog: All → Specific keeps every id that is on
50
+ * (all of them), instead of an empty pick list that reads back as None.
51
+ */
52
+ export function withCatalog(grant, ids) {
53
+ return {
54
+ ...grant,
55
+ setMode: (next) => next === 'specific' && grant.value === 'all' && grant.set && ids.length > 0
56
+ ? grant.set([...ids])
57
+ : grant.setMode(next),
58
+ };
59
+ }
60
+ /**
61
+ * The ids a Specific grant names that the catalog no longer holds: a resource
62
+ * deleted or renamed after the grant was written. The agent page lists them
63
+ * beside the catalog with a Missing mark, so the editor can see each one and
64
+ * revoke it. All and None name no id, so they have none.
65
+ */
66
+ export function grantOrphans(value, known) {
67
+ if (!Array.isArray(value))
68
+ return [];
69
+ const have = new Set(known);
70
+ return value.filter((id) => !have.has(id));
71
+ }
72
+ const GRANT_MODE_TABS = [
73
+ { value: 'all', labelKey: 'modeAll' },
74
+ { value: 'specific', labelKey: 'modeSpecific' },
75
+ { value: 'none', labelKey: 'modeNone' },
76
+ ];
77
+ /**
78
+ * The agent's grant-mode selector, the catalog's primary control in `agent`
79
+ * scope: one All · Specific · None segmented control, then one muted line
80
+ * that says what the mode means, so the decision never reads as a list
81
+ * filter. It takes its own row: a catalog's list filters (All | Connected)
82
+ * sit with the list they filter, never beside it. `agentName` names the agent
83
+ * in the control's label outside an embedded resource screen.
84
+ */
85
+ export function GrantModeTabs({ grant, label, agentName, }) {
86
+ const t = useTranslations('agentScope');
87
+ const tTabs = useTranslations('agentEditor.tabs');
88
+ const embed = useCapabilityShellEmbed();
89
+ const name = agentName ?? embed?.agentName;
90
+ const hint = grant.mode === 'all'
91
+ ? tTabs('grantAllHint')
92
+ : grant.mode === 'specific'
93
+ ? tTabs('grantSpecificHint')
94
+ : tTabs('grantNoneHint');
95
+ const control = (_jsx(Tabs, { value: grant.mode, onValueChange: (next) => grant.setMode(next), title: embed?.titled ? hint : undefined, children: _jsx(TabsList, { variant: "segmented", size: "sm", "aria-label": name ? `${tTabs('canUse', { name: agentDisplayName(name) })} ${label}` : label, children: GRANT_MODE_TABS.map((tab) => (_jsx(TabsTrigger, { value: tab.value, children: t(tab.labelKey) }, tab.value))) }) }));
96
+ // Beside the view's title (the rail layout): the control alone, its meaning on hover.
97
+ if (embed?.titled)
98
+ return control;
99
+ return (_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1", children: [control, _jsx("p", { className: "text-muted-foreground min-w-0 text-sm text-pretty", children: hint })] }));
100
+ }
101
+ /**
102
+ * A grant in the plain All · Specific · None form. `{ exclude }` exists only
103
+ * on skills and extensions, which the capability switches edit; a screen
104
+ * without switches reads it as All.
105
+ */
106
+ export function plainGrant(value) {
107
+ return value === undefined || typeof value === 'string' || Array.isArray(value) ? value : 'all';
108
+ }
109
+ /**
110
+ * One switch over a plain grant (connectors, secrets, Apps): All reads every
111
+ * row on, and turning one off under All keeps every other id, so the grant
112
+ * becomes Specific instead of losing the rest. The last one off is None.
113
+ */
114
+ export function plainGrantSwitch(value, ids, onChange) {
115
+ const picked = value === 'all' ? [...ids] : Array.isArray(value) ? value : [];
116
+ return (id) => ({
117
+ checked: value === 'all' || picked.includes(id),
118
+ onCheckedChange: (on) => {
119
+ const next = on ? [...picked.filter((x) => x !== id), id] : picked.filter((x) => x !== id);
120
+ onChange(next.length > 0 ? next : 'none');
121
+ },
122
+ });
123
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Skills, Tools and Extensions: ONE component each, in two modes (Marko,
3
+ * 2026-10-27: "no double components, one component with either mode,
4
+ * agent-based or project-wide").
5
+ *
6
+ * - **Project** (Project admin): the project's catalog. The project's own
7
+ * items first, then what Kortix ships in a quiet fold. Skills adds New,
8
+ * each skill's files, and Remove.
9
+ * - **Agent** (the agent page's Access tab): the same list, plus the
10
+ * All · Specific · None row and one switch per row writing the agent's
11
+ * grant (`skills`, `tools`, `extensions`) into the page's draft. One item
12
+ * off under All is `{ exclude: [id] }`, never an expanded list.
13
+ *
14
+ * The catalog is the project's (`GET /projects/:id/capabilities`): the same
15
+ * list in both modes, so the two can never disagree.
16
+ */
17
+ import { type AgentCapabilityGrant } from '@kortix/sdk';
18
+ import { type ReactNode } from 'react';
19
+ import type { AgentDraft } from '../sections/view/agent-editor.js';
20
+ import { type AgentGrant } from './agent-resource-scope.js';
21
+ export type CapabilityView = 'skills' | 'tools' | 'extensions';
22
+ /** Agent mode: whose grant the switches write, and the page's draft that holds it. */
23
+ export interface CapabilityAgent {
24
+ name: string;
25
+ editor: AgentDraft;
26
+ }
27
+ /**
28
+ * The All · Specific · None select over a capability grant. `{ exclude }`
29
+ * reads as All. Specific keeps every id that is on now, so a built-in row
30
+ * that was on stays on.
31
+ */
32
+ export declare function capabilityModeGrant(value: AgentCapabilityGrant | undefined, ids: readonly string[], omitted: 'all' | 'none', onChange: (next: AgentCapabilityGrant) => void): AgentGrant;
33
+ /** Skills, Tools or Extensions, project-wide or for one agent. */
34
+ export declare function CapabilityLibrary({ projectId, view, agent, footer, }: {
35
+ projectId: string;
36
+ view: CapabilityView;
37
+ /** Absent: the project's catalog (Project admin). Present: this agent's grant over it. */
38
+ agent?: CapabilityAgent;
39
+ /** Below the list: Tools' approval rules on an agent's page. */
40
+ footer?: ReactNode;
41
+ }): import("react").JSX.Element;
@@ -0,0 +1,271 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * Skills, Tools and Extensions: ONE component each, in two modes (Marko,
5
+ * 2026-10-27: "no double components, one component with either mode,
6
+ * agent-based or project-wide").
7
+ *
8
+ * - **Project** (Project admin): the project's catalog. The project's own
9
+ * items first, then what Kortix ships in a quiet fold. Skills adds New,
10
+ * each skill's files, and Remove.
11
+ * - **Agent** (the agent page's Access tab): the same list, plus the
12
+ * All · Specific · None row and one switch per row writing the agent's
13
+ * grant (`skills`, `tools`, `extensions`) into the page's draft. One item
14
+ * off under All is `{ exclude: [id] }`, never an expanded list.
15
+ *
16
+ * The catalog is the project's (`GET /projects/:id/capabilities`): the same
17
+ * list in both modes, so the two can never disagree.
18
+ */
19
+ import { capabilityGranted, getProjectDetail, setCapabilityGranted, } from '@kortix/sdk';
20
+ import { contract, qk, useProjectAccountId } from '@kortix/sdk/react';
21
+ import { MagnifyingGlassIcon } from '@phosphor-icons/react';
22
+ import { useQuery } from '@tanstack/react-query';
23
+ import { useMemo, useState } from 'react';
24
+ import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
25
+ import { useProjectCapabilities } from '../../internal/hooks/projects/use-agent-config.js';
26
+ import { PROJECT_ACTIONS } from '../../internal/lib/project-actions.js';
27
+ import { useProjectCan } from '../../internal/lib/use-project-can.js';
28
+ import { adminPath } from '../../lib/routes.js';
29
+ import { Button } from '../../primitives/button.js';
30
+ import { ErrorState } from '../../primitives/error-state.js';
31
+ import { InputGroupSearch, InputGroupSearchClear, InputGroupSearchIcon, InputGroupSearchInput, } from '../../primitives/input-group.js';
32
+ import { Skeleton } from '../../primitives/skeleton.js';
33
+ import { UiLink as Link } from '../../providers/ui-provider.js';
34
+ import { Tabs, TabsList, TabsTrigger } from '../../primitives/tabs.js';
35
+ import { cn } from '../../internal/lib/utils.js';
36
+ import { BuiltinSkillModal } from '../skills/builtin-skill-modal.js';
37
+ import { CatalogCard } from './catalog/catalog-card.js';
38
+ import { GRID_CLASSNAME } from './catalog/catalog-grid-tokens.js';
39
+ import { AccessGroup, AccessList, BuiltinGroup } from './access-list.js';
40
+ import { EditorList } from '../sections/view/agent-editor-primitives.js';
41
+ import { NewSkillModal } from '../skills/new-skill-modal.js';
42
+ import { newConfigPrompt, useConfigureThread } from '../use-configure-thread.js';
43
+ import { GrantModeTabs } from './agent-resource-scope.js';
44
+ import { CapabilityPageShell, useCapabilityShellEmbed } from './capability-page-shell.js';
45
+ import { detailSelection } from './detail-selection.js';
46
+ import { EntityDetailModal } from './entity/entity-modal.js';
47
+ import { NewEntityMenu } from './new-entity-menu.js';
48
+ import { toolRule } from './tool-rules.js';
49
+ /** What an omitted grant means: every tool, no v3 skill or extension. */
50
+ const OMITTED = { tools: 'all', skills: 'none', extensions: 'none' };
51
+ /** Built-in tools in the order an agent reaches for them. */
52
+ const BUILTIN_TOOL_GROUPS = ['workspace', 'interaction', 'kortix'];
53
+ /**
54
+ * The All · Specific · None select over a capability grant. `{ exclude }`
55
+ * reads as All. Specific keeps every id that is on now, so a built-in row
56
+ * that was on stays on.
57
+ */
58
+ export function capabilityModeGrant(value, ids, omitted, onChange) {
59
+ const current = value ?? omitted;
60
+ const mode = Array.isArray(current) ? (current.length > 0 ? 'specific' : 'none') : current === 'none' ? 'none' : 'all';
61
+ return {
62
+ value: Array.isArray(current) || typeof current === 'string' ? current : 'all',
63
+ mode,
64
+ isGranted: (id) => capabilityGranted(value, id, omitted),
65
+ toggle: (id) => onChange(setCapabilityGranted(value, id, !capabilityGranted(value, id, omitted), omitted)),
66
+ setMode: (next) => {
67
+ if (next === 'all')
68
+ return onChange('all');
69
+ if (next === 'none')
70
+ return onChange('none');
71
+ const on = ids.filter((id) => capabilityGranted(value, id, omitted));
72
+ onChange(on.length > 0 ? on : 'none');
73
+ },
74
+ };
75
+ }
76
+ /** One row per catalog item, in the order the view draws them: the project's, then Kortix's. */
77
+ function catalogRows(view, catalog, t, agentMode) {
78
+ if (view === 'skills') {
79
+ const item = (skill) => ({ id: skill.id, description: skill.description, disabled: !skill.available });
80
+ return {
81
+ project: catalog.skills.filter((s) => s.group === 'project').map(item),
82
+ builtin: catalog.skills.filter((s) => s.group === 'builtin').map(item),
83
+ // Specific names only skills a session can load: a flagged skill whose flag is off is not one.
84
+ ids: catalog.skills.filter((s) => s.available).map((s) => s.id),
85
+ };
86
+ }
87
+ if (view === 'tools') {
88
+ const item = (tool) => ({
89
+ id: tool.id,
90
+ description: tool.group === 'project'
91
+ ? t('projectTool', { path: tool.source ?? '' })
92
+ : tool.source
93
+ ? `${tool.description ?? ''} ${t('replacedBy', { path: tool.source })}`
94
+ : tool.description,
95
+ });
96
+ return {
97
+ project: catalog.tools.filter((tool) => tool.group === 'project').map(item),
98
+ builtin: BUILTIN_TOOL_GROUPS.flatMap((group) => catalog.tools.filter((tool) => tool.group === group).map(item)),
99
+ ids: catalog.tools.map((tool) => tool.id),
100
+ };
101
+ }
102
+ const item = (ext) => ({
103
+ id: ext.id,
104
+ // "Follows the agent tool switch" only where that switch is on screen.
105
+ description: ext.controlled_by && agentMode ? `${ext.description ?? ''} ${t('followsTool', { tool: ext.controlled_by })}` : ext.description,
106
+ status: ext.required ? _jsx("span", { className: "text-muted-foreground text-xs", children: t('alwaysOn') }) : undefined,
107
+ });
108
+ // A required platform extension (permission rules on script calls, the show
109
+ // tool's part, the turn's date) is plumbing, not a choice: it is not listed.
110
+ return {
111
+ project: catalog.extensions.filter((ext) => ext.group === 'project').map(item),
112
+ builtin: catalog.extensions.filter((ext) => ext.group === 'platform' && !ext.required).map(item),
113
+ ids: catalog.extensions.filter((ext) => ext.group === 'project').map((ext) => ext.id),
114
+ };
115
+ }
116
+ /**
117
+ * Agent mode: give each row its switch. A tool switch carries its aliases,
118
+ * and codemode also clears `codemode: off`. A platform extension follows its
119
+ * tool's switch; a required one has none.
120
+ */
121
+ function withSwitches(view, rows, catalog, editor) {
122
+ const toolSwitch = (id, aliases) => {
123
+ const value = editor.draft.tools;
124
+ const codemodeOff = id === 'codemode' && editor.draft.codemode === 'off';
125
+ return {
126
+ checked: !codemodeOff && capabilityGranted(value, id, OMITTED.tools),
127
+ onCheckedChange: (on) => {
128
+ editor.set('tools', setCapabilityGranted(value, [id, ...aliases], on, OMITTED.tools));
129
+ if (on && codemodeOff)
130
+ editor.set('codemode', undefined);
131
+ },
132
+ };
133
+ };
134
+ return rows.map((row) => {
135
+ if (view === 'tools') {
136
+ const tool = catalog.tools.find((x) => x.id === row.id);
137
+ return { ...row, ...toolSwitch(row.id, tool?.aliases ?? []) };
138
+ }
139
+ if (view === 'extensions') {
140
+ const ext = catalog.extensions.find((x) => x.id === row.id);
141
+ if (!ext || ext.required)
142
+ return row;
143
+ if (ext.group === 'platform') {
144
+ const tool = catalog.tools.find((x) => x.id === ext.controlled_by);
145
+ return tool ? { ...row, ...toolSwitch(tool.id, tool.aliases) } : row;
146
+ }
147
+ }
148
+ const key = view === 'skills' ? 'skills' : 'extensions';
149
+ const value = editor.draft[key];
150
+ return {
151
+ ...row,
152
+ checked: !row.disabled && capabilityGranted(value, row.id, OMITTED[view]),
153
+ onCheckedChange: (on) => editor.set(key, setCapabilityGranted(value, row.id, on, OMITTED[view])),
154
+ };
155
+ });
156
+ }
157
+ const VIEW_COPY = {
158
+ skills: { titleKey: 'skillsTitle', access: 'skillsAccess' },
159
+ tools: { titleKey: 'toolsTitle', access: 'toolsAccess' },
160
+ extensions: { titleKey: 'extensionsTitle', access: 'extensionsAccess' },
161
+ };
162
+ /** Skills, Tools or Extensions, project-wide or for one agent. */
163
+ export function CapabilityLibrary({ projectId, view, agent, footer, }) {
164
+ const t = useI18nTranslations('agentCapabilities');
165
+ const tTabs = useI18nTranslations('agentEditor.tabs');
166
+ const embed = useCapabilityShellEmbed();
167
+ const query = useProjectCapabilities(projectId);
168
+ const catalog = query.data;
169
+ const [search, setSearch] = useState('');
170
+ // Project admin's filter: the project's own items, Kortix's built-in ones, or both.
171
+ const [scope, setScope] = useState('all');
172
+ // A built-in skill's card opens it here (it is not a file in the project).
173
+ const [builtinSkill, setBuiltinSkill] = useState(null);
174
+ const skills = useSkillManagement(projectId, view === 'skills');
175
+ const rows = useMemo(() => (catalog ? catalogRows(view, catalog, t, !!agent) : null), [catalog, view, t, agent]);
176
+ const match = (row) => {
177
+ const q = search.trim().toLowerCase();
178
+ return !q || row.id.toLowerCase().includes(q) || String(row.description ?? '').toLowerCase().includes(q);
179
+ };
180
+ let project = rows?.project.filter(match) ?? [];
181
+ let builtin = rows?.builtin.filter(match) ?? [];
182
+ if (view === 'skills') {
183
+ // A flagged built-in skill whose flag is off says so, with the way to turn it on.
184
+ builtin = builtin.map((row) => row.disabled
185
+ ? {
186
+ ...row,
187
+ description: (_jsxs(_Fragment, { children: [t('flagOff'), ' ', _jsx(Link, { href: adminPath(projectId, 'feature-flags'), className: "text-foreground underline underline-offset-2", children: t('flagSettings') })] })),
188
+ }
189
+ : row);
190
+ project = project.map((row) => ({ ...row, onOpen: skills.open(row.id) }));
191
+ }
192
+ if (agent && catalog) {
193
+ project = withSwitches(view, project, catalog, agent.editor);
194
+ builtin = withSwitches(view, builtin, catalog, agent.editor);
195
+ }
196
+ const grant = agent && rows && (view !== 'extensions' || rows.project.length > 0)
197
+ ? capabilityModeGrant(agent.editor.draft[view], rows.ids, OMITTED[view], (next) => agent.editor.set(view, next))
198
+ : null;
199
+ const empty = view === 'skills' ? t('emptyProjectSkills') : view === 'tools' ? t('emptyProjectTools') : t('emptyProjectExtensions');
200
+ // The agent page's rail layout: one card of every row, the project's first;
201
+ // each tool carries its approval rule, an off one a dash.
202
+ const railCard = !!agent && !!embed?.titled;
203
+ const ruleLabel = (rule) => rule === 'allow' ? tTabs('ruleAllow') : rule === 'ask' ? tTabs('ruleAsk') : rule === 'deny' ? tTabs('ruleDeny') : rule === 'custom' ? tTabs('ruleCustom') : '';
204
+ const cardRows = railCard
205
+ ? [...project, ...builtin].map((row) => view === 'tools' && agent
206
+ ? { ...row, control: row.checked ? ruleLabel(toolRule(agent.editor.oc.permission, row.id)) : '—' }
207
+ : row)
208
+ : [];
209
+ // The agent's own view: the project's items, then Kortix's, folded.
210
+ const agentSections = (_jsxs(_Fragment, { children: [_jsx(AccessGroup, { title: t('groups.project'), items: project, empty: search ? t('noMatch') : empty }), _jsx(BuiltinGroup, { items: builtin, defaultOpen: project.length === 0 || !!search.trim() })] }));
211
+ // Project admin. Skills: the All / Project / Kortix filter, Kortix's skills as cards.
212
+ // Tools and Extensions: no filter; the project's own group only when it has
213
+ // items, then the built-ins under the API's real groups.
214
+ let projectSections;
215
+ if (view === 'skills') {
216
+ projectSections = (_jsxs(_Fragment, { children: [scope !== 'kortix' ? (_jsx(AccessGroup, { title: t('groups.project'), items: project, empty: search ? t('noMatch') : empty })) : null, scope !== 'project' ? (_jsxs("section", { className: "space-y-3", children: [_jsx("h3", { className: "text-foreground text-sm font-medium", children: t('groups.kortix') }), builtin.length > 0 ? (_jsx("div", { className: GRID_CLASSNAME, children: builtin.map((row) => (_jsx(CatalogCard, { title: _jsx("span", { className: "font-mono !tracking-normal", children: row.id }), description: row.disabled ? t('flagOff') : typeof row.description === 'string' ? row.description : undefined, className: cn(row.disabled && 'opacity-60'), onClick: () => setBuiltinSkill(row.id) }, row.id))) })) : (_jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: t('noMatch') }))] })) : null] }));
217
+ }
218
+ else {
219
+ const builtinGroups = view === 'tools'
220
+ ? BUILTIN_TOOL_GROUPS.map((group) => ({
221
+ group,
222
+ items: builtin.filter((row) => catalog?.tools.find((tool) => tool.id === row.id)?.group === group),
223
+ }))
224
+ : [{ group: 'platform', items: builtin }];
225
+ const shown = builtinGroups.filter((g) => g.items.length > 0);
226
+ projectSections = (_jsxs(_Fragment, { children: [project.length > 0 ? _jsx(AccessGroup, { title: t('groups.project'), items: project }) : null, shown.map((g) => (_jsx(AccessGroup, { title: t(`groups.${g.group}`), items: g.items }, g.group))), project.length === 0 && shown.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: search ? t('noMatch') : empty })) : null] }));
227
+ }
228
+ const body = catalog && railCard ? (_jsx("div", { "data-testid": `capability-library-${view}`, "data-grant": JSON.stringify(agent?.editor.draft[view] ?? null), children: cardRows.length > 0 ? (_jsx(AccessList, { items: cardRows })) : (_jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: search ? t('noMatch') : empty })) })) : catalog ? (_jsx("div", { className: "space-y-6", "data-testid": `capability-library-${view}`, "data-grant": agent ? JSON.stringify(agent.editor.draft[view] ?? null) : undefined, children: agent ? agentSections : projectSections })) : query.isError ? (_jsx(ErrorState, { size: "sm", title: t('loadError'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => void query.refetch(), children: t('retry') }) })) : (_jsx(EditorList, { children: [0, 1, 2, 3].map((i) => (_jsx("li", { className: "flex min-h-12 items-center gap-3 px-4 py-2", children: _jsx(Skeleton, { className: "h-4 w-40 rounded-sm" }) }, i))) }));
229
+ return (_jsxs(CapabilityPageShell, { title: t(VIEW_COPY[view].titleKey), description: agent ? t(`${view}Description`) : t(`${view}ProjectDescription`), action: skills.createButton, search: _jsxs(InputGroupSearch, { children: [_jsx(InputGroupSearchIcon, { children: _jsx(MagnifyingGlassIcon, {}) }), _jsx(InputGroupSearchInput, { placeholder: t(`${view}Search`), value: search, onChange: (event) => setSearch(event.target.value), size: "sm" }), search ? _jsx(InputGroupSearchClear, { onClick: () => setSearch('') }) : null] }), filters: agent ? (grant ? _jsx(GrantModeTabs, { grant: grant, label: t(VIEW_COPY[view].access), agentName: agent.name }) : undefined) : view !== 'skills' ? undefined : (_jsx(Tabs, { value: scope, onValueChange: (next) => setScope(next), children: _jsxs(TabsList, { "aria-label": t(VIEW_COPY[view].titleKey), children: [_jsx(TabsTrigger, { value: "all", children: t('scopeAll') }), _jsx(TabsTrigger, { value: "project", children: t('groups.project') }), _jsx(TabsTrigger, { value: "kortix", children: t('groups.kortix') })] }) })), children: [body, footer, skills.modals, view === 'skills' && !agent ? (_jsx(BuiltinSkillModal, { projectId: projectId, name: builtinSkill, description: (() => {
230
+ const d = rows?.builtin.find((row) => row.id === builtinSkill)?.description;
231
+ return typeof d === 'string' ? d : null;
232
+ })(), onOpenChange: (open) => !open && setBuiltinSkill(null) })) : null] }));
233
+ }
234
+ /** Skills' own controls, in both modes: New (chat or form), each skill's files, Remove. */
235
+ function useSkillManagement(projectId, on) {
236
+ const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
237
+ const accountId = useProjectAccountId(projectId);
238
+ const canWrite = useProjectCan(projectId, PROJECT_ACTIONS.PROJECT_SKILL_WRITE, { accountId }).allowed === true;
239
+ const configure = useConfigureThread(projectId);
240
+ const [selectedName, setSelectedName] = useState(null);
241
+ const [formOpen, setFormOpen] = useState(false);
242
+ const detailQuery = useQuery({
243
+ queryKey: qk.project.detail(projectId),
244
+ queryFn: () => getProjectDetail(projectId),
245
+ enabled: on,
246
+ ...contract('config'),
247
+ });
248
+ const skills = detailQuery.data?.config.skills ?? [];
249
+ const detail = detailSelection({
250
+ selection: selectedName,
251
+ record: skills.find((skill) => skill.name === selectedName),
252
+ isSuccess: detailQuery.isSuccess,
253
+ });
254
+ // The config came back without this skill: it really was removed or renamed.
255
+ if (detail.isMissing)
256
+ setSelectedName(null);
257
+ if (!on)
258
+ return { createButton: undefined, modals: null, open: () => undefined };
259
+ return {
260
+ open: (name) => () => setSelectedName(name),
261
+ createButton: canWrite ? (_jsx(NewEntityMenu, { label: tI18nComplete('text18fdd549b2ed'), pending: configure.pending, onChat: () => configure.start(newConfigPrompt('skill')), manual: {
262
+ label: tI18nComplete.raw('texta38668224f1a'),
263
+ description: tI18nComplete.raw('textedac6130dac7'),
264
+ onSelect: () => setFormOpen(true),
265
+ } })) : undefined,
266
+ modals: (_jsxs(_Fragment, { children: [_jsx(EntityDetailModal, { projectId: projectId, entity: detail.record, kind: "skill", removable: true, open: detail.open, isResolving: detail.isResolving, onOpenChange: (next) => {
267
+ if (!next)
268
+ setSelectedName(null);
269
+ } }), _jsx(NewSkillModal, { projectId: projectId, open: formOpen, onOpenChange: setFormOpen })] })),
270
+ };
271
+ }
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import { type ReactNode } from 'react';
2
2
  interface CapabilityPageShellProps {
3
3
  title: string;
4
4
  /** One line. Longer explanations go in `titleAddon` (an info hover card). */
@@ -23,6 +23,23 @@ interface CapabilityPageShellProps {
23
23
  stacked?: boolean;
24
24
  children: ReactNode;
25
25
  }
26
+ /**
27
+ * Set by the agent page around a resource screen it shows in agent scope
28
+ * (Access > Connectors, Runtime > Model, Triggers). The shell then drops its
29
+ * own title (the agent page's tabs name the view), runs full width on the
30
+ * agent page's gutter, and draws `lead` (the Access view switcher) as the
31
+ * first row inside its scroller, so the switcher scrolls with the content.
32
+ */
33
+ export interface CapabilityShellEmbed {
34
+ agentName: string;
35
+ lead?: ReactNode;
36
+ /** The column class, so every Access and Runtime view shares one width. */
37
+ className?: string;
38
+ /** Show the screen's title over its description: the view sits beside a rail that does not name it. */
39
+ titled?: boolean;
40
+ }
41
+ export declare const CapabilityShellEmbedProvider: import("react").Provider<CapabilityShellEmbed | null>;
42
+ export declare function useCapabilityShellEmbed(): CapabilityShellEmbed | null;
26
43
  /**
27
44
  * Shared page shell for the three capability routes (agents, connectors,
28
45
  * skills). `max-w-5xl` is a deliberate departure from
@@ -1,7 +1,16 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { SidebarToggle } from '../../internal/layout/sidebar-toggle.js';
4
+ import { useInCustomizeFrame } from './customize-tab-bar.js';
3
5
  import { cn } from '../../internal/lib/utils.js';
6
+ import { createContext, useContext } from 'react';
7
+ import { SettingsSectionHeader } from '../../primitives/settings-section-header.js';
4
8
  import { CapabilityScrollRootProvider, useCapabilityScrollRootRef } from './capability-scroll-root.js';
9
+ const CapabilityShellEmbedContext = createContext(null);
10
+ export const CapabilityShellEmbedProvider = CapabilityShellEmbedContext.Provider;
11
+ export function useCapabilityShellEmbed() {
12
+ return useContext(CapabilityShellEmbedContext);
13
+ }
5
14
  /**
6
15
  * Shared page shell for the three capability routes (agents, connectors,
7
16
  * skills). `max-w-5xl` is a deliberate departure from
@@ -20,7 +29,18 @@ import { CapabilityScrollRootProvider, useCapabilityScrollRootRef } from './capa
20
29
  */
21
30
  export function CapabilityPageShell({ title, description, titleAddon, action, search, filters, wide = false, stacked = false, children, }) {
22
31
  const scrollRef = useCapabilityScrollRootRef();
32
+ const embed = useCapabilityShellEmbed();
33
+ const framed = useInCustomizeFrame();
34
+ if (embed?.titled) {
35
+ // Beside the agent page's rail: the view's title left (no sentence under
36
+ // it, the Settings dialect), its grant control (`filters`) right; search
37
+ // and the view's own action in one row under them.
38
+ return (_jsx("div", { ref: scrollRef, className: "min-h-0 flex-1 overflow-y-auto", "data-capability-embed": "", children: _jsxs("div", { className: cn('w-full space-y-5 px-4 pt-5 pb-24 md:px-8', embed.className), children: [embed.lead, _jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-end md:justify-between", children: [_jsx(SettingsSectionHeader, { title: title, className: "min-w-0" }), filters ? _jsx("div", { className: "shrink-0", children: filters }) : null] }), search || action ? (_jsxs("div", { className: "flex items-center gap-2", children: [search ? _jsx("div", { className: "min-w-0 flex-1", children: search }) : null, action] })) : null, _jsx(CapabilityScrollRootProvider, { scrollRef: scrollRef, children: children })] }) }));
39
+ }
40
+ if (embed) {
41
+ return (_jsx("div", { ref: scrollRef, className: "min-h-0 flex-1 overflow-y-auto", "data-capability-embed": "", children: _jsxs("div", { className: cn('w-full space-y-5 px-4 pt-5 pb-24 md:px-8', embed.className), children: [embed.lead, _jsxs("header", { className: cn('flex flex-col gap-3', !stacked && 'md:flex-row md:items-center md:justify-between'), children: [_jsx("h2", { className: "sr-only", children: title }), _jsx("p", { className: "text-muted-foreground min-w-0 text-sm text-pretty md:max-w-xl", children: description }), search || action ? (_jsxs("div", { className: cn('flex w-full shrink-0 items-center gap-2', !stacked && 'md:w-auto'), children: [search ? _jsx("div", { className: cn('min-w-0 flex-1', !stacked && 'md:w-64 md:flex-none'), children: search }) : null, action] })) : null] }), filters ? _jsx("div", { className: "flex flex-wrap items-center justify-between gap-2", children: filters }) : null, _jsx(CapabilityScrollRootProvider, { scrollRef: scrollRef, children: children })] }) }));
42
+ }
23
43
  return (_jsx("div", { ref: scrollRef, className: "min-h-0 flex-1 overflow-y-auto", children: _jsxs("div", { className: wide
24
44
  ? 'mx-auto w-full max-w-7xl space-y-5 px-4 py-10 pb-20 md:px-8 lg:py-14'
25
- : 'mx-auto w-full max-w-5xl space-y-5 px-4 py-10 pb-20 lg:py-14', children: [_jsxs("header", { className: cn('flex flex-col gap-3', !stacked && 'sm:flex-row sm:items-start sm:justify-between'), children: [_jsxs("div", { className: "space-y-1 sm:max-w-md", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("h1", { className: "text-foreground text-xl font-medium text-balance", children: title }), titleAddon] }), _jsx("p", { className: "text-muted-foreground text-sm text-balance", children: description })] }), search || action ? (_jsxs("div", { className: cn('flex w-full shrink-0 items-center gap-2', !stacked && 'sm:w-auto'), children: [search ? (_jsx("div", { className: cn('min-w-0 flex-1', !stacked && 'sm:w-64 sm:flex-none'), children: search })) : null, action] })) : null] }), filters ? (_jsx("div", { className: "flex flex-wrap items-center justify-between gap-2", children: filters })) : null, _jsx(CapabilityScrollRootProvider, { scrollRef: scrollRef, children: children })] }) }));
45
+ : 'mx-auto w-full max-w-5xl space-y-5 px-4 py-10 pb-20 lg:py-14', children: [_jsxs("header", { className: cn('flex flex-col gap-3', !stacked && 'sm:flex-row sm:items-start sm:justify-between'), children: [_jsxs("div", { className: "space-y-1 sm:max-w-md", children: [_jsxs("div", { className: "flex items-center gap-1", children: [framed ? null : _jsx(SidebarToggle, { className: "-ml-2" }), _jsx("h1", { className: "text-foreground text-xl font-medium text-balance", children: title }), titleAddon] }), _jsx("p", { className: "text-muted-foreground text-sm text-balance", children: description })] }), search || action ? (_jsxs("div", { className: cn('flex w-full shrink-0 items-center gap-2', !stacked && 'sm:w-auto'), children: [search ? (_jsx("div", { className: cn('min-w-0 flex-1', !stacked && 'sm:w-64 sm:flex-none'), children: search })) : null, action] })) : null] }), filters ? (_jsx("div", { className: "flex flex-wrap items-center justify-between gap-2", children: filters })) : null, _jsx(CapabilityScrollRootProvider, { scrollRef: scrollRef, children: children })] }) }));
26
46
  }
@@ -0,0 +1,14 @@
1
+ import type { SpaceGroup } from '@kortix/sdk';
2
+ /** The sentinel filter value that shows every space (grouped). */
3
+ export declare const ALL_SPACES = "all";
4
+ /**
5
+ * A compact segmented filter over a project's spaces: `All` plus one chip per
6
+ * space, each with its count. Selecting a space scopes the catalog to it;
7
+ * `All` shows the grouped sections. Pairs with `groupBySpace` + the catalog
8
+ * views. Renders nothing when there is only the Project-wide bucket.
9
+ */
10
+ export declare function CatalogSpaceTabs<T>({ groups, value, onValueChange, }: {
11
+ groups: Array<SpaceGroup<T>>;
12
+ value: string;
13
+ onValueChange: (value: string) => void;
14
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useTranslations } from '../../../i18n/index.js';
3
+ import { CountBadge } from '../../../primitives/count-badge.js';
4
+ import { Tabs, TabsListCompact, TabsTriggerCompact } from '../../../primitives/tabs.js';
5
+ /** The sentinel filter value that shows every space (grouped). */
6
+ export const ALL_SPACES = 'all';
7
+ /**
8
+ * A compact segmented filter over a project's spaces: `All` plus one chip per
9
+ * space, each with its count. Selecting a space scopes the catalog to it;
10
+ * `All` shows the grouped sections. Pairs with `groupBySpace` + the catalog
11
+ * views. Renders nothing when there is only the Project-wide bucket.
12
+ */
13
+ export function CatalogSpaceTabs({ groups, value, onValueChange, }) {
14
+ const t = useTranslations('spaces');
15
+ // Only worth a filter when the project actually splits into spaces.
16
+ const hasRealSplit = groups.some((g) => !g.isDefault);
17
+ if (!hasRealSplit)
18
+ return null;
19
+ return (_jsx(Tabs, { value: value, onValueChange: onValueChange, children: _jsxs(TabsListCompact, { "aria-label": t('filter'), children: [_jsx(TabsTriggerCompact, { value: ALL_SPACES, children: t('all') }), groups.map((group) => (_jsxs(TabsTriggerCompact, { value: group.name, children: [group.label, _jsx(CountBadge, { count: group.items.length, tone: "neutral" })] }, group.name)))] }) }));
20
+ }