@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
@@ -26,16 +26,23 @@ export declare function newArrivals(seen: ReadonlySet<string> | null, rows: read
26
26
  seen: Set<string>;
27
27
  };
28
28
  /**
29
- * How new rows reach a person who is looking at this window: a toast for each
30
- * (at most `MAX_ARRIVAL_ALERTS`), or, when `os` (the window is in the
31
- * background, browser notifications are on and granted, and this renderer has
32
- * no Web Push), an OS notification instead. A row about the session on screen
33
- * is skipped. So is a finished turn the live stream already announced
34
- * (`unseen`); a later question, permission request or error in that session
35
- * is not.
29
+ * How new rows reach a person, at most `MAX_ARRIVAL_ALERTS` per poll. A finished
30
+ * turn the live stream already announced (`unseen`) is dropped on both paths; a
31
+ * later question, permission request or error in that session is not.
32
+ *
33
+ * When `os` (the window is in the background, browser notifications are on and
34
+ * granted, and this renderer has no Web Push), every other row goes to the OS
35
+ * path: `sendWebNotification` applies the channel policy to it.
36
+ *
37
+ * Otherwise each row toasts, except a row of any kind about the session on
38
+ * screen, and a row about a project other than the one on screen.
39
+ * `showInAppNotification` applies no policy, so both filters live here. They
40
+ * run before the cap, so a row that never toasts takes no slot from a row that
41
+ * does.
36
42
  */
37
43
  export declare function planArrivals(fresh: readonly InboxNotification[], context: {
38
44
  onScreen: (sessionId: string) => boolean;
45
+ otherProject: (projectId: string | null) => boolean;
39
46
  unseen: readonly string[];
40
47
  os: boolean;
41
48
  }): {
@@ -35,22 +35,27 @@ export function newArrivals(seen, rows) {
35
35
  return { fresh: rows.filter((row) => !row.read && !seen.has(row.id)), seen: next };
36
36
  }
37
37
  /**
38
- * How new rows reach a person who is looking at this window: a toast for each
39
- * (at most `MAX_ARRIVAL_ALERTS`), or, when `os` (the window is in the
40
- * background, browser notifications are on and granted, and this renderer has
41
- * no Web Push), an OS notification instead. A row about the session on screen
42
- * is skipped. So is a finished turn the live stream already announced
43
- * (`unseen`); a later question, permission request or error in that session
44
- * is not.
38
+ * How new rows reach a person, at most `MAX_ARRIVAL_ALERTS` per poll. A finished
39
+ * turn the live stream already announced (`unseen`) is dropped on both paths; a
40
+ * later question, permission request or error in that session is not.
41
+ *
42
+ * When `os` (the window is in the background, browser notifications are on and
43
+ * granted, and this renderer has no Web Push), every other row goes to the OS
44
+ * path: `sendWebNotification` applies the channel policy to it.
45
+ *
46
+ * Otherwise each row toasts, except a row of any kind about the session on
47
+ * screen, and a row about a project other than the one on screen.
48
+ * `showInAppNotification` applies no policy, so both filters live here. They
49
+ * run before the cap, so a row that never toasts takes no slot from a row that
50
+ * does.
45
51
  */
46
52
  export function planArrivals(fresh, context) {
47
53
  const unseen = new Set(context.unseen);
48
- const announce = fresh
49
- .filter((row) => !row.session_id ||
50
- (!context.onScreen(row.session_id) &&
51
- !(row.kind === 'turn_done' && unseen.has(row.session_id))))
52
- .slice(0, MAX_ARRIVAL_ALERTS);
53
- return context.os ? { toast: [], os: announce } : { toast: announce, os: [] };
54
+ const announce = fresh.filter((row) => !(row.session_id && row.kind === 'turn_done' && unseen.has(row.session_id)));
55
+ if (context.os)
56
+ return { toast: [], os: announce.slice(0, MAX_ARRIVAL_ALERTS) };
57
+ const toast = announce.filter((row) => !(row.session_id && context.onScreen(row.session_id)) && !context.otherProject(row.project_id));
58
+ return { toast: toast.slice(0, MAX_ARRIVAL_ALERTS), os: [] };
54
59
  }
55
60
  /** The in-page notification type: the push `type` of the kind. */
56
61
  export function webNotificationType(row) {
@@ -77,7 +82,9 @@ export function rowDestination(row) {
77
82
  return 'room';
78
83
  if (row.session_id)
79
84
  return 'session';
80
- return new URL(row.url, 'http://kortix.invalid').pathname.endsWith('/reminders') ? 'reminders' : 'triggers';
85
+ const path = new URL(row.url, 'http://kortix.invalid').pathname;
86
+ // `/admin/loops` since 2026-10-28; a row stored before carries `/reminders`.
87
+ return path.endsWith('/admin/loops') || path.endsWith('/reminders') ? 'reminders' : 'triggers';
81
88
  }
82
89
  /** The message `public/sw.js` posts to a tab already on a clicked notification's page. */
83
90
  export const NOTIFICATION_OPEN_MESSAGE = 'kortix:notification-open';
@@ -2,12 +2,12 @@
2
2
  export declare function SessionFailedCard({ title, label, detail, openLabel, onOpen, onDismiss, }: {
3
3
  /** "Session error". */
4
4
  title: string;
5
- /** The session's name — only when it is not the one on screen. */
5
+ /** The session's name. `/debug/toasts` draws the card without it. */
6
6
  label?: string;
7
7
  /** The sentence the transcript's error row shows. */
8
8
  detail?: string;
9
9
  openLabel: string;
10
- /** Absent for the session on screen: there is nowhere to go. */
10
+ /** Opens the session. `/debug/toasts` draws the card without it. */
11
11
  onOpen?: () => void;
12
12
  onDismiss: () => void;
13
13
  }): import("react").JSX.Element;
@@ -22,5 +22,9 @@ export declare function soonestFire(reminders: readonly Pick<SessionReminder, 's
22
22
  export declare function elapsedShare(reminder: Pick<SessionReminder, 'next_fire_at' | 'every_seconds' | 'last_fired_at' | 'created_at'>, now: number): number | null;
23
23
  /** The first line of the reminder text, for a one-line row title. */
24
24
  export declare function reminderTitle(reminder: Pick<SessionReminder, 'name' | 'prompt'>): string;
25
- /** "Cron 0 9 * * * Europe/Berlin", "Every 1h" or "Once"; `t` is the `reminders` translator. */
26
- export declare function scheduleLabel(reminder: Pick<SessionReminder, 'cron' | 'timezone' | 'every'>, t: (key: 'cron' | 'every' | 'once', values?: Record<string, string>) => string): string;
25
+ /**
26
+ * "Cron 0 9 * * * Europe/Berlin", "Every 1h", "Once", or "On an event" for a
27
+ * session-target trigger a webhook, connector or App event, or merge fires;
28
+ * `t` is the `reminders` translator.
29
+ */
30
+ export declare function scheduleLabel(reminder: Pick<SessionReminder, 'cron' | 'timezone' | 'every' | 'source_type'>, t: (key: 'cron' | 'every' | 'once' | 'onEvent', values?: Record<string, string>) => string): string;
@@ -82,8 +82,14 @@ export function elapsedShare(reminder, now) {
82
82
  export function reminderTitle(reminder) {
83
83
  return reminder.name ?? reminder.prompt.split('\n')[0].trim();
84
84
  }
85
- /** "Cron 0 9 * * * Europe/Berlin", "Every 1h" or "Once"; `t` is the `reminders` translator. */
85
+ /**
86
+ * "Cron 0 9 * * * Europe/Berlin", "Every 1h", "Once", or "On an event" for a
87
+ * session-target trigger a webhook, connector or App event, or merge fires;
88
+ * `t` is the `reminders` translator.
89
+ */
86
90
  export function scheduleLabel(reminder, t) {
91
+ if (reminder.source_type && reminder.source_type !== 'schedule')
92
+ return t('onEvent');
87
93
  if (reminder.cron)
88
94
  return t('cron', { expression: [reminder.cron, reminder.timezone ?? ''].join(' ').trim() });
89
95
  return reminder.every ? t('every', { period: reminder.every }) : t('once');
@@ -0,0 +1,35 @@
1
+ /** @internal Kortix apps only. No semver: it may change in any release. */
2
+ /**
3
+ * The space the user is working inside, per project. `null` = no space (no
4
+ * scope: every space plus the Project-wide bucket). A space slug scopes
5
+ * Customize (and the surfaces that opt in) to that one space's agents,
6
+ * connectors, triggers, reminders and skills. Purely a per-viewer UI context
7
+ * (which space am I looking at) — it is NOT project config, so it lives in
8
+ * localStorage only and never touches `kortix.yaml`.
9
+ */
10
+ type ActiveByProject = Record<string, string | null>;
11
+ interface ActiveSpaceState {
12
+ byProject: ActiveByProject;
13
+ setSpace: (projectId: string, space: string | null) => void;
14
+ }
15
+ export declare const useActiveSpaceStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<ActiveSpaceState>, "setState" | "persist"> & {
16
+ setState(partial: ActiveSpaceState | Partial<ActiveSpaceState> | ((state: ActiveSpaceState) => ActiveSpaceState | Partial<ActiveSpaceState>), replace?: false | undefined): unknown;
17
+ setState(state: ActiveSpaceState | ((state: ActiveSpaceState) => ActiveSpaceState), replace: true): unknown;
18
+ persist: {
19
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<ActiveSpaceState, unknown, unknown>>) => void;
20
+ clearStorage: () => void;
21
+ rehydrate: () => Promise<void> | void;
22
+ hasHydrated: () => boolean;
23
+ onHydrate: (fn: (state: ActiveSpaceState) => void) => () => void;
24
+ onFinishHydration: (fn: (state: ActiveSpaceState) => void) => () => void;
25
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<ActiveSpaceState, unknown, unknown>>;
26
+ };
27
+ }>;
28
+ /**
29
+ * The active space for a project (`null` = All), and a setter for it. Spaces
30
+ * are Work in progress under the `project_channels` flag (`SPACES_FLAG` in
31
+ * internal/lib/space-scope.ts): off, a stored space reads as `null`, so no
32
+ * surface scopes to a space. The stored value stays for when the flag is on.
33
+ */
34
+ export declare function useActiveSpace(projectId: string): [string | null, (space: string | null) => void];
35
+ export {};
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+ import { create } from 'zustand';
3
+ import { persist } from 'zustand/middleware';
4
+ import { useSpacesEnabled } from '../lib/space-scope.js';
5
+ import { createSafeJSONStorage } from '../lib/storage/managed-storage.js';
6
+ import { registerPersistedStore, resetPersistedStore } from './persisted-store-registry.js';
7
+ const STORAGE_KEY = 'kortix.active-space';
8
+ export const useActiveSpaceStore = create()(persist((set) => ({
9
+ byProject: {},
10
+ setSpace: (projectId, space) => set((state) => ({ byProject: { ...state.byProject, [projectId]: space } })),
11
+ }), {
12
+ name: STORAGE_KEY,
13
+ storage: createSafeJSONStorage(),
14
+ version: 1,
15
+ partialize: (state) => ({ byProject: state.byProject }),
16
+ }));
17
+ registerPersistedStore(STORAGE_KEY, () => resetPersistedStore(useActiveSpaceStore));
18
+ /**
19
+ * The active space for a project (`null` = All), and a setter for it. Spaces
20
+ * are Work in progress under the `project_channels` flag (`SPACES_FLAG` in
21
+ * internal/lib/space-scope.ts): off, a stored space reads as `null`, so no
22
+ * surface scopes to a space. The stored value stays for when the flag is on.
23
+ */
24
+ export function useActiveSpace(projectId) {
25
+ const spacesOn = useSpacesEnabled(projectId || null);
26
+ const space = useActiveSpaceStore((state) => state.byProject[projectId] ?? null);
27
+ const setSpace = useActiveSpaceStore((state) => state.setSpace);
28
+ return [spacesOn ? space : null, (next) => setSpace(projectId, next)];
29
+ }
@@ -314,28 +314,37 @@ export const useKortixComputerStore = create()(devtools((set, get) => ({
314
314
  // invariant instead of a patch: this is the single point where
315
315
  // "does this session have detail content" changes, so there is no
316
316
  // second route into the broken state to remember later.
317
+ //
318
+ // It closes the side panel itself, not only `detailOpen`: the layout
319
+ // shows the right side on `isSidePanelOpen` alone, so a lone
320
+ // `detailOpen` reset left it open and white. Not `setIsSidePanelOpen`:
321
+ // the person did not close it, so the panel memory stays and the
322
+ // provider's arrival restore reopens what it showed.
317
323
  const losingDetail = has === null || has === false;
318
324
  const isActive = get()._activeSessionId === sessionId;
319
325
  const closeDetail = losingDetail && isActive && get().detailOpen;
326
+ const closePatch = closeDetail
327
+ ? { ...CLOSED_PANEL_PATCH, detailOpen: false, skipNextExpandAnimation: true }
328
+ : {};
320
329
  if (has === null) {
321
330
  if (!(sessionId in map)) {
322
331
  if (closeDetail)
323
- set({ detailOpen: false });
332
+ set(closePatch);
324
333
  return;
325
334
  }
326
335
  const next = { ...map };
327
336
  delete next[sessionId];
328
- set({ _detailContentBySession: next, ...(closeDetail ? { detailOpen: false } : {}) });
337
+ set({ _detailContentBySession: next, ...closePatch });
329
338
  return;
330
339
  }
331
340
  if (map[sessionId] === has) {
332
341
  if (closeDetail)
333
- set({ detailOpen: false });
342
+ set(closePatch);
334
343
  return;
335
344
  }
336
345
  set({
337
346
  _detailContentBySession: { ...map, [sessionId]: has },
338
- ...(closeDetail ? { detailOpen: false } : {}),
347
+ ...closePatch,
339
348
  });
340
349
  },
341
350
  openSidePanel: () => {
@@ -0,0 +1,26 @@
1
+ /** @internal Kortix apps only. No semver: it may change in any release. */
2
+ /**
3
+ * The agents each person pins to the sidebar's Customize, per project. A
4
+ * view preference of this browser, like the session list's: nothing in the
5
+ * project's config changes. No pins: Customize shows the first agents.
6
+ */
7
+ interface PinnedAgentsState {
8
+ byProject: Record<string, string[]>;
9
+ togglePinned: (projectId: string, agent: string) => void;
10
+ }
11
+ export declare const usePinnedAgentsStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<PinnedAgentsState>, "setState" | "persist"> & {
12
+ setState(partial: PinnedAgentsState | Partial<PinnedAgentsState> | ((state: PinnedAgentsState) => PinnedAgentsState | Partial<PinnedAgentsState>), replace?: false | undefined): unknown;
13
+ setState(state: PinnedAgentsState | ((state: PinnedAgentsState) => PinnedAgentsState), replace: true): unknown;
14
+ persist: {
15
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<PinnedAgentsState, unknown, unknown>>) => void;
16
+ clearStorage: () => void;
17
+ rehydrate: () => Promise<void> | void;
18
+ hasHydrated: () => boolean;
19
+ onHydrate: (fn: (state: PinnedAgentsState) => void) => () => void;
20
+ onFinishHydration: (fn: (state: PinnedAgentsState) => void) => () => void;
21
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<PinnedAgentsState, unknown, unknown>>;
22
+ };
23
+ }>;
24
+ /** The agents pinned in this project, in pin order. */
25
+ export declare function usePinnedAgents(projectId: string): string[];
26
+ export {};
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+ import { create } from 'zustand';
3
+ import { persist } from 'zustand/middleware';
4
+ import { createSafeJSONStorage } from '../lib/storage/managed-storage.js';
5
+ import { registerPersistedStore, resetPersistedStore } from './persisted-store-registry.js';
6
+ const STORAGE_KEY = 'kortix.pinned-agents';
7
+ const EMPTY = [];
8
+ export const usePinnedAgentsStore = create()(persist((set, get) => ({
9
+ byProject: {},
10
+ togglePinned: (projectId, agent) => {
11
+ const current = get().byProject[projectId] ?? EMPTY;
12
+ const next = current.includes(agent) ? current.filter((name) => name !== agent) : [...current, agent];
13
+ set({ byProject: { ...get().byProject, [projectId]: next } });
14
+ },
15
+ }), { name: STORAGE_KEY, storage: createSafeJSONStorage(), partialize: (state) => ({ byProject: state.byProject }) }));
16
+ /** The agents pinned in this project, in pin order. */
17
+ export function usePinnedAgents(projectId) {
18
+ return usePinnedAgentsStore((state) => state.byProject[projectId] ?? EMPTY);
19
+ }
20
+ registerPersistedStore(STORAGE_KEY, () => resetPersistedStore(usePinnedAgentsStore));
@@ -48,6 +48,9 @@ export function rememberedPanelOf({ terminalOpen, detailKey, }) {
48
48
  return { kind: 'view', view: 'browser', target: { url: detailKey.slice(4) } };
49
49
  if (detailKey?.startsWith('file:'))
50
50
  return { kind: 'file', path: detailKey.slice(5) };
51
+ // An artifact opens through the browser request, as a clicked artifact link does.
52
+ if (detailKey?.startsWith('artifact:'))
53
+ return { kind: 'view', view: 'browser', target: { url: detailKey.slice(9) } };
51
54
  return null;
52
55
  }
53
56
  /** The panel to reopen on arrival, or null: only on a running session, with the panel closed, on desktop. */
@@ -1,17 +1,18 @@
1
1
  /** @internal Kortix apps only. No semver: it may change in any release. */
2
2
  /**
3
- * Finished turns the user has not seen yet, per session.
3
+ * Turns the user has not seen yet, per session: finished turns, and failed
4
+ * turns of another project.
4
5
  *
5
6
  * The source of truth for the favicon badge (TurnAttentionBadge): a turn that
6
- * finished while the user was on another tab or another in-app session lands
7
+ * ended while the user was on another tab or another in-app session lands
7
8
  * here, and every entry is dropped the moment that session comes into view.
8
9
  * In-memory on purpose — the toast and the OS notification it complements are
9
10
  * ephemeral too, and the session list has no "unseen" concept to hydrate from.
10
11
  */
11
12
  interface TurnAttentionState {
12
- /** Session ids whose finished turn the user has not seen yet. */
13
+ /** Session ids whose finished or failed turn the user has not seen yet. */
13
14
  unseen: readonly string[];
14
- /** Record a finished turn for a session the user is not looking at. */
15
+ /** Record a finished or failed turn for a session the user is not looking at. */
15
16
  markTurnComplete: (sessionId: string) => void;
16
17
  /** Drop every id the user has now seen (viewed the session or its tab). */
17
18
  markSeen: (sessionIds: readonly string[]) => void;
@@ -28,6 +28,8 @@ export interface UiRoutes {
28
28
  goals: (projectId: string) => string | null;
29
29
  /** The project's artifacts (flag `artifacts`); one is `<artifacts>/<artifact_id>`. */
30
30
  artifacts: (projectId: string) => string | null;
31
+ /** One space: a channel, its room and its tabs (`?tab=` opens one). */
32
+ space: (projectId: string, slug: string) => string | null;
31
33
  members: (projectId: string) => string | null;
32
34
  /** The project settings page, on its sandbox section. */
33
35
  sandboxSettings: (projectId: string) => string | null;
@@ -37,6 +39,12 @@ export interface UiRoutes {
37
39
  * capability root, for example `models` or `triggers?id=<slug>`.
38
40
  */
39
41
  customize: (projectId: string, path?: string) => string | null;
42
+ /**
43
+ * Project admin: the project-wide libraries (connectors, skills, triggers,
44
+ * loops, models, secrets, apps, repo) and settings, one section each.
45
+ * `path` is the section and anything below it (`connectors/<app>`).
46
+ */
47
+ admin: (projectId: string, path?: string) => string | null;
40
48
  /** A channel of the project, by slug (`project_channels` flag). */
41
49
  channel: (projectId: string, slug: string) => string;
42
50
  /** The caller's direct messages with one agent, by agent name (`project_channels` flag). */
@@ -45,7 +53,12 @@ export interface UiRoutes {
45
53
  memory: (projectId: string) => string | null;
46
54
  }
47
55
  export declare const defaultUiRoutes: UiRoutes;
48
- /** Replaces the routes the host passes. Omitted routes keep their default. */
56
+ /**
57
+ * Replaces the routes the host passes. Omitted routes keep their default,
58
+ * except `admin`: a host that maps `customize` (to its own pages, or to null)
59
+ * and says nothing of `admin` gets the same mapping for it, since the
60
+ * libraries left Customize for Project admin (2026-10-27).
61
+ */
49
62
  export declare function setUiRoutes(overrides: Partial<UiRoutes>): void;
50
63
  export declare function uiRoutes(): UiRoutes;
51
64
  /** A channel slug or DM agent name from its URL segment; null when a hand-typed escape is malformed. */
@@ -56,6 +69,8 @@ export declare function decodeSpaceSegment(segment: string): string | null;
56
69
  * the default path instead of breaking their own tabs.
57
70
  */
58
71
  export declare function customizePath(projectId: string, path?: string): string;
72
+ /** A Project admin URL, with the same fallback as `customizePath`. */
73
+ export declare function adminPath(projectId: string, path?: string): string;
59
74
  /**
60
75
  * The session id `pathname` shows, read through the host's `session` route
61
76
  * (so a host URL scheme works), or null when it is not a session page of
@@ -8,18 +8,26 @@ const DEFAULT_ROUTES = {
8
8
  rooms: (p) => `/projects/${p}/rooms`,
9
9
  goals: (p) => `/projects/${p}/goals`,
10
10
  artifacts: (p) => `/projects/${p}/artifacts`,
11
+ space: (p, slug) => `/projects/${p}/spaces/${encodeURIComponent(slug)}`,
11
12
  members: (p) => `/projects/${p}/members`,
12
- sandboxSettings: (p) => `/projects/${p}/config?section=sandbox`,
13
+ sandboxSettings: (p) => `/projects/${p}/admin/sandbox`,
13
14
  customize: (p, path) => `/projects/${p}/customize${path ? `/${path}` : ''}`,
15
+ admin: (p, path) => `/projects/${p}/admin${path ? `/${path}` : ''}`,
14
16
  channel: (p, slug) => `/projects/${p}/c/${slug}`,
15
17
  dm: (p, agentName) => `/projects/${p}/dm/${encodeURIComponent(agentName)}`,
16
18
  memory: (p) => `/projects/${p}/memory`,
17
19
  };
18
20
  export const defaultUiRoutes = DEFAULT_ROUTES;
19
21
  let routes = DEFAULT_ROUTES;
20
- /** Replaces the routes the host passes. Omitted routes keep their default. */
22
+ /**
23
+ * Replaces the routes the host passes. Omitted routes keep their default,
24
+ * except `admin`: a host that maps `customize` (to its own pages, or to null)
25
+ * and says nothing of `admin` gets the same mapping for it, since the
26
+ * libraries left Customize for Project admin (2026-10-27).
27
+ */
21
28
  export function setUiRoutes(overrides) {
22
- routes = { ...DEFAULT_ROUTES, ...overrides };
29
+ const admin = overrides.admin ?? overrides.customize;
30
+ routes = { ...DEFAULT_ROUTES, ...overrides, ...(admin ? { admin } : {}) };
23
31
  }
24
32
  export function uiRoutes() {
25
33
  return routes;
@@ -41,6 +49,10 @@ export function decodeSpaceSegment(segment) {
41
49
  export function customizePath(projectId, path) {
42
50
  return routes.customize(projectId, path) ?? DEFAULT_ROUTES.customize(projectId, path);
43
51
  }
52
+ /** A Project admin URL, with the same fallback as `customizePath`. */
53
+ export function adminPath(projectId, path) {
54
+ return routes.admin(projectId, path) ?? DEFAULT_ROUTES.admin(projectId, path);
55
+ }
44
56
  /**
45
57
  * The session id `pathname` shows, read through the host's `session` route
46
58
  * (so a host URL scheme works), or null when it is not a session page of
@@ -0,0 +1,31 @@
1
+ import type { LinkPreview } from '@kortix/sdk';
2
+ import { Node } from '@tiptap/core';
3
+ /**
4
+ * A pasted link shown as a card: its title, its description and the address on
5
+ * the left, the page's Open Graph image (when it has one) on the right. With
6
+ * no image, the site's favicon sits before the address. The
7
+ * card is stored in the Markdown file as one line of HTML
8
+ * (`<div class="kx-embed">…</div>`), so the published page shows it without
9
+ * fetching anything but that image; the doc stylesheet draws it.
10
+ */
11
+ export type EmbedMeta = {
12
+ href: string;
13
+ title: string;
14
+ summary: string;
15
+ image: string;
16
+ };
17
+ /** A link that can be a card: any http(s) address. */
18
+ export declare function canEmbed(href: string): boolean;
19
+ /** One plain line from page text (Markdown or HTML removed), capped. */
20
+ export declare function plainSummary(text: string | null | undefined): string;
21
+ /** What the URL alone tells: the card when the page says nothing (a private page, Linear, a failed read). */
22
+ export declare function embedFromUrl(href: string): EmbedMeta | null;
23
+ /**
24
+ * The card for a link: the page's own title, description and image, read by
25
+ * the API (`read`: `getLinkPreview` for the doc's project). GitHub's title
26
+ * reads "… by author · Pull Request #12 · owner/repo". Linear is not read (its
27
+ * pages need a login); a page that cannot be read is the card the URL gives.
28
+ */
29
+ export declare function fetchEmbed(href: string, read: (url: string) => Promise<LinkPreview>): Promise<EmbedMeta | null>;
30
+ /** The card in a doc: an atom block, `div.kx-embed` in the HTML and in the Markdown file. */
31
+ export declare const LinkEmbed: Node<any, any>;
@@ -0,0 +1,168 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Button } from '../../primitives/button.js';
4
+ import { ButtonGroup } from '../../primitives/button-group.js';
5
+ import { FaviconAvatar } from '../../primitives/favicon-avatar.js';
6
+ import { Hint } from '../../primitives/hint.js';
7
+ import { faviconUrlForUrl } from '../../lib/favicon.js';
8
+ import { successToast } from '../../primitives/toast.js';
9
+ import { ArrowSquareOutIcon, LinkSimpleIcon, TextTIcon, TrashIcon } from '@phosphor-icons/react';
10
+ import { Node } from '@tiptap/core';
11
+ import { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react';
12
+ import { useState } from 'react';
13
+ import { useTranslations } from '../../i18n/index.js';
14
+ const SUMMARY_MAX = 220;
15
+ /** A link that can be a card: any http(s) address. */
16
+ export function canEmbed(href) {
17
+ return /^https?:\/\/[^\s]+$/i.test(href) && URL.canParse(href);
18
+ }
19
+ /** `fix-the-thing` → `Fix the thing`. */
20
+ function fromSlug(slug) {
21
+ const words = decodeURIComponent(slug).replace(/[-_]+/g, ' ').trim();
22
+ return words.charAt(0).toUpperCase() + words.slice(1);
23
+ }
24
+ /** A Linear page's id and name from its URL: its pages need a login, so they tell nothing more. */
25
+ function linearTitle(url) {
26
+ if (url.hostname !== 'linear.app')
27
+ return null;
28
+ const [, section, id, slug] = url.pathname.split('/').filter(Boolean);
29
+ if (section === 'issue' && id)
30
+ return [id.toUpperCase(), slug ? fromSlug(slug) : ''].filter(Boolean).join(' ');
31
+ // A project or document link ends in `<name>-<hash>`.
32
+ return id ? fromSlug(id.replace(/-[0-9a-f]{8,}$/i, '')) : 'Linear';
33
+ }
34
+ /** Strip complete HTML comments in one forward pass, including nested opening markers. */
35
+ function withoutComments(text) {
36
+ const chunks = [];
37
+ let cursor = 0;
38
+ for (;;) {
39
+ const start = text.indexOf('<!--', cursor);
40
+ if (start === -1)
41
+ break;
42
+ const end = text.indexOf('-->', start + 4);
43
+ if (end === -1)
44
+ break;
45
+ chunks.push(text.slice(cursor, start), ' ');
46
+ cursor = end + 3;
47
+ }
48
+ chunks.push(text.slice(cursor));
49
+ return chunks.join('');
50
+ }
51
+ /** One plain line from page text (Markdown or HTML removed), capped. */
52
+ export function plainSummary(text) {
53
+ if (!text)
54
+ return '';
55
+ const plain = withoutComments(text)
56
+ .replace(/```[\s\S]*?```/g, ' ')
57
+ .replace(/<[^<>]+>/g, ' ')
58
+ .replace(/!\[[^\]]*\]\([^)]*\)/g, ' ')
59
+ .replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
60
+ .replace(/^\s{0,3}(#{1,6}|>|[-*+]|\d+\.)\s+/gm, '')
61
+ .replace(/[*_`~]/g, '')
62
+ // Text a page escaped twice (GitHub's descriptions): shown as written, after tags are gone.
63
+ .replace(/&(lt|gt|quot|#39|apos|amp);/g, (_m, name) => ({ lt: '<', gt: '>', quot: '"', '#39': "'", apos: "'", amp: '&' })[name] ?? '')
64
+ .replace(/\s+/g, ' ')
65
+ .trim();
66
+ return plain.length > SUMMARY_MAX ? `${plain.slice(0, SUMMARY_MAX - 1).trimEnd()}…` : plain;
67
+ }
68
+ /** What the URL alone tells: the card when the page says nothing (a private page, Linear, a failed read). */
69
+ export function embedFromUrl(href) {
70
+ if (!canEmbed(href))
71
+ return null;
72
+ const url = new URL(href);
73
+ const title = linearTitle(url) ?? `${url.hostname}${url.pathname === '/' ? '' : url.pathname}`;
74
+ return { href, title, summary: '', image: '' };
75
+ }
76
+ /**
77
+ * The card for a link: the page's own title, description and image, read by
78
+ * the API (`read`: `getLinkPreview` for the doc's project). GitHub's title
79
+ * reads "… by author · Pull Request #12 · owner/repo". Linear is not read (its
80
+ * pages need a login); a page that cannot be read is the card the URL gives.
81
+ */
82
+ export async function fetchEmbed(href, read) {
83
+ const base = embedFromUrl(href);
84
+ if (!base || new URL(href).hostname === 'linear.app')
85
+ return base;
86
+ try {
87
+ const page = await read(href);
88
+ return { href, title: page.title ?? base.title, summary: plainSummary(page.description), image: page.image_url ?? '' };
89
+ }
90
+ catch {
91
+ return base;
92
+ }
93
+ }
94
+ const text = (el, cls) => el.querySelector(`.${cls}`)?.textContent?.trim() ?? '';
95
+ /** The card's markup: the same in the editor and in the stored HTML. */
96
+ function CardBody({ href, title, summary, image, onClick }) {
97
+ // An image that does not load (gone, blocked) leaves the card text only.
98
+ const [broken, setBroken] = useState(false);
99
+ return (_jsxs("a", { href: href, target: "_blank", rel: "noopener noreferrer", onClick: onClick, children: [_jsxs("span", { className: "kx-embed-text", children: [_jsx("span", { className: "kx-embed-title", children: title }), summary ? _jsx("span", { className: "kx-embed-summary", children: summary }) : null, _jsxs("span", { className: "kx-embed-url", children: [!image || broken ? _jsx(FaviconAvatar, { value: href, size: "2xs" }) : null, _jsx("span", { className: "kx-embed-href", children: href })] })] }), image && !broken ? _jsx("img", { className: "kx-embed-image", src: image, alt: "", referrerPolicy: "no-referrer", onError: () => setBroken(true) }) : null] }));
100
+ }
101
+ /**
102
+ * The card in the editor, with its actions on hover, in one button group:
103
+ * Open link, Convert to a plain link, Copy link, Delete. While editing, a click on the card selects
104
+ * it; Open link opens the page.
105
+ */
106
+ function LinkEmbedView({ node, editor, getPos, deleteNode }) {
107
+ const t = useTranslations('artifacts');
108
+ const meta = node.attrs;
109
+ const editable = editor.isEditable;
110
+ const convert = () => {
111
+ const at = getPos();
112
+ if (typeof at !== 'number')
113
+ return;
114
+ editor
115
+ .chain()
116
+ .focus()
117
+ .insertContentAt({ from: at, to: at + node.nodeSize }, { type: 'paragraph', content: [{ type: 'text', text: meta.href, marks: [{ type: 'link', attrs: { href: meta.href } }] }] })
118
+ .run();
119
+ };
120
+ const copy = async () => {
121
+ await navigator.clipboard.writeText(meta.href);
122
+ successToast(t('linkCopied'));
123
+ };
124
+ const action = (label, Icon, run) => (_jsx(Hint, { label: label, side: "top", children: _jsx(Button, { variant: "secondary", size: "icon-sm", "aria-label": label, onClick: run, children: _jsx(Icon, { className: "size-3.5" }) }) }));
125
+ return (_jsxs(NodeViewWrapper, { className: "kx-embed group/embed relative", children: [_jsx(CardBody, { ...meta, onClick: editable ? (e) => e.preventDefault() : undefined }), _jsx("div", { contentEditable: false, "data-embed-actions": "", className: "absolute top-2 right-2 opacity-0 transition-opacity group-focus-within/embed:opacity-100 group-hover/embed:opacity-100", children: _jsxs(ButtonGroup, { children: [action(t('embedOpen'), ArrowSquareOutIcon, () => window.open(meta.href, '_blank', 'noopener,noreferrer')), editable ? action(t('embedConvert'), TextTIcon, convert) : null, action(t('embedCopy'), LinkSimpleIcon, () => void copy()), editable ? action(t('embedDelete'), TrashIcon, deleteNode) : null] }) })] }));
126
+ }
127
+ /** The card in a doc: an atom block, `div.kx-embed` in the HTML and in the Markdown file. */
128
+ export const LinkEmbed = Node.create({
129
+ name: 'linkEmbed',
130
+ group: 'block',
131
+ atom: true,
132
+ draggable: true,
133
+ selectable: true,
134
+ addAttributes() {
135
+ return {
136
+ href: { default: '', rendered: false, parseHTML: (el) => el.querySelector('a')?.getAttribute('href') ?? '' },
137
+ title: { default: '', rendered: false, parseHTML: (el) => text(el, 'kx-embed-title') },
138
+ summary: { default: '', rendered: false, parseHTML: (el) => text(el, 'kx-embed-summary') },
139
+ image: { default: '', rendered: false, parseHTML: (el) => el.querySelector('img.kx-embed-image')?.getAttribute('src') ?? '' },
140
+ };
141
+ },
142
+ parseHTML() {
143
+ return [{ tag: 'div.kx-embed', priority: 60 }];
144
+ },
145
+ renderHTML({ node }) {
146
+ const { href, title, summary, image } = node.attrs;
147
+ const textParts = [['span', { class: 'kx-embed-title' }, title]];
148
+ if (summary)
149
+ textParts.push(['span', { class: 'kx-embed-summary' }, summary]);
150
+ const favicon = image ? null : faviconUrlForUrl(href);
151
+ textParts.push([
152
+ 'span',
153
+ { class: 'kx-embed-url' },
154
+ ...(favicon ? [['img', { class: 'kx-embed-favicon', src: favicon, alt: '', referrerpolicy: 'no-referrer' }]] : []),
155
+ ['span', { class: 'kx-embed-href' }, href],
156
+ ]);
157
+ const body = [['span', { class: 'kx-embed-text' }, ...textParts]];
158
+ if (image)
159
+ body.push(['img', { class: 'kx-embed-image', src: image, alt: '', referrerpolicy: 'no-referrer' }]);
160
+ return ['div', { class: 'kx-embed' }, ['a', { href, target: '_blank', rel: 'noopener noreferrer' }, ...body]];
161
+ },
162
+ addNodeView() {
163
+ // The editor leaves the action buttons to themselves (see DocCodeBlock).
164
+ return ReactNodeViewRenderer(LinkEmbedView, {
165
+ stopEvent: ({ event }) => !!event.target?.closest?.('[data-embed-actions]'),
166
+ });
167
+ },
168
+ });