@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,20 @@
1
+ import type { ReactNode } from 'react';
2
+ /**
3
+ * A room inside a space: the space's own room (the project room named like
4
+ * the space's slug, the space page's first tab) or the room a board `chat`
5
+ * block names. The host renders the conversation through
6
+ * `UiHostComponents.RoomPanel`; a host without it links to its rooms page.
7
+ * Nothing here creates a room: the first post does. With the `agent_rooms`
8
+ * flag off it renders nothing.
9
+ */
10
+ export declare function SpaceRoom({ projectId, roomName, topic, fill, intro, className, }: {
11
+ projectId: string;
12
+ roomName: string;
13
+ /** The topic a room gets when the first post creates it. */
14
+ topic?: string | null;
15
+ /** Fill the container with no frame and no header: the space page's room tab. */
16
+ fill?: boolean;
17
+ /** What the room shows above its first message, in place of the one-line intro. */
18
+ intro?: ReactNode;
19
+ className?: string;
20
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useFeatureFlag } from '@kortix/sdk/react';
4
+ import { HashIcon } from '@phosphor-icons/react';
5
+ import { useTranslations } from '../../i18n/index.js';
6
+ import { uiRoutes } from '../../lib/routes.js';
7
+ import { UiLink as Link, useUiComponents } from '../../providers/ui-provider.js';
8
+ /**
9
+ * A room inside a space: the space's own room (the project room named like
10
+ * the space's slug, the space page's first tab) or the room a board `chat`
11
+ * block names. The host renders the conversation through
12
+ * `UiHostComponents.RoomPanel`; a host without it links to its rooms page.
13
+ * Nothing here creates a room: the first post does. With the `agent_rooms`
14
+ * flag off it renders nothing.
15
+ */
16
+ export function SpaceRoom({ projectId, roomName, topic, fill = false, intro, className, }) {
17
+ const { RoomPanel } = useUiComponents();
18
+ const rooms = useFeatureFlag(projectId, 'agent_rooms');
19
+ const t = useTranslations('spaces');
20
+ const roomsHref = uiRoutes().rooms(projectId);
21
+ if (rooms.isLoading || !rooms.enabled)
22
+ return null;
23
+ if (RoomPanel) {
24
+ return (_jsx("div", { className: className, children: _jsx(RoomPanel, { projectId: projectId, roomName: roomName, emptyTopic: topic ?? undefined, fill: fill, intro: intro }) }));
25
+ }
26
+ return (_jsx("div", { className: className, children: _jsxs("div", { className: "bg-popover flex flex-col gap-1.5 rounded-md border px-4 py-3", children: [_jsxs("span", { className: "text-foreground flex min-w-0 items-center gap-1 text-sm font-medium", children: [_jsx(HashIcon, { className: "size-4 shrink-0" }), _jsx("span", { className: "truncate", children: roomName })] }), _jsx("span", { className: "text-muted-foreground text-xs", children: roomsHref ? (_jsx(Link, { href: roomsHref, className: "text-foreground underline-offset-4 hover:underline", children: t('openRooms') })) : (t('roomHint')) })] }) }));
27
+ }
@@ -0,0 +1,14 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type ManifestSpace } from '@kortix/sdk';
3
+ /**
4
+ * The "+" beside a space's tabs: add a view (Goals, Apps, Artifacts, a
5
+ * folder), pin an App or an Artifact, add a link or a board, or edit the tabs.
6
+ * Every choice is one commit to `spaces.<slug>.tabs` in `kortix.yaml`.
7
+ */
8
+ export declare function SpaceTabMenu({ projectId, space, onAdded, children, }: {
9
+ projectId: string;
10
+ space: ManifestSpace;
11
+ /** Called with the new tab's key, to open it. */
12
+ onAdded: (key: string) => void;
13
+ children: ReactNode;
14
+ }): import("react").JSX.Element;
@@ -0,0 +1,127 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState } from 'react';
4
+ import { spaceTabKey, spaceTabs } from '@kortix/sdk';
5
+ import { useArtifacts, useFeatureFlag, useProjectApps } from '@kortix/sdk/react';
6
+ import { AppWindowIcon, ArrowDownIcon, ArrowUpIcon, FileTextIcon, FolderSimpleIcon, LinkSimpleIcon, PencilSimpleIcon, SquaresFourIcon, StackSimpleIcon, TargetIcon, XIcon, } from '@phosphor-icons/react';
7
+ import { useTranslations } from '../../i18n/index.js';
8
+ import { Button } from '../../primitives/button.js';
9
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from '../../primitives/dropdown-menu.js';
10
+ import { Field, FieldLabel } from '../../primitives/field.js';
11
+ import { Input } from '../../primitives/input.js';
12
+ import { Modal, ModalBody, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTitle, } from '../../primitives/modal.js';
13
+ import { Switch } from '../../primitives/switch.js';
14
+ import { errorToast, successToast } from '../../primitives/toast.js';
15
+ import { useTabLabel } from './space-tab-panels.js';
16
+ import { appendSpaceTab, setSpaceTabs } from './space-templates.js';
17
+ import { useManifestWrite } from './use-space-manifest.js';
18
+ const VIEW_ICON = {
19
+ goals: _jsx(TargetIcon, {}),
20
+ apps: _jsx(AppWindowIcon, {}),
21
+ artifacts: _jsx(FileTextIcon, {}),
22
+ };
23
+ /**
24
+ * The "+" beside a space's tabs: add a view (Goals, Apps, Artifacts, a
25
+ * folder), pin an App or an Artifact, add a link or a board, or edit the tabs.
26
+ * Every choice is one commit to `spaces.<slug>.tabs` in `kortix.yaml`.
27
+ */
28
+ export function SpaceTabMenu({ projectId, space, onAdded, children, }) {
29
+ const t = useTranslations('spaces');
30
+ const write = useManifestWrite(projectId);
31
+ const goalsOn = useFeatureFlag(projectId, 'goals').enabled;
32
+ const artifactsOn = useFeatureFlag(projectId, 'artifacts').enabled;
33
+ const apps = useProjectApps(projectId);
34
+ const artifacts = useArtifacts(artifactsOn ? projectId : null, { limit: 20 });
35
+ const [ask, setAsk] = useState(null);
36
+ const current = spaceTabs(space);
37
+ const has = (type) => current.some((tab) => tab.type === type);
38
+ const add = async (tab) => {
39
+ try {
40
+ await write((yaml) => appendSpaceTab(yaml, space.name, tab));
41
+ successToast(t('tabAdded'));
42
+ onAdded(spaceTabKey(tab, current.length));
43
+ }
44
+ catch (error) {
45
+ errorToast(t('saveError'), { description: error instanceof Error ? error.message : undefined });
46
+ throw error;
47
+ }
48
+ };
49
+ // A menu item that opens a modal lets the menu close first.
50
+ const open = (next) => requestAnimationFrame(() => setAsk(next));
51
+ const views = ['goals', 'apps', 'artifacts'].filter((type) => !has(type) && (type !== 'goals' || goalsOn) && (type !== 'artifacts' || artifactsOn));
52
+ return (_jsxs(_Fragment, { children: [_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: children }), _jsxs(DropdownMenuContent, { align: "start", className: "w-56", children: [_jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { children: [_jsx(SquaresFourIcon, {}), t('menu.view')] }), _jsxs(DropdownMenuSubContent, { className: "w-48", children: [views.map((type) => (_jsxs(DropdownMenuItem, { onSelect: () => void add({ type }).catch(() => { }), children: [VIEW_ICON[type], t(`tabs.${type}`)] }, type))), _jsxs(DropdownMenuItem, { onSelect: () => open('files'), children: [_jsx(FolderSimpleIcon, {}), t('menu.folder')] })] })] }), _jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { children: [_jsx(AppWindowIcon, {}), t('menu.app')] }), _jsx(DropdownMenuSubContent, { className: "max-h-72 w-56 overflow-y-auto", children: (apps.data ?? []).length === 0 ? (_jsx(DropdownMenuItem, { disabled: true, children: t('menu.noApps') })) : ((apps.data ?? []).map((app) => (_jsx(DropdownMenuItem, { onSelect: () => void add({ type: 'app', app: app.slug, label: app.name }).catch(() => { }), children: _jsx("span", { className: "truncate", children: app.name }) }, app.app_id)))) })] }), artifactsOn ? (_jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { children: [_jsx(FileTextIcon, {}), t('menu.artifact')] }), _jsx(DropdownMenuSubContent, { className: "max-h-72 w-56 overflow-y-auto", children: (artifacts.data ?? []).length === 0 ? (_jsx(DropdownMenuItem, { disabled: true, children: t('menu.noArtifacts') })) : ((artifacts.data ?? []).map((artifact) => (_jsx(DropdownMenuItem, { onSelect: () => void add({ type: 'artifact', artifact: artifact.artifact_id, label: artifact.title }).catch(() => { }), children: _jsx("span", { className: "truncate", children: artifact.title }) }, artifact.artifact_id)))) })] })) : null, _jsxs(DropdownMenuItem, { onSelect: () => open('link'), children: [_jsx(LinkSimpleIcon, {}), t('menu.link')] }), _jsxs(DropdownMenuItem, { onSelect: () => void add({ type: 'board', label: t('tabs.board'), blocks: [] }).catch(() => { }), children: [_jsx(StackSimpleIcon, {}), t('menu.board')] }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onSelect: () => open('edit'), children: [_jsx(PencilSimpleIcon, {}), t('menu.editTabs')] })] })] }), _jsx(TargetModal, { kind: ask === 'link' || ask === 'files' ? ask : null, onClose: () => setAsk(null), onAdd: add }), _jsx(EditTabsModal, { open: ask === 'edit', onOpenChange: (next) => setAsk(next ? 'edit' : null), tabs: [...current], onSave: async (tabs) => {
53
+ await write((yaml) => setSpaceTabs(yaml, space.name, tabs));
54
+ } }, ask === 'edit' ? 'open' : 'closed')] }));
55
+ }
56
+ /** Ask for a link's url (and whether to embed it) or a folder's path. */
57
+ function TargetModal({ kind, onClose, onAdd, }) {
58
+ const t = useTranslations('spaces');
59
+ const [value, setValue] = useState('');
60
+ const [label, setLabel] = useState('');
61
+ const [embed, setEmbed] = useState(false);
62
+ const [pending, setPending] = useState(false);
63
+ const isLink = kind === 'link';
64
+ const trimmed = value.trim();
65
+ const valid = isLink ? /^https?:\/\/\S+$/i.test(trimmed) : trimmed.length > 0;
66
+ const reset = () => {
67
+ setValue('');
68
+ setLabel('');
69
+ setEmbed(false);
70
+ };
71
+ const submit = async (event) => {
72
+ event.preventDefault();
73
+ if (!valid || pending)
74
+ return;
75
+ setPending(true);
76
+ try {
77
+ await onAdd(isLink
78
+ ? { type: 'link', url: trimmed, ...(label.trim() ? { label: label.trim() } : {}), ...(embed ? { embed: true } : {}) }
79
+ : { type: 'files', path: trimmed.replace(/^\/+|\/+$/g, ''), ...(label.trim() ? { label: label.trim() } : {}) });
80
+ reset();
81
+ onClose();
82
+ }
83
+ catch {
84
+ // The toast already said what failed; the dialog stays open to retry.
85
+ }
86
+ finally {
87
+ setPending(false);
88
+ }
89
+ };
90
+ return (_jsx(Modal, { open: kind !== null, onOpenChange: (next) => (next ? null : onClose()), children: _jsxs(ModalContent, { className: "lg:max-w-md", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: isLink ? t('add.linkTitle') : t('add.folderTitle') }), _jsx(ModalDescription, { children: isLink ? t('add.linkHint') : t('add.folderHint') })] }), _jsxs("form", { onSubmit: submit, children: [_jsxs(ModalBody, { className: "space-y-4", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "space-tab-target", children: isLink ? t('add.url') : t('add.path') }), _jsx(Input, { id: "space-tab-target", value: value, onChange: (event) => setValue(event.target.value), placeholder: isLink ? 'https://' : 'docs', className: isLink ? undefined : 'font-mono', autoFocus: true })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "space-tab-label", children: t('add.label') }), _jsx(Input, { id: "space-tab-label", value: label, onChange: (event) => setLabel(event.target.value) })] }), isLink ? (_jsxs("label", { htmlFor: "space-tab-embed", className: "flex items-center justify-between gap-3", children: [_jsx("span", { className: "text-foreground text-sm", children: t('add.embed') }), _jsx(Switch, { id: "space-tab-embed", checked: embed, onCheckedChange: setEmbed })] })) : null] }), _jsxs(ModalFooter, { className: "sm:justify-between", children: [_jsx(Button, { type: "button", variant: "outline-ghost", onClick: onClose, children: t('cancel') }), _jsx(Button, { type: "submit", disabled: !valid || pending, "aria-busy": pending || undefined, children: t('add.submit') })] })] })] }) }));
91
+ }
92
+ /** Rename, reorder and remove a space's tabs. The room is not listed: it is always first. */
93
+ function EditTabsModal({ open, onOpenChange, tabs, onSave, }) {
94
+ const t = useTranslations('spaces');
95
+ const [draft, setDraft] = useState(tabs);
96
+ const [pending, setPending] = useState(false);
97
+ const move = (from, to) => setDraft((list) => {
98
+ const next = [...list];
99
+ const [tab] = next.splice(from, 1);
100
+ next.splice(to, 0, tab);
101
+ return next;
102
+ });
103
+ const save = async () => {
104
+ setPending(true);
105
+ try {
106
+ await onSave(draft.map((tab) => {
107
+ const { label, ...rest } = tab;
108
+ return label?.trim() ? { ...rest, label: label.trim() } : rest;
109
+ }));
110
+ successToast(t('tabsSaved'));
111
+ onOpenChange(false);
112
+ }
113
+ catch (error) {
114
+ errorToast(t('saveError'), { description: error instanceof Error ? error.message : undefined });
115
+ }
116
+ finally {
117
+ setPending(false);
118
+ }
119
+ };
120
+ return (_jsx(Modal, { open: open, onOpenChange: onOpenChange, children: _jsxs(ModalContent, { className: "lg:max-w-lg", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: t('edit.title') }), _jsx(ModalDescription, { children: t('edit.description') })] }), _jsx(ModalBody, { children: draft.length === 0 ? (_jsx("p", { className: "text-muted-foreground py-4 text-sm", children: t('edit.empty') })) : (_jsx("ul", { className: "divide-border flex flex-col divide-y", children: draft.map((tab, index) => (_jsx(EditRow, { tab: tab, first: index === 0, last: index === draft.length - 1, onLabel: (label) => setDraft((list) => list.map((item, i) => (i === index ? { ...item, label } : item))), onUp: () => move(index, index - 1), onDown: () => move(index, index + 1), onRemove: () => setDraft((list) => list.filter((_, i) => i !== index)) }, `${spaceTabKey(tab, index)}-${index}`))) })) }), _jsxs(ModalFooter, { className: "sm:justify-between", children: [_jsx(Button, { type: "button", variant: "outline-ghost", onClick: () => onOpenChange(false), children: t('cancel') }), _jsx(Button, { type: "button", onClick: save, disabled: pending, "aria-busy": pending || undefined, children: t('edit.save') })] })] }) }));
121
+ }
122
+ function EditRow({ tab, first, last, onLabel, onUp, onDown, onRemove, }) {
123
+ const t = useTranslations('spaces');
124
+ const name = useTabLabel({ ...tab, label: undefined });
125
+ const shown = tab.label?.trim() || name;
126
+ return (_jsxs("li", { className: "flex items-center gap-2 py-2", children: [_jsx("span", { className: "text-muted-foreground w-20 shrink-0 truncate text-xs", children: t(`tabs.${tab.type}`) }), _jsx(Input, { "aria-label": t('edit.rename', { name: shown }), value: tab.label ?? '', placeholder: name, onChange: (event) => onLabel(event.target.value), className: "h-8 min-w-0 flex-1" }), _jsx(Button, { size: "icon-sm", variant: "ghost", disabled: first, onClick: onUp, "aria-label": t('edit.moveUp', { name: shown }), children: _jsx(ArrowUpIcon, {}) }), _jsx(Button, { size: "icon-sm", variant: "ghost", disabled: last, onClick: onDown, "aria-label": t('edit.moveDown', { name: shown }), children: _jsx(ArrowDownIcon, {}) }), _jsx(Button, { size: "icon-sm", variant: "ghost", onClick: onRemove, "aria-label": t('edit.remove', { name: shown }), children: _jsx(XIcon, {}) })] }));
127
+ }
@@ -0,0 +1,9 @@
1
+ import { type ManifestSpace, type SpaceTab } from '@kortix/sdk';
2
+ /** A tab's name: its `label`, else its target, else its type. */
3
+ export declare function useTabLabel(tab: SpaceTab): string;
4
+ /** The content of one tab; `tab` null is the room. */
5
+ export declare function SpaceTabPanel({ projectId, space, tab, }: {
6
+ projectId: string;
7
+ space: ManifestSpace;
8
+ tab: SpaceTab | null;
9
+ }): import("react").JSX.Element;
@@ -0,0 +1,203 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState } from 'react';
4
+ import { useQuery } from '@tanstack/react-query';
5
+ import { agentsInSpace, bindingSpace, listProjectDirectory, } from '@kortix/sdk';
6
+ import { qk, useAppAccess, useArtifact, useArtifacts, useFeatureFlag, useProjectApps, useProjectConfig, useProjectGoals, } from '@kortix/sdk/react';
7
+ import { ArrowSquareOutIcon, FileTextIcon, FolderSimpleIcon } from '@phosphor-icons/react';
8
+ import { AppPreview } from '../../apps/app-preview.js';
9
+ import { appCan, appStatus } from '../../apps/app-shared.js';
10
+ import { useLocale, useTranslations } from '../../i18n/index.js';
11
+ import { AgentMark, agentDisplayName } from '../../internal/components/agent-mark.js';
12
+ import { GoalHealthDot, goalHref } from '../../internal/goals/goal-meta.js';
13
+ import { useFilePreviewStore } from '../../internal/stores/file-preview-store.js';
14
+ import { uiRoutes } from '../../lib/routes.js';
15
+ import { cn } from '../../lib/utils.js';
16
+ import { UiLink as Link } from '../../providers/ui-provider.js';
17
+ import { Button } from '../../primitives/button.js';
18
+ import { EmptyState } from '../../primitives/empty-state.js';
19
+ import { ErrorState } from '../../primitives/error-state.js';
20
+ import { Skeleton } from '../../primitives/skeleton.js';
21
+ import { framePolicy } from '../../files/viewer/preview-policy.js';
22
+ import { SpaceBlocks } from './space-blocks.js';
23
+ import { SpaceRoom } from './space-room.js';
24
+ /** Same sandbox as the Artifacts viewer: the content server's CSP decides the rest. */
25
+ const ARTIFACT_SANDBOX = 'allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-modals allow-downloads';
26
+ /** A tab's name: its `label`, else its target, else its type. */
27
+ export function useTabLabel(tab) {
28
+ const t = useTranslations('spaces');
29
+ if (tab.label?.trim())
30
+ return tab.label.trim();
31
+ if (tab.type === 'app' && tab.app)
32
+ return tab.app;
33
+ if (tab.type === 'link' && tab.url)
34
+ return hostOf(tab.url);
35
+ if (tab.type === 'files' && tab.path)
36
+ return tab.path.split('/').filter(Boolean).at(-1) ?? t('tabs.files');
37
+ return t(`tabs.${tab.type}`);
38
+ }
39
+ function hostOf(url) {
40
+ try {
41
+ return new URL(url).host;
42
+ }
43
+ catch {
44
+ return url;
45
+ }
46
+ }
47
+ /** The content of one tab; `tab` null is the room. */
48
+ export function SpaceTabPanel({ projectId, space, tab, }) {
49
+ if (!tab)
50
+ return _jsx(RoomTab, { projectId: projectId, space: space });
51
+ switch (tab.type) {
52
+ case 'goals':
53
+ return _jsx(GoalsTab, { projectId: projectId, slug: space.name });
54
+ case 'apps':
55
+ return _jsx(AppsTab, { projectId: projectId, slug: space.name });
56
+ case 'artifacts':
57
+ return _jsx(ArtifactsTab, { projectId: projectId, slug: space.name });
58
+ case 'files':
59
+ return _jsx(FilesTab, { projectId: projectId, root: tab.path ?? '' }, tab.path);
60
+ case 'board':
61
+ return _jsx(BoardTab, { projectId: projectId, tab: tab });
62
+ case 'app':
63
+ return _jsx(AppTab, { projectId: projectId, slug: tab.app ?? '' });
64
+ case 'artifact':
65
+ return _jsx(ArtifactTab, { projectId: projectId, artifactId: tab.artifact ?? '' });
66
+ case 'link':
67
+ return _jsx(LinkTab, { tab: tab });
68
+ }
69
+ }
70
+ function RoomTab({ projectId, space }) {
71
+ const t = useTranslations('spaces');
72
+ const rooms = useFeatureFlag(projectId, 'agent_rooms');
73
+ if (!rooms.isLoading && !rooms.enabled) {
74
+ return (_jsx(Centered, { children: _jsx(EmptyState, { size: "sm", title: t('roomsOff'), description: t('roomsOffHint') }) }));
75
+ }
76
+ return (_jsx(SpaceRoom, { projectId: projectId, roomName: space.name, topic: space.description, fill: true, intro: _jsx(RoomIntro, { projectId: projectId, space: space }), className: "h-full" }));
77
+ }
78
+ /** The top of the room: what the space is for, who posts in it, and how to bring someone in. */
79
+ function RoomIntro({ projectId, space }) {
80
+ const t = useTranslations('spaces');
81
+ const locale = useLocale();
82
+ const agents = agentsInSpace(space.name, useProjectConfig(projectId)?.agents ?? []);
83
+ const names = new Intl.ListFormat(locale, { type: 'conjunction' }).format(agents.map(agentDisplayName));
84
+ return (_jsxs("div", { className: "flex max-w-2xl flex-col gap-3 px-5 pb-2", children: [agents.length ? (_jsx("span", { className: "flex -space-x-1", children: agents.map((name) => (_jsx(AgentMark, { slug: name, size: 21, className: "ring-background ring-2" }, name))) })) : null, _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("h2", { className: "text-foreground text-xl font-medium text-balance", children: t('room.introTitle', { name: space.label || space.name }) }), _jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: space.description?.trim() || t('room.introBody') })] }), _jsxs("p", { className: "text-muted-foreground text-xs text-pretty", children: [agents.length ? t('room.introAgents', { count: agents.length, names }) : t('room.introNoAgents'), ' ', t('room.introMention')] })] }));
85
+ }
86
+ /** A list tab's frame: one column on the header's gutter, so rows line up with the tabs. */
87
+ function ListFrame({ children }) {
88
+ return _jsx("div", { className: "flex w-full max-w-3xl flex-col gap-4 px-5 py-5 pb-20", children: children });
89
+ }
90
+ function Centered({ children }) {
91
+ return _jsx("div", { className: "flex h-full min-h-64 items-center justify-center px-4 py-8", children: children });
92
+ }
93
+ function ViewAll({ href }) {
94
+ const t = useTranslations('spaces');
95
+ if (!href)
96
+ return null;
97
+ return (_jsx("div", { className: "flex justify-end", children: _jsx(Button, { asChild: true, size: "sm", variant: "ghost", children: _jsx(Link, { href: href, children: t('viewAll') }) }) }));
98
+ }
99
+ function Rows({ children }) {
100
+ return _jsx("ul", { className: "border-border divide-border flex flex-col divide-y rounded-md border", children: children });
101
+ }
102
+ function Row({ href, mark, meta, children }) {
103
+ const body = (_jsxs(_Fragment, { children: [mark, _jsx("span", { className: "text-foreground min-w-0 flex-1 truncate text-sm", children: children }), meta ? _jsx("span", { className: "text-muted-foreground shrink-0 text-xs", children: meta }) : null] }));
104
+ const row = 'flex min-w-0 items-center gap-3 px-4 py-2.5';
105
+ return (_jsx("li", { children: href ? (_jsx(Link, { href: href, className: cn(row, 'hover:bg-hover transition-colors'), children: body })) : (_jsx("div", { className: row, children: body })) }));
106
+ }
107
+ function LoadingRows() {
108
+ return (_jsx("div", { className: "flex flex-col gap-2", children: [0, 1, 2].map((i) => (_jsx(Skeleton, { className: "h-10 w-full rounded-md" }, i))) }));
109
+ }
110
+ function Failed({ onRetry }) {
111
+ const t = useTranslations('spaces');
112
+ return (_jsx(ErrorState, { size: "sm", title: t('loadError'), action: _jsx(Button, { size: "sm", variant: "outline", onClick: onRetry, children: t('retry') }) }));
113
+ }
114
+ const filtered = (href, slug) => (href ? `${href}?space=${encodeURIComponent(slug)}` : null);
115
+ function GoalsTab({ projectId, slug }) {
116
+ const t = useTranslations('spaces');
117
+ const agents = useProjectConfig(projectId)?.agents ?? [];
118
+ const goals = useProjectGoals(projectId);
119
+ const rows = (goals.data ?? []).filter((goal) => bindingSpace(goal.goal, agents) === slug);
120
+ return (_jsx(ListFrame, { children: goals.isError ? (_jsx(Failed, { onRetry: () => goals.refetch() })) : goals.isLoading ? (_jsx(LoadingRows, {})) : rows.length === 0 ? (_jsx(EmptyState, { size: "sm", title: t('empty.goals') })) : (_jsxs(_Fragment, { children: [_jsx(Rows, { children: rows.map((goal) => (_jsx(Row, { href: goalHref(projectId, goal), mark: _jsx(GoalHealthDot, { goal: goal }), children: goal.goal?.objective ?? goal.slug }, `${goal.scope}/${goal.slug}`))) }), _jsx(ViewAll, { href: filtered(uiRoutes().goals(projectId), slug) })] })) }));
121
+ }
122
+ function AppsTab({ projectId, slug }) {
123
+ const t = useTranslations('spaces');
124
+ const tApps = useTranslations('hardcodedUi.i18nComplete');
125
+ const agents = useProjectConfig(projectId)?.agents ?? [];
126
+ const apps = useProjectApps(projectId);
127
+ const appsHref = uiRoutes().apps(projectId);
128
+ const rows = (apps.data ?? []).filter((app) => bindingSpace(app.display, agents) === slug);
129
+ return (_jsx(ListFrame, { children: apps.isError ? (_jsx(Failed, { onRetry: () => apps.refetch() })) : apps.isLoading ? (_jsx(LoadingRows, {})) : rows.length === 0 ? (_jsx(EmptyState, { size: "sm", title: t('empty.apps') })) : (_jsx(Rows, { children: rows.map((app) => (_jsx(Row, { href: appsHref ? `${appsHref}?app=${encodeURIComponent(app.app_id)}` : null, mark: _jsx("span", { className: cn('inline-block size-2 shrink-0 rounded-full', appStatus(app, tApps).dot) }), meta: appStatus(app, tApps).label, children: app.name }, app.app_id))) })) }));
130
+ }
131
+ function ArtifactsTab({ projectId, slug }) {
132
+ const t = useTranslations('spaces');
133
+ const agents = useProjectConfig(projectId)?.agents ?? [];
134
+ const list = useArtifacts(projectId, { space: slug, agents: agentsInSpace(slug, agents), limit: 50 });
135
+ const href = uiRoutes().artifacts(projectId);
136
+ const rows = list.data ?? [];
137
+ return (_jsx(ListFrame, { children: list.isError ? (_jsx(Failed, { onRetry: () => list.refetch() })) : list.isLoading ? (_jsx(LoadingRows, {})) : rows.length === 0 ? (_jsx(EmptyState, { size: "sm", title: t('empty.artifacts') })) : (_jsxs(_Fragment, { children: [_jsx(Rows, { children: rows.map((artifact) => (_jsx(Row, { href: href ? `${href}/${artifact.artifact_id}` : null, mark: _jsx(FileTextIcon, { className: "text-muted-foreground size-4 shrink-0" }), meta: artifact.type === 'doc' ? t('doc') : t('page'), children: artifact.title }, artifact.artifact_id))) }), _jsx(ViewAll, { href: filtered(href, slug) })] })) }));
138
+ }
139
+ /** One project folder: folders open in place, files open in the file viewer. */
140
+ function FilesTab({ projectId, root }) {
141
+ const t = useTranslations('spaces');
142
+ const clean = root.replace(/^\/+|\/+$/g, '');
143
+ const [path, setPath] = useState(clean);
144
+ const openPreview = useFilePreviewStore((state) => state.openPreview);
145
+ const listing = useQuery({
146
+ queryKey: [...qk.project.files(projectId), 'space-folder', path],
147
+ queryFn: () => listProjectDirectory(projectId, { path: path || undefined }),
148
+ retry: false,
149
+ });
150
+ const entries = [...(listing.data?.entries ?? [])].sort((a, b) => (a.type === b.type ? a.path.localeCompare(b.path) : a.type === 'directory' ? -1 : 1));
151
+ const parent = path === clean ? null : path.split('/').slice(0, -1).join('/');
152
+ const name = (entry) => entry.split('/').at(-1) ?? entry;
153
+ return (_jsxs(ListFrame, { children: [_jsx("p", { className: "text-muted-foreground truncate font-mono text-xs", children: path || '/' }), listing.isError ? (_jsx(Failed, { onRetry: () => listing.refetch() })) : listing.isLoading ? (_jsx(LoadingRows, {})) : (_jsxs(Rows, { children: [parent !== null ? (_jsx(FolderRow, { onOpen: () => setPath(parent), icon: _jsx(FolderSimpleIcon, { className: "text-muted-foreground size-4 shrink-0" }), children: ".." })) : null, entries.length === 0 ? (_jsx("li", { className: "text-muted-foreground px-4 py-2.5 text-sm", children: t('empty.folder') })) : (entries.map((entry) => (_jsx(FolderRow, { onOpen: () => (entry.type === 'directory' ? setPath(entry.path) : openPreview(entry.path)), icon: entry.type === 'directory' ? (_jsx(FolderSimpleIcon, { className: "text-muted-foreground size-4 shrink-0" })) : (_jsx(FileTextIcon, { className: "text-muted-foreground size-4 shrink-0" })), children: name(entry.path) }, entry.path))))] }))] }));
154
+ }
155
+ function FolderRow({ onOpen, icon, children }) {
156
+ return (_jsx("li", { children: _jsxs("button", { type: "button", onClick: onOpen, className: "hover:bg-hover flex w-full min-w-0 items-center gap-3 px-4 py-2.5 text-left transition-colors", children: [icon, _jsx("span", { className: "text-foreground min-w-0 flex-1 truncate text-sm", children: children })] }) }));
157
+ }
158
+ function BoardTab({ projectId, tab }) {
159
+ const t = useTranslations('spaces');
160
+ const blocks = tab.blocks ?? [];
161
+ if (!blocks.length) {
162
+ return (_jsx(Centered, { children: _jsx(EmptyState, { size: "sm", title: t('empty.board'), description: t('empty.boardHint') }) }));
163
+ }
164
+ return (_jsx("div", { className: "w-full max-w-6xl px-5 py-5 pb-20", children: _jsx(SpaceBlocks, { projectId: projectId, blocks: blocks }) }));
165
+ }
166
+ /** A pinned App, live and interactive, filling the tab. */
167
+ function AppTab({ projectId, slug }) {
168
+ const t = useTranslations('spaces');
169
+ const apps = useProjectApps(projectId);
170
+ const app = apps.data?.find((candidate) => candidate.slug === slug);
171
+ const live = !!app && !!app.active_deployment_id && appCan(app, 'preview') && app.viewer_can_access !== false;
172
+ const access = useAppAccess(projectId, live && app ? app.app_id : null, { policy: false, session: live });
173
+ if (apps.isLoading)
174
+ return _jsx(Centered, { children: _jsx(Skeleton, { className: "h-64 w-full max-w-4xl rounded-md" }) });
175
+ if (!app) {
176
+ return (_jsx(Centered, { children: _jsx(EmptyState, { size: "sm", title: t('missing.app', { slug }) }) }));
177
+ }
178
+ return (_jsx(AppPreview, { app: app, url: access.session.data?.url ?? null, accessError: access.session.isError, interactive: true, className: "h-full" }));
179
+ }
180
+ /** A pinned Artifact, its current state in a sandboxed frame. */
181
+ function ArtifactTab({ projectId, artifactId }) {
182
+ const t = useTranslations('spaces');
183
+ const artifact = useArtifact(projectId, artifactId);
184
+ const href = uiRoutes().artifacts(projectId);
185
+ if (artifact.isLoading)
186
+ return _jsx(Centered, { children: _jsx(Skeleton, { className: "h-64 w-full max-w-4xl rounded-md" }) });
187
+ if (!artifact.data) {
188
+ return (_jsx(Centered, { children: _jsx(EmptyState, { size: "sm", title: t('missing.artifact') }) }));
189
+ }
190
+ return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "border-border flex shrink-0 items-center gap-2 border-b px-5 py-1.5", children: [_jsx("span", { className: "text-foreground min-w-0 flex-1 truncate text-sm font-medium", children: artifact.data.title }), href ? (_jsx(Button, { asChild: true, size: "sm", variant: "ghost", children: _jsxs(Link, { href: `${href}/${artifact.data.artifact_id}`, children: [_jsx(ArrowSquareOutIcon, {}), t('openArtifact')] }) })) : null] }), _jsx("iframe", { src: artifact.data.view_url, title: artifact.data.title, sandbox: ARTIFACT_SANDBOX, className: "bg-background min-h-0 w-full flex-1" })] }));
191
+ }
192
+ /** A link: embedded in a sandboxed frame, or a card that opens it. */
193
+ function LinkTab({ tab }) {
194
+ const t = useTranslations('spaces');
195
+ const url = tab.url ?? '';
196
+ const safe = /^https?:\/\//i.test(url);
197
+ if (safe && tab.embed) {
198
+ return (_jsx("iframe", { src: url, title: tab.label || hostOf(url),
199
+ // As a board's iframe block: a Kortix origin gets an opaque origin (space-blocks.tsx).
200
+ sandbox: framePolicy('app', url).sandbox, className: "bg-background h-full w-full" }));
201
+ }
202
+ return (_jsx(Centered, { children: _jsx(EmptyState, { size: "sm", title: tab.label || hostOf(url), description: _jsx("span", { className: "font-mono wrap-anywhere", children: url }), action: safe ? (_jsx(Button, { asChild: true, size: "sm", variant: "outline", children: _jsxs("a", { href: url, target: "_blank", rel: "noopener noreferrer", children: [_jsx(ArrowSquareOutIcon, {}), t('openLink', { host: hostOf(url) })] }) })) : null }) }));
203
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Space templates and the pure `kortix.yaml` edits that create a space and
3
+ * set its tabs. A space is `spaces.<slug>` (see `ManifestSpace` in
4
+ * `@kortix/sdk`). Every edit round-trips through the `yaml` document model,
5
+ * so comments and the rest of the manifest stay as they were. Each edit rewrites
6
+ * every deprecated shape (`fixManifestText`): a Kortix write saves the latest shape.
7
+ */
8
+ import { type SpaceTab } from '@kortix/sdk';
9
+ export interface SpaceTemplate {
10
+ /** Also the catalog key of its name and hint: `spaces.templates.<id>`. */
11
+ id: 'standard' | 'room' | 'board';
12
+ /** The tabs after the room. */
13
+ tabs: SpaceTab[];
14
+ }
15
+ /** The presets the New space dialog offers, in order. The first is the default. */
16
+ export declare function spaceTemplates(t: (key: 'tabs.board' | 'templates.board.brief' | 'templates.board.text') => string): SpaceTemplate[];
17
+ export declare const SPACE_TEMPLATES: SpaceTemplate[];
18
+ /** Turn a space name into a `spaces:` key. The result is also a valid room
19
+ * name (the space's room is the room with its slug): at most 63 characters,
20
+ * starting with a letter or a digit. */
21
+ export declare function slugifySpace(name: string): string;
22
+ /** Add `spaces.<slug>` to a `kortix.yaml` text. Returns the new text. */
23
+ export declare function addSpaceToManifest(yamlText: string, input: {
24
+ slug: string;
25
+ label: string;
26
+ description?: string;
27
+ tabs: SpaceTab[];
28
+ }): string;
29
+ /** Replace `spaces.<slug>.tabs` in a `kortix.yaml` text, declaring the space
30
+ * when only an agent names it. Returns the new text. */
31
+ export declare function setSpaceTabs(yamlText: string, slug: string, tabs: SpaceTab[]): string;
32
+ /** Append one tab to `spaces.<slug>.tabs` as the file has it now. A space
33
+ * with no `tabs` shows the default set, so the new list starts from it. */
34
+ export declare function appendSpaceTab(yamlText: string, slug: string, tab: SpaceTab): string;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Space templates and the pure `kortix.yaml` edits that create a space and
3
+ * set its tabs. A space is `spaces.<slug>` (see `ManifestSpace` in
4
+ * `@kortix/sdk`). Every edit round-trips through the `yaml` document model,
5
+ * so comments and the rest of the manifest stay as they were. Each edit rewrites
6
+ * every deprecated shape (`fixManifestText`): a Kortix write saves the latest shape.
7
+ */
8
+ import { fixManifestText } from '../../_vendor/kortix-shared.js';
9
+ import { isSeq, parseDocument } from 'yaml';
10
+ import { DEFAULT_SPACE_TABS } from '@kortix/sdk';
11
+ import { createTranslator, defaultUiMessages } from '../../i18n/index.js';
12
+ /** The presets the New space dialog offers, in order. The first is the default. */
13
+ export function spaceTemplates(t) {
14
+ return [
15
+ {
16
+ id: 'standard',
17
+ tabs: [...DEFAULT_SPACE_TABS],
18
+ },
19
+ {
20
+ id: 'room',
21
+ tabs: [],
22
+ },
23
+ {
24
+ id: 'board',
25
+ tabs: [
26
+ { type: 'board', label: t('tabs.board'), blocks: [{ type: 'text', label: t('templates.board.brief'), text: t('templates.board.text') }] },
27
+ { type: 'goals' },
28
+ ],
29
+ },
30
+ ];
31
+ }
32
+ export const SPACE_TEMPLATES = spaceTemplates(createTranslator({ locale: 'en', messages: defaultUiMessages, namespace: 'spaces' }));
33
+ /** Turn a space name into a `spaces:` key. The result is also a valid room
34
+ * name (the space's room is the room with its slug): at most 63 characters,
35
+ * starting with a letter or a digit. */
36
+ export function slugifySpace(name) {
37
+ const trim = (value) => value.replace(/^[-_]+|[-_]+$/g, '');
38
+ return (trim(trim(name
39
+ .toLowerCase()
40
+ .replace(/[^a-z0-9_-]+/g, '-')
41
+ .replace(/-{2,}/g, '-')).slice(0, 63)) || 'space');
42
+ }
43
+ function editManifest(yamlText, edit) {
44
+ // The line, not the key: a comment above it stays.
45
+ const doc = parseDocument(fixManifestText(yamlText).text);
46
+ edit(doc);
47
+ return doc.toString();
48
+ }
49
+ /** Add `spaces.<slug>` to a `kortix.yaml` text. Returns the new text. */
50
+ export function addSpaceToManifest(yamlText, input) {
51
+ const description = input.description?.trim();
52
+ return editManifest(yamlText, (doc) => doc.setIn(['spaces', input.slug], {
53
+ label: input.label,
54
+ ...(description ? { description } : {}),
55
+ tabs: input.tabs,
56
+ }));
57
+ }
58
+ /** Replace `spaces.<slug>.tabs` in a `kortix.yaml` text, declaring the space
59
+ * when only an agent names it. Returns the new text. */
60
+ export function setSpaceTabs(yamlText, slug, tabs) {
61
+ return editManifest(yamlText, (doc) => doc.setIn(['spaces', slug, 'tabs'], tabs));
62
+ }
63
+ /** Append one tab to `spaces.<slug>.tabs` as the file has it now. A space
64
+ * with no `tabs` shows the default set, so the new list starts from it. */
65
+ export function appendSpaceTab(yamlText, slug, tab) {
66
+ return editManifest(yamlText, (doc) => {
67
+ const current = doc.getIn(['spaces', slug, 'tabs']);
68
+ const tabs = isSeq(current) ? current.toJSON() : [...DEFAULT_SPACE_TABS];
69
+ doc.setIn(['spaces', slug, 'tabs'], [...tabs, tab]);
70
+ });
71
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The space a list page (Goals, Artifacts) filters to: the `?space=` param
3
+ * (a space home's "View all" link), else the active space, else
4
+ * `ALL_SPACES`. A value that names no space of the project (a removed space
5
+ * still stored as active) is `ALL_SPACES`. `PROJECT_WIDE_SPACE` selects
6
+ * the project-wide items. Choosing one makes it the active space and drops
7
+ * the param, so the sidebar, the home and the page agree. With the spaces
8
+ * flag off (`project_channels`) it is always `ALL_SPACES`.
9
+ */
10
+ export declare function useSpaceFilter(projectId: string): [string, (value: string) => void];
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { PROJECT_WIDE_SPACE, listSpaces } from '@kortix/sdk';
3
+ import { useProjectConfig } from '@kortix/sdk/react';
4
+ import { ALL_SPACES } from '../../customize/shared/catalog/catalog-space-tabs.js';
5
+ import { useActiveSpace } from '../../internal/stores/active-space-store.js';
6
+ import { useUiPathname, useUiRouter, useUiSearchParams } from '../../providers/ui-provider.js';
7
+ import { useSpacesEnabled } from '../../internal/lib/space-scope.js';
8
+ /**
9
+ * The space a list page (Goals, Artifacts) filters to: the `?space=` param
10
+ * (a space home's "View all" link), else the active space, else
11
+ * `ALL_SPACES`. A value that names no space of the project (a removed space
12
+ * still stored as active) is `ALL_SPACES`. `PROJECT_WIDE_SPACE` selects
13
+ * the project-wide items. Choosing one makes it the active space and drops
14
+ * the param, so the sidebar, the home and the page agree. With the spaces
15
+ * flag off (`project_channels`) it is always `ALL_SPACES`.
16
+ */
17
+ export function useSpaceFilter(projectId) {
18
+ const [active, setActive] = useActiveSpace(projectId);
19
+ const config = useProjectConfig(projectId);
20
+ const searchParams = useUiSearchParams();
21
+ const router = useUiRouter();
22
+ const pathname = useUiPathname();
23
+ const spacesOn = useSpacesEnabled(projectId);
24
+ const param = searchParams.get('space');
25
+ const raw = param || active || ALL_SPACES;
26
+ const known = raw === ALL_SPACES ||
27
+ raw === PROJECT_WIDE_SPACE ||
28
+ !config ||
29
+ listSpaces(config).some((space) => space.name === raw);
30
+ const value = spacesOn && known ? raw : ALL_SPACES;
31
+ const onChange = (next) => {
32
+ // Project-wide is a filter of this page, not a space to make active.
33
+ setActive(next === ALL_SPACES || next === PROJECT_WIDE_SPACE ? null : next);
34
+ if (next === PROJECT_WIDE_SPACE)
35
+ router.replace(`${pathname}?space=${PROJECT_WIDE_SPACE}`);
36
+ else if (param)
37
+ router.replace(pathname);
38
+ };
39
+ return [value, onChange];
40
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Edit the project's `kortix.yaml` on its default branch: read the file,
3
+ * apply `change` to its text, write it back against the revision it read (a
4
+ * concurrent edit answers 409 instead of being overwritten), then refetch the
5
+ * config. Each call is one commit, the same write My Kortix makes through a
6
+ * change request.
7
+ */
8
+ export declare function useManifestWrite(projectId: string): (change: (yamlText: string) => string) => Promise<void>;
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+ import { useQueryClient } from '@tanstack/react-query';
3
+ import { getProjectDetail, readProjectFile, writeProjectFile } from '@kortix/sdk';
4
+ import { qk } from '@kortix/sdk/react';
5
+ /**
6
+ * Edit the project's `kortix.yaml` on its default branch: read the file,
7
+ * apply `change` to its text, write it back against the revision it read (a
8
+ * concurrent edit answers 409 instead of being overwritten), then refetch the
9
+ * config. Each call is one commit, the same write My Kortix makes through a
10
+ * change request.
11
+ */
12
+ export function useManifestWrite(projectId) {
13
+ const queryClient = useQueryClient();
14
+ return async (change) => {
15
+ const detail = await queryClient.fetchQuery({
16
+ queryKey: qk.project.detail(projectId),
17
+ queryFn: () => getProjectDetail(projectId),
18
+ });
19
+ const path = detail.config?.manifest_health?.path || detail.project.manifest_path || 'kortix.yaml';
20
+ const ref = detail.project.default_branch || 'main';
21
+ const file = await readProjectFile(projectId, path, ref);
22
+ if (!file.revision)
23
+ throw new Error(`Could not read ${path}.`);
24
+ await writeProjectFile(projectId, { path, ref, content: change(file.content), expected_revision: file.revision });
25
+ await queryClient.invalidateQueries({ queryKey: qk.project.detail(projectId) });
26
+ };
27
+ }
@@ -1,4 +1,4 @@
1
- import { capitalizeWords, isMetaAgentName, META_AGENT_DISPLAY_NAME } from '../../_vendor/kortix-shared.js';
1
+ import { capitalizeWords, isMyKortixAgentName, MY_KORTIX_DISPLAY_NAME } from '../../_vendor/kortix-shared.js';
2
2
  import { relativeTime } from '../../internal/lib/relative-time.js';
3
3
  import { sessionDisplayLabel, sessionDisplayStatus } from '../../session/actions/session-label.js';
4
4
  import { parseAgentMentionReferences, parseFileMentionReferences, parseFileReferences, parseSessionReferences, stripReplyContexts, } from '../../session/thread/message-parsing.js';
@@ -105,7 +105,7 @@ export function firstPromptTruncated(session) {
105
105
  export const DEFAULT_AGENT_SLUG = 'kortix';
106
106
  /** An agent's display name: the sidebar's DM row and the space view say it the same way. */
107
107
  export function agentLabel(name) {
108
- return isMetaAgentName(name) ? META_AGENT_DISPLAY_NAME : capitalizeWords(name);
108
+ return isMyKortixAgentName(name) ? MY_KORTIX_DISPLAY_NAME : capitalizeWords(name);
109
109
  }
110
110
  /**
111
111
  * Who is in a space, as far as its loaded threads tell: the people who