@kortix/ui 0.14.12 → 0.14.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
@@ -9,6 +9,8 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
9
9
  import { Badge } from '../../../primitives/badge.js';
10
10
  import { Button } from '../../../primitives/button.js';
11
11
  import { Checkbox } from '../../../primitives/checkbox.js';
12
+ import { Switch } from '../../../primitives/switch.js';
13
+ import { plainGrantSwitch } from '../../shared/access-list.js';
12
14
  import { ConfirmDialog } from '../../../primitives/confirm-dialog.js';
13
15
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '../../../primitives/dropdown-menu.js';
14
16
  import { Field, FieldDescription, FieldLabel } from '../../../primitives/field.js';
@@ -29,6 +31,7 @@ import { errorToast, infoToast, successToast, warningToast } from '../../../prim
29
31
  import { EmptyState } from '../../../primitives/empty-state.js';
30
32
  import { ErrorState } from '../../../primitives/error-state.js';
31
33
  import { CapabilityPageShell } from '../../shared/capability-page-shell.js';
34
+ import { GrantModeTabs, withCatalog, grantOrphans, } from '../../shared/agent-resource-scope.js';
32
35
  import { AudienceFields } from '../add-account-fields.js';
33
36
  import { NewEntityMenu } from '../../shared/new-entity-menu.js';
34
37
  import { newConfigPrompt, useConfigureThread, } from '../../use-configure-thread.js';
@@ -48,8 +51,10 @@ import { audienceDraftFrom, sameSharedWith, sharedWithFrom, } from './secret-aud
48
51
  import { useSlashFocus } from '../../../internal/hooks/index.js';
49
52
  const SECRET_NAME_REGEX = /^[A-Z_][A-Z0-9_]{0,63}$/;
50
53
  const IDENTIFIER_REGEX = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/;
51
- export function SecretsView({ projectId }) {
54
+ export function SecretsView({ projectId, surface = { kind: 'global' }, grant, }) {
55
+ const agentGrant = surface.kind === 'agent' ? grant : undefined;
52
56
  const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
57
+ const tAgentScope = useI18nTranslations('agentScope');
53
58
  const tHardcodedUi = useTranslations('hardcodedUi');
54
59
  const tI18nHardcoded = useTranslations('hardcodedUi');
55
60
  const tSecrets = useTranslations('secrets');
@@ -76,7 +81,12 @@ export function SecretsView({ projectId }) {
76
81
  // role that holds `project.secret.write` without the manager role saw a
77
82
  // read-only page, and one denied the leaf saw editable controls that 403.
78
83
  const canManage = useProjectCan(projectId, PROJECT_ACTIONS.PROJECT_SECRET_WRITE).allowed === true;
79
- const allRows = useMemo(() => buildRows(normalized), [normalized]);
84
+ const projectRows = useMemo(() => buildRows(normalized), [normalized]);
85
+ // An agent's grant governs only what reaches its sandbox: environment
86
+ // variables and network-enforced secrets. Model logins, connector and git
87
+ // credentials are used by Kortix services (the model and connector settings
88
+ // decide who may use them), and a disabled secret reaches nothing.
89
+ const allRows = useMemo(() => (agentGrant ? projectRows.filter((r) => r.strategy === 'runtime' || r.strategy === 'egress') : projectRows), [agentGrant, projectRows]);
80
90
  const viewerId = useUiViewerId() ?? null;
81
91
  const tSharing = useI18nTranslations('accessSharing');
82
92
  // A legacy/enforced row keeps its "Enforce at the network" badge even with the
@@ -115,6 +125,18 @@ export function SecretsView({ projectId }) {
115
125
  return allRows;
116
126
  return allRows.filter((r) => r.identifier.toLowerCase().includes(q) || r.key.toLowerCase().includes(q));
117
127
  }, [allRows, query]);
128
+ // Agent scope: granted identifiers this project no longer declares (deleted,
129
+ // renamed, or never a project secret). Listed after the rows with a Missing
130
+ // mark so the editor can revoke them; a search hides them, since they hold
131
+ // nothing to match but the name.
132
+ const orphans = useMemo(() => agentGrant && !query.trim()
133
+ ? grantOrphans(agentGrant.value, projectRows.map((r) => r.identifier))
134
+ : [], [agentGrant, projectRows, query]);
135
+ // Agent mode: one switch per row, at the row's end, like every Access view.
136
+ // Turning one off under All keeps the rest (`plainGrantSwitch`).
137
+ const grantSwitch = agentGrant?.set
138
+ ? plainGrantSwitch(agentGrant.value, allRows.map((r) => r.identifier), agentGrant.set)
139
+ : undefined;
118
140
  const configure = useConfigureThread(projectId);
119
141
  const openCreate = () => {
120
142
  setDialogRow(null);
@@ -134,7 +156,7 @@ export function SecretsView({ projectId }) {
134
156
  if (!next && editorSaving)
135
157
  return;
136
158
  setDialogOpen(next);
137
- }, size: "lg", className: "flex-1", children: [_jsx(SplitSheetMain, { children: _jsxs(CapabilityPageShell, { title: tI18nComplete.raw('textd8707d411d99'), description: tI18nComplete.raw('texteca47e3afa10'), search:
159
+ }, size: "lg", className: "flex-1", children: [_jsx(SplitSheetMain, { children: _jsxs(CapabilityPageShell, { title: tI18nComplete.raw('textd8707d411d99'), description: agentGrant ? tI18nComplete.raw('textbb74cc7dce98') : tI18nComplete.raw('texteca47e3afa10'), filters: agentGrant ? (_jsx(GrantModeTabs, { grant: withCatalog(agentGrant, allRows.map((r) => r.identifier)), label: tAgentScope('secretsAccess') })) : undefined, search:
138
160
  /* Hidden until there is a list to search, the same rule Triggers
139
161
  uses: a filter over nothing is a control that cannot do anything. */
140
162
  showContent && allRows.length > 0 ? (_jsxs(InputGroupSearch, { children: [_jsx(InputGroupSearchIcon, { children: _jsx(Search, {}) }), _jsx(InputGroupSearchInput, { ref: searchRef, placeholder: tI18nComplete.raw('textb5814f05b923'), value: query, onChange: (e) => setQuery(e.target.value), variant: "popover", size: "sm" }), _jsx(InputGroupSearchClear, { onClick: () => setQuery('') })] })) : undefined, titleAddon: _jsx(SecretsAccessInfo, { showEnforced: showEnforced }), action: showContent && canManage ? (_jsx(NewEntityMenu, { label: tI18nComplete.raw('text18fdd549b2ed'), pending: configure.pending, onChat: () => configure.start(newConfigPrompt('secret')), manual: {
@@ -143,7 +165,11 @@ export function SecretsView({ projectId }) {
143
165
  } })) : undefined, children: [_jsx("div", { className: "space-y-4", children: secretsQuery.isLoading ? (_jsx("div", { className: "space-y-1", children: Array.from({ length: 5 }).map((_, i) => (_jsx(Skeleton, { className: "h-10 rounded-md" }, i))) })) : secretsQuery.isError ? (_jsx(ErrorState, { size: "sm", title: tHardcodedUi.raw('appProjectsIdCustomizeSecretsPage.line773JsxAttrTitleFailedToLoadSecrets'), description: secretsQuery.error?.message ?? tI18nComplete.raw('text398e53499fed'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => secretsQuery.refetch(), children: tI18nComplete.raw('text942087cc2d41') }) })) : (_jsxs(_Fragment, { children: [missingRequired.length > 0 && (_jsx(InfoBanner, { tone: "warning", icon: _jsx(DangerTriangleSolid, { weight: "fill" }), title: tI18nComplete('text10d33709a797', {
144
166
  value0: missingRequired.length,
145
167
  value1: missingRequired.length === 1 ? 'secret' : 'secrets',
146
- }), children: tI18nComplete.raw('textc18dc13ca821') })), filtered.length === 0 ? (query.trim() ? (_jsxs("p", { className: "text-muted-foreground px-3 py-6 text-center text-xs", children: [tI18nComplete.raw('texta8897de42124'), _jsx("span", { className: "text-foreground font-mono", children: query }), "."] })) : (_jsx(EmptyState, { icon: KeyRound, size: "sm", title: tI18nComplete.raw('text5aa40906d187'), description: tI18nComplete.raw('text234482872368'), action: canManage ? (_jsxs(Button, { variant: "outline", size: "sm", className: "gap-1.5", onClick: openCreate, children: [_jsx(Plus, { className: "size-3.5 shrink-0" }), tI18nComplete.raw('textf57a23c69b34')] })) : undefined }))) : (_jsxs(Table, { className: "overflow-hidden rounded-md", children: [_jsx(TableHeader, { children: _jsxs(TableRow, { className: "hover:bg-transparent", children: [_jsx(TableHead, { children: tI18nComplete.raw('text9b10587f84a2') }), _jsx(TableHead, { children: tI18nComplete.raw('text8e37953d23da') }), _jsx(TableHead, { children: tI18nComplete.raw('textec5ba0abb717') }), _jsx(TableHead, { children: tSharing('whoCanUse') }), _jsx(TableHead, { className: "w-[52px]", children: _jsx("span", { className: "sr-only", children: tI18nComplete.raw('textff8059dc6752') }) })] }) }), _jsx(TableBody, { children: filtered.map((row) => (_jsx(SecretTableRow, { row: row, canManage: canManage, viewerId: viewerId, busy: removeShared.isPending && removeShared.variables === row.identifier, deletingMine: deleteMine.isPending && deleteMine.variables === row.key, onEdit: () => openEdit(row), onDelete: () => setDeleteRow(row), onDeleteMine: () => deleteMine.mutate(row.key) }, row.identifier))) })] }))] })) }), _jsx(ConfirmDialog, { open: deleteRow !== null, onOpenChange: (open) => {
168
+ }), children: tI18nComplete.raw('textc18dc13ca821') })), filtered.length === 0 && orphans.length === 0 ? (query.trim() ? (_jsxs("p", { className: "text-muted-foreground px-3 py-6 text-center text-xs", children: [tI18nComplete.raw('texta8897de42124'), _jsx("span", { className: "text-foreground font-mono", children: query }), "."] })) : (_jsx(EmptyState, { icon: KeyRound, size: "sm", title: agentGrant && projectRows.length > 0 ? tAgentScope('sandboxSecretsEmptyTitle') : tI18nComplete.raw('text5aa40906d187'), description: agentGrant && projectRows.length > 0
169
+ ? tAgentScope('sandboxSecretsEmptyDescription')
170
+ : tI18nComplete.raw('text234482872368'), action: canManage ? (_jsxs(Button, { variant: "outline", size: "sm", className: "gap-1.5", onClick: openCreate, children: [_jsx(Plus, { className: "size-3.5 shrink-0" }), tI18nComplete.raw('textf57a23c69b34')] })) : undefined }))) : (_jsxs(Table, { className: "overflow-hidden rounded-md", children: [_jsx(TableHeader, { children: _jsxs(TableRow, { className: "hover:bg-transparent", children: [_jsx(TableHead, { children: tI18nComplete.raw('text9b10587f84a2') }), _jsx(TableHead, { children: tI18nComplete.raw('text8e37953d23da') }), _jsx(TableHead, { children: tI18nComplete.raw('textec5ba0abb717') }), _jsx(TableHead, { children: tSharing('whoCanUse') }), grantSwitch ? _jsx(TableHead, { className: "w-24 text-right", children: tAgentScope('thisAgent') }) : null, _jsx(TableHead, { className: "w-[52px]", children: _jsx("span", { className: "sr-only", children: tI18nComplete.raw('textff8059dc6752') }) })] }) }), _jsxs(TableBody, { children: [filtered.map((row) => (_jsx(SecretTableRow, { row: row, grantSwitch: grantSwitch, canManage: canManage, viewerId: viewerId, busy: removeShared.isPending && removeShared.variables === row.identifier, deletingMine: deleteMine.isPending && deleteMine.variables === row.key, onEdit: () => openEdit(row), onDelete: () => setDeleteRow(row), onDeleteMine: () => deleteMine.mutate(row.key) }, row.identifier))), agentGrant
171
+ ? orphans.map((identifier) => (_jsx(MissingSecretRow, { identifier: identifier, grantSwitch: grantSwitch }, identifier)))
172
+ : null] })] }))] })) }), _jsx(ConfirmDialog, { open: deleteRow !== null, onOpenChange: (open) => {
147
173
  if (!open)
148
174
  setDeleteRow(null);
149
175
  }, title: tI18nComplete.raw('text1a48c8c83043'), description: deleteRow ? tI18nComplete('text05b1f0cd964e', { value0: deleteRow.identifier }) : '', confirmLabel: tI18nComplete.raw('texte2d0a54968ea'), confirmVariant: "destructive", onConfirm: () => {
@@ -294,7 +320,17 @@ function SecretMarks({ row }) {
294
320
  return null;
295
321
  return (_jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [row.system ? (_jsx(Hint, { label: tI18nComplete.raw('texte9ec6c0ad396'), side: "top", children: _jsx(Lock, { className: "text-muted-foreground size-3.5 shrink-0", "aria-label": tI18nComplete.raw('texte9ec6c0ad396') }) })) : null, row.requirement === 'required' ? (_jsx(Hint, { label: row.configured ? 'Required' : tI18nComplete.raw('text85f09652bb1d'), side: "top", children: _jsx(Asterisk, { className: cn('size-3.5 shrink-0', row.configured ? 'text-muted-foreground' : 'text-kortix-orange'), "aria-label": row.configured ? 'Required' : tI18nComplete.raw('textf0335c9d1910') }) })) : null] }));
296
322
  }
297
- function SecretTableRow({ row, canManage, viewerId, busy, deletingMine, onEdit, onDelete, onDeleteMine, }) {
323
+ /**
324
+ * A granted identifier the project no longer declares: its name, the Missing
325
+ * mark, and the grant checkbox to revoke it. It has no value, delivery or
326
+ * audience, so those cells stay empty.
327
+ */
328
+ function MissingSecretRow({ identifier, grantSwitch, }) {
329
+ const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
330
+ const control = grantSwitch?.(identifier);
331
+ return (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "max-w-[260px] align-middle", children: _jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [_jsx("code", { className: "text-foreground truncate font-mono text-xs", children: identifier }), _jsx(Badge, { variant: "destructive", size: "xs", children: tI18nComplete.raw('text6be36ca49ee8') })] }), _jsx("span", { className: "text-muted-foreground truncate text-xs", children: tI18nComplete.raw('textfecc36d012be') })] }) }), _jsx(TableCell, { colSpan: 3 }), _jsx(TableCell, { className: "text-right align-middle", children: control ? (_jsx(Switch, { checked: control.checked, onCheckedChange: control.onCheckedChange, "aria-label": tI18nComplete('textd4170e74c3b0', { value0: identifier }) })) : null }), _jsx(TableCell, {})] }));
332
+ }
333
+ function SecretTableRow({ row, grantSwitch, canManage, viewerId, busy, deletingMine, onEdit, onDelete, onDeleteMine, }) {
298
334
  const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
299
335
  const tI18nHardcoded = useTranslations('hardcodedUi');
300
336
  const tSharing = useI18nTranslations('accessSharing');
@@ -305,7 +341,7 @@ function SecretTableRow({ row, canManage, viewerId, busy, deletingMine, onEdit,
305
341
  // No row tint for an unset required secret: the orange asterisk carries that
306
342
  // state, and a status hue belongs on the mark (color.md, Accents and status).
307
343
  return (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "max-w-[260px] align-middle", children: _jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [_jsx("code", { className: "text-foreground truncate font-mono text-xs", children: row.identifier }), _jsx(SecretMarks, { row: row })] }), distinctKey && (_jsxs("code", { className: "text-muted-foreground truncate font-mono text-xs", children: ["\u2192 ", row.key] }))] }) }), _jsx(TableCell, { className: "text-muted-foreground max-w-[160px] align-middle text-xs whitespace-nowrap", children: row.mineUndecryptable ? (_jsx(UndecryptableValue, { hint: tSecrets('undecryptable.mineHint'), actionLabel: tSecrets('undecryptable.deleteMine'), onAction: onDeleteMine, pending: deletingMine })) : row.undecryptable ? (_jsx(UndecryptableValue, { onAction: canManageShared ? onEdit : undefined })) : (statusLabel(row)) }), _jsx(TableCell, { className: "max-w-[220px] align-middle whitespace-normal", children: _jsxs("div", { className: "flex flex-col items-start gap-1", children: [_jsx(Badge, { variant: delivery.tone, size: "sm", children: delivery.label }), row.requiresRotation && (_jsx("span", { className: "text-kortix-orange text-xs font-medium", children: tI18nComplete.raw('texte450e0da6cf9') })), shouldWarnMissingAgentGrant(row.deliveryBlockedReason, row.strategy, row.consumer) && (_jsx("span", { className: "text-kortix-orange text-xs font-medium", children: tI18nComplete.raw('text6404e0b5d78d') }))] }) }), _jsx(TableCell, { className: "align-middle", children: row.configured ? (_jsxs("div", { className: "flex flex-col items-start gap-1", children: [_jsx(AudienceBadge, { visibility: audienceVisibility(row.sharedWith, viewerId), labels: row.sharedWith.map((share) => share.label) }), row.agents != null && (_jsx("span", { className: "text-muted-foreground text-xs", children: tSecrets('agentAccess', { agents: row.agents === 'all'
308
- ? tSecrets('allAgents') : row.agents.join(', ') || tSecrets('noAgents') }) })), row.usable ? null : (_jsx("span", { className: "text-muted-foreground text-xs", children: tSharing('notSharedWithYou') }))] })) : null }), _jsx(TableCell, { children: !canManageShared ? null : (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { size: "icon", variant: "ghost", "aria-label": tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsSecretsViewJsxAttrAriaLabelda70cb1c'), children: busy ? (_jsx(Loading, { className: "size-3.5 shrink-0" })) : (_jsx(MoreHorizontal, { className: "size-3.5 shrink-0" })) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-52", children: [_jsxs(DropdownMenuItem, { onClick: onEdit, children: [_jsx(PencilSimpleIcon, { className: "size-3.5 shrink-0" }), row.configured
344
+ ? tSecrets('allAgents') : row.agents.join(', ') || tSecrets('noAgents') }) })), row.usable ? null : (_jsx("span", { className: "text-muted-foreground text-xs", children: tSharing('notSharedWithYou') }))] })) : null }), grantSwitch ? (_jsx(TableCell, { className: "text-right align-middle", children: _jsx(Switch, { ...grantSwitch(row.identifier), "aria-label": tI18nComplete('textd4170e74c3b0', { value0: row.identifier }) }) })) : null, _jsx(TableCell, { children: !canManageShared ? null : (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { size: "icon", variant: "ghost", "aria-label": tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsSecretsViewJsxAttrAriaLabelda70cb1c'), children: busy ? (_jsx(Loading, { className: "size-3.5 shrink-0" })) : (_jsx(MoreHorizontal, { className: "size-3.5 shrink-0" })) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-52", children: [_jsxs(DropdownMenuItem, { onClick: onEdit, children: [_jsx(PencilSimpleIcon, { className: "size-3.5 shrink-0" }), row.configured
309
345
  ? tI18nComplete.raw('textb5068d24eb4f')
310
346
  : tI18nComplete.raw('text58bf3410b028')] }), row.configured && (_jsxs(DropdownMenuItem, { onClick: onDelete, children: [_jsx(TrashIcon, { className: "size-3.5 shrink-0" }), tI18nHardcoded.raw('autoComponentsProjectsCustomizeSectionsSecretsViewJsxTextDeleteSharedd7bb1731')] }))] })] })) })] }));
311
347
  }
@@ -1,4 +1,4 @@
1
- import { ArrowCircleUpIcon as ArrowUpCircle, ChatCircleIcon as ChatCircle, CoinsIcon as Coins, ShippingContainerIcon as Container, CreditCardIcon as CreditCard, FlaskIcon as Flask, KeyIcon as Key, LaptopIcon as Laptop, LinkIcon as Link, PaletteIcon as Palette, ShieldCheckIcon as ShieldCheck, SlidersHorizontalIcon as SlidersHorizontal, SquaresFourIcon as SquaresFour, UserIcon as User, } from '@phosphor-icons/react';
1
+ import { ChatCircleIcon as ChatCircle, CoinsIcon as Coins, ShippingContainerIcon as Container, CreditCardIcon as CreditCard, FlaskIcon as Flask, KeyIcon as Key, LaptopIcon as Laptop, LinkIcon as Link, PaletteIcon as Palette, ShieldCheckIcon as ShieldCheck, SlidersHorizontalIcon as SlidersHorizontal, SquaresFourIcon as SquaresFour, UserIcon as User, } from '@phosphor-icons/react';
2
2
  import { Mcp } from '../../internal/icons/mcp.js';
3
3
  import { ChromeRailIcon } from '../../internal/chrome/browser-icon.js';
4
4
  /**
@@ -17,7 +17,7 @@ export function isRailItemActive(item, tab) {
17
17
  const STATIC_GROUPS = [
18
18
  /**
19
19
  * No Workspace group. Project configuration — General, Sandbox templates,
20
- * Feature flags, Upgrades — is the Customize bar's Settings tab
20
+ * Feature flags — is the Customize bar's Settings tab
21
21
  * (`/projects/<id>/config`, `capability-tab-routes.ts`), where the rest of
22
22
  * the project is configured. It sat here between 2026-09-02 and
23
23
  * 2026-09-03; Marko: the overlay is for the PERSON, so it holds only what
@@ -155,12 +155,6 @@ export const RETIRED_RAIL_ITEMS = [
155
155
  description: 'Features you can switch on before they are generally available.',
156
156
  icon: Flask,
157
157
  },
158
- {
159
- tab: 'upgrades',
160
- label: 'Upgrades',
161
- description: 'Changes an agent makes to this workspace. Every run opens a change request for you to review — nothing merges on its own.',
162
- icon: ArrowUpCircle,
163
- },
164
158
  // Connected accounts listed the ACCOUNT's GitHub App installations — the
165
159
  // same rows the account page's Git tab manages — under a person's own
166
160
  // settings. Gone from the rail on 2026-09-03 (Marko); `/settings/connected`
@@ -1,4 +1,4 @@
1
- export type SettingsTab = 'profile' | 'security' | 'appearance' | 'sessions' | 'preferences' | 'connected' | 'chrome' | 'tokens' | 'plan' | 'credits' | 'workspace' | 'sandbox' | 'feature-flags' | 'upgrades' | 'mcp' | 'computer';
1
+ export type SettingsTab = 'profile' | 'security' | 'appearance' | 'sessions' | 'preferences' | 'connected' | 'chrome' | 'tokens' | 'plan' | 'credits' | 'workspace' | 'sandbox' | 'feature-flags' | 'mcp' | 'computer';
2
2
  /**
3
3
  * The default must be a tab that survives every gate, or the overlay opens on
4
4
  * nothing. It was `general` until project configuration moved to
@@ -84,7 +84,7 @@ export declare function isProjectGraduatedSection(rawSection: string | null | un
84
84
  * `/settings/<id>`; anything unrecognized returns `null`.
85
85
  *
86
86
  * There is no rename map left. Every id that used to be renamed INTO the
87
- * overlay (`settings`, `git`, `upgrade`, the seven `llm-*` ids) now names a
87
+ * overlay (`settings`, `git`, the seven `llm-*` ids) now names a
88
88
  * surface outside it, so all of them are entries in `GRADUATED` above.
89
89
  *
90
90
  * **`accountId` is optional and is checked FIRST.** It is the caller's
@@ -27,6 +27,7 @@ import { accountPanelUrl, hubTarget } from '../../internal/stores/account-panel-
27
27
  * legacy section/tab name and redirect them where applicable.
28
28
  */
29
29
  import { capabilityTabHref, channelsHref, } from '../../internal/lib/capability-tab-routes.js';
30
+ import { adminPath } from '../../lib/routes.js';
30
31
  // Organization (General, Billing, Usage, Groups, Roles, Identity, Audit log)
31
32
  // and API keys are gone: every one of them configured the ACCOUNT, not the
32
33
  // project, and the account already owns a full page for them at
@@ -34,11 +35,11 @@ import { capabilityTabHref, channelsHref, } from '../../internal/lib/capability-
34
35
  //
35
36
  // The project's own configuration left too — General, Members, Secrets,
36
37
  // Channels, Repositories, Models, Sandbox templates, Snapshots, Marketplace,
37
- // Review, Voice, Feature flags (was `experimental`) and Upgrades. All thirteen
38
+ // Review, Voice and Feature flags (was `experimental`). All twelve
38
39
  // became sections of the Customize bar's Settings tab, `/projects/[id]/config
39
40
  // ?section=<key>`, and that page was itself retired on 2026-09-02: each id now
40
41
  // resolves through `GRADUATED` to a capability page, or is a live tab of this
41
- // overlay again (`workspace`, `sandbox`, `feature-flags`, `upgrades`).
42
+ // overlay again (`workspace`, `sandbox`, `feature-flags`).
42
43
  // Nothing routes to `/config` any more — `menu-registry-destinations.test.ts`
43
44
  // fails on a palette row that tries.
44
45
  /**
@@ -63,7 +64,7 @@ export const SETTINGS_TABS = [
63
64
  // Account group was removed on 2026-09-03 (Marko) — a wallet and a
64
65
  // subscription belong to the account page, `/accounts/[id]`, and both ids
65
66
  // resolve there through `ACCOUNT_GRADUATED`.
66
- // `workspace`, `sandbox`, `feature-flags` and `upgrades` are still in the
67
+ // `workspace`, `sandbox` and `feature-flags` are still in the
67
68
  // type — `settings-panel.tsx` keeps their panes mountable — but NOT here:
68
69
  // the overlay's Workspace group was removed on 2026-09-03 (Marko), so no
69
70
  // route or palette row may open them. Each id resolves through `GRADUATED`
@@ -102,29 +103,26 @@ export const GRADUATED = {
102
103
  schedules: (p) => capabilityTabHref(p, 'triggers'),
103
104
  webhooks: (p) => capabilityTabHref(p, 'triggers'),
104
105
  // ── Project configuration → the Customize bar's Settings tab ────────────
105
- // `/projects/<id>/config` holds General, Sandbox templates, Feature flags
106
- // and Upgrades. It was retired on 2026-09-02 for the overlay's Workspace
106
+ // `/projects/<id>/config` holds General, Sandbox templates and Feature
107
+ // flags. It was retired on 2026-09-02 for the overlay's Workspace
107
108
  // group and brought back on 2026-09-03 (Marko), and the overlay group went
108
109
  // — so every id that ever named one of these sections, the overlay's own
109
110
  // tab ids included, lands on the page. Review, the one section that was an
110
111
  // inbox rather than configuration, is a capability tab of its own.
111
- workspace: (p) => `${capabilityTabHref(p, 'config')}`,
112
- general: (p) => `${capabilityTabHref(p, 'config')}`,
113
- settings: (p) => `${capabilityTabHref(p, 'config')}`,
112
+ workspace: (p) => capabilityTabHref(p, 'config'),
113
+ general: (p) => capabilityTabHref(p, 'config'),
114
+ settings: (p) => capabilityTabHref(p, 'config'),
114
115
  // Repositories and its pre-rename `git` are the Git repo section — its own
115
116
  // section of the Settings tab since 2026-09-03.
116
- repositories: (p) => `${capabilityTabHref(p, 'config')}?section=git`,
117
- git: (p) => `${capabilityTabHref(p, 'config')}?section=git`,
118
- sandbox: (p) => `${capabilityTabHref(p, 'config')}?section=sandbox`,
117
+ repositories: (p) => adminPath(p, 'git'),
118
+ git: (p) => adminPath(p, 'git'),
119
+ sandbox: (p) => adminPath(p, 'sandbox'),
119
120
  // Snapshots merged into Sandbox templates — a snapshot is a template's
120
121
  // build history.
121
- snapshots: (p) => `${capabilityTabHref(p, 'config')}?section=sandbox`,
122
- 'feature-flags': (p) => `${capabilityTabHref(p, 'config')}?section=feature-flags`,
122
+ snapshots: (p) => adminPath(p, 'sandbox'),
123
+ 'feature-flags': (p) => adminPath(p, 'feature-flags'),
123
124
  // `experimental` was renamed Feature flags on the way.
124
- experimental: (p) => `${capabilityTabHref(p, 'config')}?section=feature-flags`,
125
- upgrades: (p) => `${capabilityTabHref(p, 'config')}?section=upgrades`,
126
- // `upgrade`, singular, is the old Customize id for the Upgrades pane.
127
- upgrade: (p) => `${capabilityTabHref(p, 'config')}?section=upgrades`,
125
+ experimental: (p) => adminPath(p, 'feature-flags'),
128
126
  review: (p) => capabilityTabHref(p, 'review'),
129
127
  // Secrets, Channels, and Models graduated a SECOND time — off the Settings
130
128
  // sub-nav entirely and onto their own top-level Customize tab. `models` and
@@ -230,7 +228,7 @@ export const RENAMED = {
230
228
  connected: 'profile',
231
229
  'api-keys': 'tokens',
232
230
  // Every project-configuration spelling (`general`, `git`, `snapshots`,
233
- // `experimental`, `upgrade`, …) is in `GRADUATED` above: they name the
231
+ // `experimental`, …) is in `GRADUATED` above: they name the
234
232
  // Customize bar's Settings tab, not a tab of this overlay.
235
233
  };
236
234
  /**
@@ -268,7 +266,7 @@ export function isProjectGraduatedSection(rawSection) {
268
266
  * `/settings/<id>`; anything unrecognized returns `null`.
269
267
  *
270
268
  * There is no rename map left. Every id that used to be renamed INTO the
271
- * overlay (`settings`, `git`, `upgrade`, the seven `llm-*` ids) now names a
269
+ * overlay (`settings`, `git`, the seven `llm-*` ids) now names a
272
270
  * surface outside it, so all of them are entries in `GRADUATED` above.
273
271
  *
274
272
  * **`accountId` is optional and is checked FIRST.** It is the caller's
@@ -19,6 +19,9 @@ export interface ExperimentalCopy {
19
19
  emptyTitle: string;
20
20
  emptyDescription: string;
21
21
  permission: string;
22
+ /** The badge on a work-in-progress flag, and what it means. */
23
+ wip: string;
24
+ wipNote: string;
22
25
  }
23
26
  export declare const DEFAULT_EXPERIMENTAL_COPY: ExperimentalCopy;
24
27
  /** The translator surface {@link localizeFeatureFlag} reads. */
@@ -58,6 +58,7 @@ import { Button } from '../../../primitives/button.js';
58
58
  import { InputGroupSearch, InputGroupSearchClear, InputGroupSearchIcon, InputGroupSearchInput, } from '../../../primitives/input-group.js';
59
59
  import Loading from '../../../primitives/loading.js';
60
60
  import { Skeleton } from '../../../primitives/skeleton.js';
61
+ import { Badge } from '../../../primitives/badge.js';
61
62
  import { Switch } from '../../../primitives/switch.js';
62
63
  import { errorToast } from '../../../primitives/toast.js';
63
64
  import { EmptyState } from '../../../primitives/empty-state.js';
@@ -84,6 +85,8 @@ export const DEFAULT_EXPERIMENTAL_COPY = {
84
85
  emptyTitle: 'No experimental features',
85
86
  emptyDescription: 'This deployment exposes no per-project feature flags.',
86
87
  permission: "You need the project's settings permission to change a feature flag.",
88
+ wip: 'Work in progress',
89
+ wipNote: 'Not recommended yet: it can change or break.',
87
90
  };
88
91
  function originLabel(feature, copy) {
89
92
  // An internal-only flag (`apps`) is listed only while on, and
@@ -151,7 +154,7 @@ function ExperimentalFeatureRow({ feature, pending, canManage, onToggle, copy, }
151
154
  // needed and the row stays hook-free, which is what lets the view render
152
155
  // under `renderToStaticMarkup`.
153
156
  const nameId = `feature-flag-${feature.key}`;
154
- return (_jsxs("div", { className: "flex items-center justify-between gap-4 px-4 py-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("p", { id: nameId, className: "text-foreground text-sm font-medium", children: feature.name }), _jsx("span", { className: "text-muted-foreground text-xs", children: originLabel(feature, copy) })] }), _jsx("p", { className: "text-muted-foreground mt-0.5 text-xs text-pretty", children: feature.description })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [pending ? _jsx(Loading, { className: "text-muted-foreground size-3.5" }) : null, _jsx(Switch, { "aria-labelledby": nameId, checked: feature.enabled, disabled: !canManage || pending, onCheckedChange: (v) => onToggle(feature.key, v) })] })] }));
157
+ return (_jsxs("div", { className: "flex items-center justify-between gap-4 px-4 py-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("p", { id: nameId, className: "text-foreground text-sm font-medium", children: feature.name }), feature.wip ? (_jsx(Badge, { variant: "warning", size: "xs", children: copy.wip })) : null, _jsx("span", { className: "text-muted-foreground text-xs", children: originLabel(feature, copy) })] }), _jsxs("p", { className: "text-muted-foreground mt-0.5 text-xs text-pretty", children: [feature.wip ? `${copy.wipNote} ` : null, feature.description] })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [pending ? _jsx(Loading, { className: "text-muted-foreground size-3.5" }) : null, _jsx(Switch, { "aria-labelledby": nameId, checked: feature.enabled, disabled: !canManage || pending, onCheckedChange: (v) => onToggle(feature.key, v) })] })] }));
155
158
  }
156
159
  /** Presentational only — no hooks, no data fetching, no store or Supabase
157
160
  * read. Kept separate from `ExperimentalTab` so this renders under
@@ -292,5 +295,7 @@ export function ExperimentalTab({ projectId }) {
292
295
  emptyTitle: t('emptyTitle'),
293
296
  emptyDescription: t('emptyDescription'),
294
297
  permission: t('permission'),
298
+ wip: t('wip'),
299
+ wipNote: t('wipNote'),
295
300
  } })] }));
296
301
  }
@@ -12,7 +12,7 @@ export declare function describeState(state: string, labels?: Partial<Record<str
12
12
  /** Where the template is declared, in words a reader who has never opened the
13
13
  * repo can act on. Replaces the raw `platform` / `UI` / `kortix.yaml` tag
14
14
  * that used to sit last in the bullet-separated meta line. */
15
- export declare function describeSource(template: SandboxTemplate, manifestVersion: number | null, labels?: {
15
+ export declare function describeSource(template: SandboxTemplate, manifestPath: string, labels?: {
16
16
  platform?: string;
17
17
  dashboard?: string;
18
18
  }): {
@@ -55,10 +55,8 @@ export interface SandboxTabViewProps {
55
55
  * by the container from the same `canManage` gate as everything else in
56
56
  * this tab. `undefined` (not rendered) for a non-manager. */
57
57
  headerAction?: ReactNode;
58
- /** `1 | 2 | null` — drives whether the manifest hint below reads
59
- * `kortix.toml` or `kortix.yaml`. `null`/anything else falls back to
60
- * `kortix.toml`, matching `sandbox-view.tsx`'s own ternary default. */
61
- manifestVersion?: number | null;
58
+ /** The manifest's repository path the hint below names. */
59
+ manifestPath?: string;
62
60
  /** `data.templates_error` from `listProjectSnapshots` — a partial-read
63
61
  * warning, not a hard error (the hard-error path is `isError` above). */
64
62
  templatesError?: string | null;
@@ -85,7 +83,7 @@ export interface SandboxTabViewProps {
85
83
  * read. Kept separate from `SandboxTab` so this renders under
86
84
  * `renderToStaticMarkup` with no `QueryClientProvider` — see
87
85
  * `GeneralTabView` for the same split. */
88
- export declare function SandboxTabView({ isLoading, isError, errorMessage, onRetry, headerAction, manifestVersion, templatesError, isEmpty, emptyAction, templatesSlot, copy: copyOverride, }: SandboxTabViewProps): import("react").JSX.Element;
86
+ export declare function SandboxTabView({ isLoading, isError, errorMessage, onRetry, headerAction, manifestPath, templatesError, isEmpty, emptyAction, templatesSlot, copy: copyOverride, }: SandboxTabViewProps): import("react").JSX.Element;
89
87
  /** Container: owns every hook (project + snapshots queries, the template
90
88
  * form's open/edit state) and renders `SandboxTabView` with real data +
91
89
  * the templates slot, plus `SandboxTemplateForm` as a sibling (it owns its
@@ -14,7 +14,7 @@ import { Skeleton } from '../../../primitives/skeleton.js';
14
14
  import { errorToast, successToast } from '../../../primitives/toast.js';
15
15
  import { EmptyState } from '../../../primitives/empty-state.js';
16
16
  import { ErrorState } from '../../../primitives/error-state.js';
17
- import { manifestFilename, useProjectManifestVersion, } from '../../../internal/lib/manifest-version.js';
17
+ import { useProjectManifestHealth } from '../../../internal/lib/manifest-health.js';
18
18
  import { useLocale, useTranslations } from '../../../i18n/index.js';
19
19
  import { PROJECT_ACTIONS } from '../../../internal/lib/project-actions.js';
20
20
  import { useProjectCans } from '../../../internal/lib/use-project-can.js';
@@ -63,7 +63,7 @@ export function describeState(state, labels = {}) {
63
63
  /** Where the template is declared, in words a reader who has never opened the
64
64
  * repo can act on. Replaces the raw `platform` / `UI` / `kortix.yaml` tag
65
65
  * that used to sit last in the bullet-separated meta line. */
66
- export function describeSource(template, manifestVersion, labels = {}) {
66
+ export function describeSource(template, manifestPath, labels = {}) {
67
67
  if (template.source === 'platform')
68
68
  return {
69
69
  label: labels.platform ?? 'Kortix platform',
@@ -73,7 +73,7 @@ export function describeSource(template, manifestVersion, labels = {}) {
73
73
  if (template.source === 'ui')
74
74
  return { label: labels.dashboard ?? 'This dashboard', icon: SquaresFourIcon, mono: false };
75
75
  return {
76
- label: manifestFilename(manifestVersion),
76
+ label: manifestPath,
77
77
  icon: FileCodeIcon,
78
78
  mono: true,
79
79
  };
@@ -121,7 +121,7 @@ function TemplateCard({ projectId, template, canManage, onEdit, }) {
121
121
  const t = useTranslations('settings.sandbox');
122
122
  const locale = useLocale();
123
123
  const queryClient = useQueryClient();
124
- const { version: manifestVersion } = useProjectManifestVersion(projectId);
124
+ const manifestPath = useProjectManifestHealth(projectId)?.path ?? 'kortix.yaml';
125
125
  const [confirmDelete, setConfirmDelete] = useState(false);
126
126
  const templateId = template.template_id ?? null;
127
127
  const requireTemplateId = () => {
@@ -157,7 +157,7 @@ function TemplateCard({ projectId, template, canManage, onEdit, }) {
157
157
  missing: t('states.notBuilt'),
158
158
  unknown: t('states.unknown'),
159
159
  });
160
- const source = describeSource(template, manifestVersion, {
160
+ const source = describeSource(template, manifestPath, {
161
161
  platform: t('sources.platform'),
162
162
  dashboard: t('sources.dashboard'),
163
163
  });
@@ -182,7 +182,7 @@ const TEMPLATE_SKELETON_HEIGHT = 'h-60';
182
182
  * read. Kept separate from `SandboxTab` so this renders under
183
183
  * `renderToStaticMarkup` with no `QueryClientProvider` — see
184
184
  * `GeneralTabView` for the same split. */
185
- export function SandboxTabView({ isLoading = false, isError = false, errorMessage = '', onRetry = () => { }, headerAction, manifestVersion = null, templatesError = null, isEmpty = true, emptyAction, templatesSlot, copy: copyOverride, }) {
185
+ export function SandboxTabView({ isLoading = false, isError = false, errorMessage = '', onRetry = () => { }, headerAction, manifestPath = 'kortix.yaml', templatesError = null, isEmpty = true, emptyAction, templatesSlot, copy: copyOverride, }) {
186
186
  const t = useTranslations('settings.sandbox');
187
187
  const copy = copyOverride ?? {
188
188
  loadFailed: t('loadFailed'),
@@ -194,7 +194,7 @@ export function SandboxTabView({ isLoading = false, isError = false, errorMessag
194
194
  emptyDescription: t('emptyDescription'),
195
195
  };
196
196
  const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
197
- return (_jsx("div", { className: "mx-auto w-full max-w-2xl space-y-8", children: _jsxs("div", { className: "space-y-8", children: [_jsx(SettingsTabHeader, { tab: "sandbox", action: headerAction }), isLoading ? (_jsx("div", { className: "space-y-2", children: TEMPLATE_SKELETON_ROWS.map((row) => (_jsx(Skeleton, { className: cn(TEMPLATE_SKELETON_HEIGHT, 'rounded-md') }, row))) })) : isError ? (_jsx(ErrorState, { size: "sm", title: copy.loadFailed, description: errorMessage, action: _jsx(Button, { variant: "outline", size: "sm", onClick: onRetry, children: copy.retry }) })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("p", { className: "text-muted-foreground text-sm text-pretty", children: [copy.descriptionStart, " ", _jsx("code", { className: "font-mono", children: "/workspace" }), ".", ' ', copy.descriptionEnd, ' ', manifestFilename(manifestVersion) === 'kortix.yaml' ? (_jsxs(_Fragment, { children: [_jsx("code", { className: "font-mono", children: "sandbox.templates" }), ' ', tI18nComplete.raw('text582967534d0f'), ' ', _jsx("code", { className: "font-mono", children: "kortix.yaml" })] })) : (_jsxs(_Fragment, { children: [_jsx("code", { className: "font-mono", children: "[[sandbox.templates]]" }), ' ', tI18nComplete.raw('text582967534d0f'), ' ', _jsx("code", { className: "font-mono", children: "kortix.toml" })] })), "."] }), templatesError ? (_jsxs(InfoBanner, { tone: "warning", children: [copy.configReadFailed, " ", templatesError] })) : null, isEmpty ? (_jsx(EmptyState, { icon: ShippingContainerIcon, size: "sm", title: copy.emptyTitle, description: copy.emptyDescription, action: emptyAction })) : (templatesSlot)] }))] }) }));
197
+ return (_jsx("div", { className: "mx-auto w-full max-w-2xl space-y-8", children: _jsxs("div", { className: "space-y-8", children: [_jsx(SettingsTabHeader, { tab: "sandbox", action: headerAction }), isLoading ? (_jsx("div", { className: "space-y-2", children: TEMPLATE_SKELETON_ROWS.map((row) => (_jsx(Skeleton, { className: cn(TEMPLATE_SKELETON_HEIGHT, 'rounded-md') }, row))) })) : isError ? (_jsx(ErrorState, { size: "sm", title: copy.loadFailed, description: errorMessage, action: _jsx(Button, { variant: "outline", size: "sm", onClick: onRetry, children: copy.retry }) })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("p", { className: "text-muted-foreground text-sm text-pretty", children: [copy.descriptionStart, " ", _jsx("code", { className: "font-mono", children: "/workspace" }), ".", ' ', copy.descriptionEnd, ' ', _jsx("code", { className: "font-mono", children: "sandbox.templates" }), ' ', tI18nComplete.raw('text582967534d0f'), ' ', _jsx("code", { className: "font-mono", children: manifestPath }), "."] }), templatesError ? (_jsxs(InfoBanner, { tone: "warning", children: [copy.configReadFailed, " ", templatesError] })) : null, isEmpty ? (_jsx(EmptyState, { icon: ShippingContainerIcon, size: "sm", title: copy.emptyTitle, description: copy.emptyDescription, action: emptyAction })) : (templatesSlot)] }))] }) }));
198
198
  }
199
199
  /** Container: owns every hook (project + snapshots queries, the template
200
200
  * form's open/edit state) and renders `SandboxTabView` with real data +
@@ -206,7 +206,7 @@ export function SandboxTab({ projectId }) {
206
206
  const t = useTranslations('settings.sandbox');
207
207
  const caps = useProjectCans(projectId, SANDBOX_TAB_ACTIONS);
208
208
  const canManage = caps[PROJECT_ACTIONS.PROJECT_SANDBOX_WRITE]?.allowed === true;
209
- const { version: manifestVersion } = useProjectManifestVersion(projectId);
209
+ const manifestPath = useProjectManifestHealth(projectId)?.path ?? 'kortix.yaml';
210
210
  const snapshotsQuery = useQuery({
211
211
  queryKey: qk.project.snapshots(projectId),
212
212
  queryFn: () => listProjectSnapshots(projectId),
@@ -235,5 +235,5 @@ export function SandboxTab({ projectId }) {
235
235
  setFormOpen(true);
236
236
  };
237
237
  const newTemplateAction = canManage ? (_jsxs(Button, { size: "sm", variant: "outline", className: "gap-1.5 transition-transform active:scale-[0.96]", onClick: openNewForm, children: [_jsx(PlusIcon, { className: "size-3.5 shrink-0" }), t('actions.new')] })) : undefined;
238
- return (_jsxs(_Fragment, { children: [_jsx(SandboxTabView, { isLoading: snapshotsQuery.isLoading, isError: snapshotsQuery.isError, errorMessage: snapshotsQuery.error?.message ?? '', onRetry: () => snapshotsQuery.refetch(), headerAction: canManage ? (_jsxs(Button, { size: "sm", variant: "secondary", className: "gap-1.5 transition-transform active:scale-[0.96]", onClick: openNewForm, children: [_jsx(PlusIcon, { className: "size-4 shrink-0" }), t('actions.new')] })) : undefined, manifestVersion: manifestVersion, templatesError: data?.templates_error ?? null, isEmpty: templates.length === 0, emptyAction: newTemplateAction, templatesSlot: templates.length === 0 ? undefined : (_jsx("ul", { className: "space-y-2", children: templates.map((t) => (_jsx(TemplateCard, { projectId: projectId, template: t, canManage: canManage, onEdit: openEditForm }, t.template_id ?? `tpl-${t.slug}`))) })) }), _jsx(SandboxTemplateForm, { projectId: projectId, open: formOpen, onOpenChange: setFormOpen, template: editingTemplate })] }));
238
+ return (_jsxs(_Fragment, { children: [_jsx(SandboxTabView, { isLoading: snapshotsQuery.isLoading, isError: snapshotsQuery.isError, errorMessage: snapshotsQuery.error?.message ?? '', onRetry: () => snapshotsQuery.refetch(), headerAction: canManage ? (_jsxs(Button, { size: "sm", variant: "secondary", className: "gap-1.5 transition-transform active:scale-[0.96]", onClick: openNewForm, children: [_jsx(PlusIcon, { className: "size-4 shrink-0" }), t('actions.new')] })) : undefined, manifestPath: manifestPath, templatesError: data?.templates_error ?? null, isEmpty: templates.length === 0, emptyAction: newTemplateAction, templatesSlot: templates.length === 0 ? undefined : (_jsx("ul", { className: "space-y-2", children: templates.map((t) => (_jsx(TemplateCard, { projectId: projectId, template: t, canManage: canManage, onEdit: openEditForm }, t.template_id ?? `tpl-${t.slug}`))) })) }), _jsx(SandboxTemplateForm, { projectId: projectId, open: formOpen, onOpenChange: setFormOpen, template: editingTemplate })] }));
239
239
  }
@@ -0,0 +1,39 @@
1
+ import type { ReactNode } from 'react';
2
+ export { plainGrantSwitch } from './agent-resource-scope.js';
3
+ export interface AccessItem {
4
+ id: string;
5
+ /** Defaults to the id, in mono: most items are names a person types. */
6
+ title?: ReactNode;
7
+ /** A real logo only (a connector's app mark). */
8
+ leading?: ReactNode;
9
+ /** One line. The whole text shows on hover. */
10
+ description?: ReactNode;
11
+ /** An exception only (Needs auth, Not set). The normal state carries none. */
12
+ status?: ReactNode;
13
+ /** The row's rule beside its switch, in the agent page's rail layout: Ask, Allow, a policy set. */
14
+ control?: ReactNode;
15
+ /** Opens the item (a skill's files, a connector's page): the name becomes a link-like button. */
16
+ onOpen?: () => void;
17
+ /** Absent: the row has no switch (an always-on extension). */
18
+ checked?: boolean;
19
+ onCheckedChange?: (on: boolean) => void;
20
+ disabled?: boolean;
21
+ }
22
+ export declare function AccessList({ items, quiet }: {
23
+ items: AccessItem[];
24
+ quiet?: boolean;
25
+ }): import("react").JSX.Element;
26
+ /** The project's own items: the first thing a view shows. */
27
+ export declare function AccessGroup({ title, items, empty }: {
28
+ title: string;
29
+ items: AccessItem[];
30
+ empty?: string;
31
+ }): import("react").JSX.Element;
32
+ /**
33
+ * What Kortix ships, after the project's items and folded: open by default
34
+ * only when the project has none of its own, so the view is never empty.
35
+ */
36
+ export declare function BuiltinGroup({ items, defaultOpen }: {
37
+ items: AccessItem[];
38
+ defaultOpen: boolean;
39
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,62 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * One look for every view of the agent page's Access tab (Marko, 2026-10-27:
5
+ * "top notch unified UX; built-in stuff more lowkey than the project's").
6
+ *
7
+ * lead line ............................ Manage
8
+ * Kortix can use [All ▾] what the mode means
9
+ * ┌ the project's items, one row each ┐
10
+ * › Built-in · 9 of 12 (a quiet fold, after the project's items)
11
+ *
12
+ * Every row is the same: name, one muted line, an exception mark, a switch.
13
+ * Skills, Tools, Extensions, Connectors, Secrets and Apps draw from here, so
14
+ * a change to the row changes every view.
15
+ */
16
+ import { CaretRightIcon } from '@phosphor-icons/react';
17
+ import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
18
+ import { cn } from '../../internal/lib/utils.js';
19
+ import { Disclosure, DisclosureContent, DisclosureTrigger } from '../../primitives/disclosure.js';
20
+ import { Switch } from '../../primitives/switch.js';
21
+ import { EditorList } from '../sections/view/agent-editor-primitives.js';
22
+ import { useCapabilityShellEmbed } from './capability-page-shell.js';
23
+ export { plainGrantSwitch } from './agent-resource-scope.js';
24
+ /** A one-line description reads as text: Markdown code ticks (a skill's routing text) are dropped. */
25
+ const plain = (text) => text.replace(/`([^`]*)`/g, '$1');
26
+ function AccessText({ item, quiet }) {
27
+ return (_jsxs(_Fragment, { children: [_jsx("span", { className: cn('block truncate text-sm leading-5 underline-offset-4 group-hover/open:underline', quiet ? 'text-muted-foreground' : 'text-foreground'), children: item.title ?? _jsx("span", { className: "font-mono !tracking-normal", children: item.id }) }), item.description ? (_jsx("span", { className: "text-muted-foreground mt-1 block truncate text-xs", title: typeof item.description === 'string' ? plain(item.description) : undefined, children: typeof item.description === 'string' ? plain(item.description) : item.description })) : null] }));
28
+ }
29
+ /**
30
+ * The agent page's rail layout: one filled, bordered card, a divider between rows; a row that is
31
+ * switched off reads muted; the row's rule sits left of its switch.
32
+ */
33
+ function CardAccessList({ items }) {
34
+ const t = useI18nTranslations('agentCapabilities');
35
+ return (_jsx("ul", { className: "bg-popover divide-border divide-y overflow-hidden rounded-lg border", children: items.map((item) => {
36
+ const off = item.onCheckedChange !== undefined && !item.checked;
37
+ return (_jsxs("li", { "data-capability": item.id, className: cn('flex min-h-12 items-center gap-3 px-4 py-2.5', item.disabled && 'opacity-60'), children: [item.leading, item.onOpen ? (_jsx("button", { type: "button", onClick: item.onOpen, className: "group/open focus-visible:ring-ring min-w-0 flex-1 rounded-sm text-left focus-visible:ring-2 focus-visible:outline-none", children: _jsx(AccessText, { item: item, quiet: off }) })) : (_jsx("span", { className: "min-w-0 flex-1", children: _jsx(AccessText, { item: item, quiet: off }) })), item.status ? _jsx("span", { className: "flex shrink-0 items-center gap-2", children: item.status }) : null, item.control !== undefined ? (_jsx("span", { className: "text-muted-foreground flex shrink-0 justify-end text-xs", children: item.control })) : null, item.onCheckedChange ? (_jsx(Switch, { checked: item.checked ?? false, disabled: item.disabled, onCheckedChange: item.onCheckedChange, "aria-label": t('toggle', { name: typeof item.title === 'string' ? item.title : item.id }) })) : null] }, item.id));
38
+ }) }));
39
+ }
40
+ export function AccessList({ items, quiet = false }) {
41
+ const t = useI18nTranslations('agentCapabilities');
42
+ const embed = useCapabilityShellEmbed();
43
+ if (embed?.titled)
44
+ return _jsx(CardAccessList, { items: items });
45
+ return (_jsx(EditorList, { children: items.map((item) => (_jsxs("li", { "data-capability": item.id, className: cn('flex min-h-12 items-center gap-3 px-4 py-2', item.disabled && 'opacity-60'), children: [item.leading, item.onOpen ? (_jsx("button", { type: "button", onClick: item.onOpen, className: "group/open focus-visible:ring-ring min-w-0 flex-1 rounded-sm text-left focus-visible:ring-2 focus-visible:outline-none", children: _jsx(AccessText, { item: item, quiet: quiet }) })) : (_jsx("span", { className: "min-w-0 flex-1", children: _jsx(AccessText, { item: item, quiet: quiet }) })), item.status ? _jsx("span", { className: "flex shrink-0 items-center gap-2", children: item.status }) : null, item.onCheckedChange ? (_jsx(Switch, { checked: item.checked ?? false, disabled: item.disabled, onCheckedChange: item.onCheckedChange, "aria-label": t('toggle', { name: typeof item.title === 'string' ? item.title : item.id }) })) : null] }, item.id))) }));
46
+ }
47
+ /** The project's own items: the first thing a view shows. */
48
+ export function AccessGroup({ title, items, empty }) {
49
+ return (_jsxs("section", { className: "space-y-3", children: [_jsx("h3", { className: "text-foreground text-sm font-medium", children: title }), items.length > 0 ? (_jsx(AccessList, { items: items })) : empty ? (_jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: empty })) : null] }));
50
+ }
51
+ /**
52
+ * What Kortix ships, after the project's items and folded: open by default
53
+ * only when the project has none of its own, so the view is never empty.
54
+ */
55
+ export function BuiltinGroup({ items, defaultOpen }) {
56
+ const t = useI18nTranslations('agentCapabilities');
57
+ if (items.length === 0)
58
+ return null;
59
+ const switchable = items.filter((item) => item.onCheckedChange);
60
+ const on = switchable.filter((item) => item.checked).length;
61
+ return (_jsxs(Disclosure, { defaultOpen: defaultOpen, className: "group/builtin space-y-3", children: [_jsx(DisclosureTrigger, { children: _jsxs("button", { type: "button", className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring flex items-center gap-1.5 rounded-sm text-sm focus-visible:ring-2 focus-visible:outline-none", children: [_jsx(CaretRightIcon, { "aria-hidden": true, className: "size-3.5 shrink-0 group-data-[state=open]/builtin:rotate-90" }), t('groups.builtin'), switchable.length > 0 ? (_jsx("span", { className: "tabular-nums", children: t('builtinOn', { on, total: switchable.length }) })) : null] }) }), _jsx(DisclosureContent, { children: _jsx(AccessList, { items: items, quiet: true }) })] }));
62
+ }