@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.
- package/README.md +1 -1
- package/dist/_vendor/kortix-shared.js +521 -7045
- package/dist/_vendor/shared/app-config.d.ts +8 -0
- package/dist/_vendor/shared/artifact-annotations.d.ts +708 -0
- package/dist/_vendor/shared/artifact-comments.d.ts +327 -0
- package/dist/_vendor/shared/index.d.ts +3 -1
- package/dist/_vendor/shared/my-kortix-agent.d.ts +40 -0
- package/dist/_vendor/shared/peer-message-prompt.d.ts +35 -0
- package/dist/_vendor/shared/pixel-mark.d.ts +11 -0
- package/dist/_vendor/shared/prompt-attachments.d.ts +1 -0
- package/dist/_vendor/shared/reminder-prompt.d.ts +8 -2
- package/dist/_vendor/shared/runtime-versions.d.ts +8 -0
- package/dist/artifacts/artifact-frame.d.ts +1 -0
- package/dist/artifacts/artifact-frame.js +18 -5
- package/dist/artifacts/frame-policy.d.ts +1 -1
- package/dist/artifacts/frame-policy.js +10 -5
- package/dist/customize/agents/agent-access-text.d.ts +16 -0
- package/dist/customize/agents/agent-access-text.js +54 -0
- package/dist/customize/agents/agent-approval-rules.d.ts +8 -0
- package/dist/customize/agents/agent-approval-rules.js +26 -0
- package/dist/customize/agents/agent-authority-card.js +4 -1
- package/dist/customize/agents/agent-cover-card.d.ts +4 -1
- package/dist/customize/agents/agent-cover-card.js +2 -2
- package/dist/customize/agents/agent-detail-aside.d.ts +1 -2
- package/dist/customize/agents/agent-detail-aside.js +8 -11
- package/dist/customize/agents/agent-drives-section.d.ts +23 -7
- package/dist/customize/agents/agent-drives-section.js +107 -41
- package/dist/customize/agents/agent-instructions.d.ts +11 -0
- package/dist/customize/agents/agent-instructions.js +114 -0
- package/dist/customize/agents/agent-model-view.d.ts +17 -0
- package/dist/customize/agents/agent-model-view.js +67 -0
- package/dist/customize/agents/agent-overview.d.ts +53 -0
- package/dist/customize/agents/agent-overview.js +242 -0
- package/dist/customize/agents/agent-page-chrome.d.ts +128 -0
- package/dist/customize/agents/agent-page-chrome.js +145 -0
- package/dist/customize/agents/agent-page.d.ts +13 -1
- package/dist/customize/agents/agent-page.js +478 -367
- package/dist/customize/agents/agent-pin-button.d.ts +10 -0
- package/dist/customize/agents/agent-pin-button.js +20 -0
- package/dist/customize/agents/agent-policy-sets-section.d.ts +16 -0
- package/dist/customize/agents/agent-policy-sets-section.js +80 -0
- package/dist/customize/agents/agent-policy-sets.js +1 -1
- package/dist/customize/agents/agent-section-rail.d.ts +21 -0
- package/dist/customize/agents/agent-section-rail.js +23 -0
- package/dist/customize/agents/agent-share-control.d.ts +4 -3
- package/dist/customize/agents/agent-share-control.js +15 -16
- package/dist/customize/agents/{agent-people-section.d.ts → agent-share-dialog.d.ts} +3 -1
- package/dist/customize/agents/{agent-people-section.js → agent-share-dialog.js} +21 -21
- package/dist/customize/agents/agent-tabs.d.ts +95 -0
- package/dist/customize/agents/agent-tabs.js +199 -0
- package/dist/customize/agents/agents-page.d.ts +0 -21
- package/dist/customize/agents/agents-page.js +104 -118
- package/dist/customize/agents/connectors-required.d.ts +16 -0
- package/dist/customize/agents/connectors-required.js +19 -0
- package/dist/customize/agents/create-agent-modal.d.ts +19 -0
- package/dist/customize/agents/create-agent-modal.js +94 -0
- package/dist/customize/connectors/agent-access.d.ts +4 -4
- package/dist/customize/connectors/agent-access.js +7 -10
- package/dist/customize/connectors/connector-identity.d.ts +12 -0
- package/dist/customize/connectors/connector-identity.js +15 -2
- package/dist/customize/connectors/connector-routes.js +2 -2
- package/dist/customize/connectors/connectors-page.d.ts +14 -1
- package/dist/customize/connectors/connectors-page.js +101 -32
- package/dist/customize/connectors/detail/app-page.js +1 -1
- package/dist/customize/connectors/detail/connector-agents.js +0 -3
- package/dist/customize/connectors/detail/connector-page.d.ts +1 -1
- package/dist/customize/connectors/detail/connector-page.js +5 -2
- package/dist/customize/connectors/detail/connector-policy-sets.js +1 -1
- package/dist/customize/connectors/detail/connector-triggers.js +2 -2
- package/dist/customize/connectors/use-agent-access.d.ts +7 -5
- package/dist/customize/connectors/use-agent-access.js +2 -6
- package/dist/customize/models/models-page.d.ts +7 -1
- package/dist/customize/models/models-page.js +2 -2
- package/dist/customize/project-settings/project-admin-sections.d.ts +63 -0
- package/dist/customize/project-settings/project-admin-sections.js +80 -0
- package/dist/customize/project-settings/project-settings-page.d.ts +1 -1
- package/dist/customize/project-settings/project-settings-page.js +4 -13
- package/dist/customize/project-settings/project-settings-sections.d.ts +5 -5
- package/dist/customize/project-settings/project-settings-sections.js +6 -20
- package/dist/customize/providers/provider-accordion.js +29 -17
- package/dist/customize/providers/provider-connect.js +1 -1
- package/dist/customize/providers/provider-sheet.d.ts +4 -1
- package/dist/customize/providers/provider-sheet.js +15 -5
- package/dist/customize/secrets/secrets-page.d.ts +5 -1
- package/dist/customize/secrets/secrets-page.js +2 -2
- package/dist/customize/sections/gateway-view.d.ts +10 -2
- package/dist/customize/sections/gateway-view.js +16 -4
- package/dist/customize/sections/llm-provider/chatgpt-subscription-connect.d.ts +12 -5
- package/dist/customize/sections/llm-provider/chatgpt-subscription-connect.js +131 -8
- package/dist/customize/sections/llm-provider/claude-code-step.d.ts +10 -0
- package/dist/customize/sections/llm-provider/claude-code-step.js +32 -0
- package/dist/customize/sections/llm-provider/models-tab.js +5 -1
- package/dist/customize/sections/view/account-secret-resources-panel.d.ts +5 -3
- package/dist/customize/sections/view/account-secret-resources-panel.js +122 -19
- package/dist/customize/sections/view/agent-editor-access-fields.d.ts +1 -1
- package/dist/customize/sections/view/agent-editor-access-fields.js +8 -4
- package/dist/customize/sections/view/agent-editor-basics-fields.d.ts +4 -1
- package/dist/customize/sections/view/agent-editor-basics-fields.js +33 -4
- package/dist/customize/sections/view/agent-editor-catalog.d.ts +2 -2
- package/dist/customize/sections/view/agent-editor-catalog.js +10 -12
- package/dist/customize/sections/view/agent-editor-primitives.d.ts +1 -1
- package/dist/customize/sections/view/agent-editor-primitives.js +4 -4
- package/dist/customize/sections/view/agent-editor.d.ts +37 -26
- package/dist/customize/sections/view/agent-editor.js +19 -19
- package/dist/customize/sections/view/grant-mode-field.d.ts +8 -20
- package/dist/customize/sections/view/grant-mode-field.js +31 -57
- package/dist/customize/sections/view/permission-editor.d.ts +3 -1
- package/dist/customize/sections/view/permission-editor.js +19 -10
- package/dist/customize/sections/view/review-view.d.ts +8 -0
- package/dist/customize/sections/view/review-view.js +12 -1
- package/dist/customize/sections/view/secret-delivery.js +1 -4
- package/dist/customize/sections/view/secrets-view.d.ts +7 -1
- package/dist/customize/sections/view/secrets-view.js +42 -6
- package/dist/customize/settings/rail.js +2 -8
- package/dist/customize/settings/settings-tabs.d.ts +2 -2
- package/dist/customize/settings/settings-tabs.js +17 -19
- package/dist/customize/settings/tabs/experimental-tab.d.ts +3 -0
- package/dist/customize/settings/tabs/experimental-tab.js +6 -1
- package/dist/customize/settings/tabs/sandbox-tab.d.ts +4 -6
- package/dist/customize/settings/tabs/sandbox-tab.js +9 -9
- package/dist/customize/shared/access-list.d.ts +39 -0
- package/dist/customize/shared/access-list.js +62 -0
- package/dist/customize/shared/agent-resource-scope.d.ts +87 -0
- package/dist/customize/shared/agent-resource-scope.js +123 -0
- package/dist/customize/shared/capability-library.d.ts +41 -0
- package/dist/customize/shared/capability-library.js +271 -0
- package/dist/customize/shared/capability-page-shell.d.ts +18 -1
- package/dist/customize/shared/capability-page-shell.js +21 -1
- package/dist/customize/shared/catalog/catalog-space-tabs.d.ts +14 -0
- package/dist/customize/shared/catalog/catalog-space-tabs.js +20 -0
- package/dist/customize/shared/customize-tab-bar.d.ts +13 -0
- package/dist/customize/shared/customize-tab-bar.js +95 -0
- package/dist/customize/shared/entity/entity-modal.d.ts +17 -1
- package/dist/customize/shared/entity/entity-modal.js +10 -9
- package/dist/customize/shared/leave-guard.d.ts +23 -0
- package/dist/customize/shared/leave-guard.js +87 -0
- package/dist/customize/shared/standalone-settings-nav.js +4 -1
- package/dist/customize/shared/tool-rules.d.ts +11 -0
- package/dist/customize/shared/tool-rules.js +29 -0
- package/dist/customize/skills/builtin-skill-modal.d.ts +6 -0
- package/dist/customize/skills/builtin-skill-modal.js +41 -0
- package/dist/customize/skills/skills-page.d.ts +21 -18
- package/dist/customize/skills/skills-page.js +16 -110
- package/dist/customize/triggers/runtime-triggers.d.ts +17 -0
- package/dist/customize/triggers/runtime-triggers.js +57 -0
- package/dist/customize/triggers/schedule/event-trigger-copy.js +2 -2
- package/dist/customize/triggers/schedule/post-to-field.js +2 -2
- package/dist/customize/triggers/schedule/schedule-copy.d.ts +11 -6
- package/dist/customize/triggers/schedule/schedule-copy.js +29 -8
- package/dist/customize/triggers/schedule/schedule-detail-sheet.js +7 -3
- package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +26 -1
- package/dist/customize/triggers/schedule/trigger-composer-logic.js +64 -3
- package/dist/customize/triggers/schedule/trigger-composer.js +57 -20
- package/dist/customize/triggers/schedule/trigger-edit-logic.js +18 -5
- package/dist/customize/triggers/schedule/trigger-filter.d.ts +10 -0
- package/dist/customize/triggers/schedule/trigger-filter.js +16 -0
- package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
- package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
- package/dist/customize/triggers/schedule/use-trigger-mutations.d.ts +1 -1
- package/dist/customize/triggers/schedule/use-trigger-mutations.js +1 -1
- package/dist/customize/triggers/schedule/when-app.d.ts +15 -0
- package/dist/customize/triggers/schedule/when-app.js +21 -0
- package/dist/customize/triggers/schedule/when-change-request.d.ts +10 -0
- package/dist/customize/triggers/schedule/when-change-request.js +15 -0
- package/dist/customize/triggers/schedule-view.d.ts +17 -3
- package/dist/customize/triggers/schedule-view.js +46 -16
- package/dist/customize/triggers/triggers-page.d.ts +3 -3
- package/dist/customize/triggers/triggers-page.js +2 -2
- package/dist/customize/use-configure-thread.d.ts +8 -2
- package/dist/customize/use-configure-thread.js +30 -18
- package/dist/files/project/components/change-request-detail-dialog.js +2 -3
- package/dist/files/project/components/drive-explorer.js +6 -5
- package/dist/files/project/explorer-source.d.ts +3 -0
- package/dist/files/project/upload-batch.d.ts +3 -3
- package/dist/files/project/upload-batch.js +7 -6
- package/dist/files/runtime/sandbox-explorer-source.js +3 -3
- package/dist/i18n/en.d.ts +1330 -53
- package/dist/i18n/en.js +1422 -145
- package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +16 -7
- package/dist/internal/auth/auth-primitives.d.ts +1 -3
- package/dist/internal/auth/auth-primitives.js +2 -2
- package/dist/internal/billing/session-cost-format.d.ts +1 -0
- package/dist/internal/billing/session-cost-format.js +11 -0
- package/dist/internal/components/agent-mark.d.ts +12 -1
- package/dist/internal/components/agent-mark.js +34 -11
- package/dist/internal/components/nav-rail.d.ts +22 -0
- package/dist/internal/components/nav-rail.js +16 -0
- package/dist/internal/components/repository-disconnected.js +2 -2
- package/dist/internal/goals/goal-meta.d.ts +15 -1
- package/dist/internal/goals/goal-meta.js +42 -2
- package/dist/internal/hooks/projects/use-agent-config.d.ts +11 -7
- package/dist/internal/hooks/projects/use-agent-config.js +28 -11
- package/dist/internal/hooks/use-slash-focus.d.ts +7 -1
- package/dist/internal/hooks/use-slash-focus.js +9 -3
- package/dist/internal/layout/project-capability-nav.d.ts +24 -0
- package/dist/internal/layout/project-capability-nav.js +86 -0
- package/dist/internal/layout/project-page-header.d.ts +1 -1
- package/dist/internal/layout/project-page-header.js +1 -1
- package/dist/internal/layout/project-settings-nav.d.ts +3 -2
- package/dist/internal/layout/project-settings-nav.js +5 -3
- package/dist/internal/lib/browser-noise/rules/old-browsers.js +1 -1
- package/dist/internal/lib/capability-tab-routes.d.ts +34 -3
- package/dist/internal/lib/capability-tab-routes.js +76 -8
- package/dist/internal/lib/manifest-health.d.ts +10 -0
- package/dist/internal/lib/manifest-health.js +20 -0
- package/dist/internal/lib/pixel-mark.d.ts +4 -1
- package/dist/internal/lib/pixel-mark.js +33 -6
- package/dist/internal/lib/project-actions.d.ts +1 -1
- package/dist/internal/lib/project-actions.js +0 -4
- package/dist/internal/lib/provider-branding.js +2 -0
- package/dist/internal/lib/space-scope.d.ts +29 -0
- package/dist/internal/lib/space-scope.js +28 -0
- package/dist/internal/lib/use-project-feature-flags.js +3 -3
- package/dist/internal/lib/web-notifications.d.ts +74 -8
- package/dist/internal/lib/web-notifications.js +243 -117
- package/dist/internal/notifications/notification-rows.d.ts +14 -7
- package/dist/internal/notifications/notification-rows.js +21 -14
- package/dist/internal/notifications/session-toast-cards.d.ts +2 -2
- package/dist/internal/reminders/reminder-format.d.ts +6 -2
- package/dist/internal/reminders/reminder-format.js +7 -1
- package/dist/internal/stores/active-space-store.d.ts +35 -0
- package/dist/internal/stores/active-space-store.js +29 -0
- package/dist/internal/stores/kortix-computer-store.js +13 -4
- package/dist/internal/stores/pinned-agents-store.d.ts +26 -0
- package/dist/internal/stores/pinned-agents-store.js +20 -0
- package/dist/internal/stores/session-panel-memory-store.js +3 -0
- package/dist/internal/stores/turn-attention-store.d.ts +5 -4
- package/dist/lib/routes.d.ts +16 -1
- package/dist/lib/routes.js +15 -3
- package/dist/markdown/doc-editor/doc-embed.d.ts +31 -0
- package/dist/markdown/doc-editor/doc-embed.js +168 -0
- package/dist/markdown/doc-editor/doc-extensions.d.ts +26 -0
- package/dist/markdown/doc-editor/doc-extensions.js +149 -0
- package/dist/markdown/doc-editor/doc-menus.d.ts +9 -0
- package/dist/markdown/doc-editor/doc-menus.js +56 -0
- package/dist/markdown/doc-editor/markdown.d.ts +12 -0
- package/dist/markdown/doc-editor/markdown.js +140 -0
- package/dist/markdown/genui/components/inline.d.ts +1 -1
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/button.d.ts +1 -1
- package/dist/primitives/pixel-kortix-mark.d.ts +5 -4
- package/dist/primitives/pixel-kortix-mark.js +5 -15
- package/dist/primitives/tag.d.ts +1 -1
- package/dist/primitives/textarea.js +14 -0
- package/dist/primitives/toast.d.ts +2 -0
- package/dist/primitives/toast.js +4 -2
- package/dist/providers/ui-provider.d.ts +16 -0
- package/dist/session/actions/session-label.d.ts +1 -1
- package/dist/session/actions/session-label.js +3 -3
- package/dist/session/agents/agent-model.d.ts +92 -0
- package/dist/session/agents/agent-model.js +123 -0
- package/dist/session/agents/agent-state-mark.d.ts +10 -0
- package/dist/session/agents/agent-state-mark.js +22 -0
- package/dist/session/agents/agent-strip.d.ts +58 -0
- package/dist/session/agents/agent-strip.js +259 -0
- package/dist/session/agents/held-messages.d.ts +33 -0
- package/dist/session/agents/held-messages.js +50 -0
- package/dist/session/agents/legacy-subagent-chat.d.ts +11 -0
- package/dist/session/agents/legacy-subagent-chat.js +19 -0
- package/dist/session/agents/session-peek.d.ts +20 -0
- package/dist/session/agents/session-peek.js +67 -0
- package/dist/session/agents/session-prompt.d.ts +13 -0
- package/dist/session/agents/session-prompt.js +18 -0
- package/dist/session/agents/steer-session.d.ts +13 -0
- package/dist/session/agents/steer-session.js +29 -0
- package/dist/session/agents/subagent-dialog-content.d.ts +11 -0
- package/dist/session/agents/subagent-dialog-content.js +115 -0
- package/dist/session/agents/subagent-view.d.ts +8 -0
- package/dist/session/agents/subagent-view.js +18 -0
- package/dist/session/agents/tasks-panel.d.ts +13 -0
- package/dist/session/agents/tasks-panel.js +41 -0
- package/dist/session/agents/workflow-run-controls.d.ts +43 -0
- package/dist/session/agents/workflow-run-controls.js +141 -0
- package/dist/session/composer/ComposerCard.d.ts +1 -1
- package/dist/session/composer/ComposerCard.js +3 -3
- package/dist/session/composer/agent-selector.js +13 -19
- package/dist/session/composer/composer-underbar.d.ts +3 -1
- package/dist/session/composer/composer-underbar.js +2 -2
- package/dist/session/composer/composer.d.ts +5 -0
- package/dist/session/composer/composer.js +16 -10
- package/dist/session/composer/editor/composer-editor.js +19 -8
- package/dist/session/composer/editor/ultracode.d.ts +34 -0
- package/dist/session/composer/editor/ultracode.js +127 -0
- package/dist/session/composer/send-blockers.d.ts +1 -11
- package/dist/session/composer/send-blockers.js +1 -11
- package/dist/session/composer/session-composer-readiness.d.ts +1 -28
- package/dist/session/composer/session-composer-readiness.js +5 -16
- package/dist/session/header/reminder-parts.d.ts +1 -1
- package/dist/session/header/session-site-header.js +6 -3
- package/dist/session/header/subagent-hover-card.d.ts +0 -2
- package/dist/session/header/subagent-hover-card.js +1 -4
- package/dist/session/models/claude-connection-slot.d.ts +11 -0
- package/dist/session/models/claude-connection-slot.js +30 -0
- package/dist/session/models/model-availability.d.ts +3 -1
- package/dist/session/models/model-availability.js +3 -0
- package/dist/session/models/model-selector.js +11 -12
- package/dist/session/models/model-tags.d.ts +9 -0
- package/dist/session/models/model-tags.js +8 -0
- package/dist/session/panel/easy/easy-panel.js +1 -1
- package/dist/session/panel/easy/step-icon.js +5 -1
- package/dist/session/panel/mobile-tool-drawer.js +1 -1
- package/dist/session/panel/session-action-panel-column.js +1 -1
- package/dist/session/panel/session-desktop.js +41 -14
- package/dist/session/panel/session-panel-provider.d.ts +1 -1
- package/dist/session/panel/session-panel-provider.js +7 -11
- package/dist/session/prompts/question-prompt.js +3 -1
- package/dist/session/status/session-error-banner.js +4 -1
- package/dist/session/thread/session-chat.js +286 -296
- package/dist/session/thread/session-context-modal.js +29 -10
- package/dist/session/thread/session-context-spawned-sessions.d.ts +13 -0
- package/dist/session/thread/session-context-spawned-sessions.js +44 -0
- package/dist/session/thread/session-context-sub-sessions.js +3 -8
- package/dist/session/thread/transcript.d.ts +3 -0
- package/dist/session/thread/transcript.js +32 -8
- package/dist/session/tool/shared/full-view-action.d.ts +29 -0
- package/dist/session/tool/shared/full-view-action.js +43 -0
- package/dist/session/tool/tool-part-renderer.js +10 -2
- package/dist/session/tool/tools/agent-message-tool.js +2 -2
- package/dist/session/tool/tools/agent-spawn-tool.js +2 -2
- package/dist/session/tool/tools/agent-status-tool.js +2 -2
- package/dist/session/tool/tools/kortix-action-tool.d.ts +2 -0
- package/dist/session/tool/tools/kortix-action-tool.js +148 -0
- package/dist/session/tool/tools/kortix-tool-card.d.ts +83 -0
- package/dist/session/tool/tools/kortix-tool-card.js +186 -0
- package/dist/session/tool/tools/multi-agent-tool-bodies.d.ts +11 -0
- package/dist/session/tool/tools/multi-agent-tool-bodies.js +141 -0
- package/dist/session/tool/tools/multi-agent-tool-data.d.ts +63 -0
- package/dist/session/tool/tools/multi-agent-tool-data.js +118 -0
- package/dist/session/tool/tools/multi-agent-tools.d.ts +9 -0
- package/dist/session/tool/tools/multi-agent-tools.js +38 -0
- package/dist/session/tool/tools/question-tool.js +1 -1
- package/dist/session/tool/tools/register.d.ts +3 -0
- package/dist/session/tool/tools/register.js +3 -0
- package/dist/session/tool/tools/session-spawn-tool.js +2 -2
- package/dist/session/tool/tools/task-tool.d.ts +1 -1
- package/dist/session/tool/tools/task-tool.js +29 -41
- package/dist/session/tool/tools/workflow-progress.d.ts +34 -0
- package/dist/session/tool/tools/workflow-progress.js +186 -0
- package/dist/session/tool/tools/workflow-run.d.ts +128 -0
- package/dist/session/tool/tools/workflow-run.js +251 -0
- package/dist/session/tool/tools/workflow-tool.d.ts +9 -0
- package/dist/session/tool/tools/workflow-tool.js +253 -0
- package/dist/session/turn/notice-batch-group.d.ts +12 -0
- package/dist/session/turn/notice-batch-group.js +17 -0
- package/dist/session/turn/peer-message-row.d.ts +14 -0
- package/dist/session/turn/peer-message-row.js +57 -0
- package/dist/session/turn/subagent-notice-row.d.ts +4 -0
- package/dist/session/turn/subagent-notice-row.js +50 -0
- package/dist/session/turn/subagent-notice.d.ts +58 -0
- package/dist/session/turn/subagent-notice.js +111 -0
- package/dist/session/turn/user-message.js +24 -5
- package/dist/styles/tokens.css +2 -0
- package/dist/styles.css +1 -1
- package/dist/terminal/session-terminal-connect-bar.js +1 -1
- package/dist/workspace/admin/project-admin-dashboard.d.ts +53 -0
- package/dist/workspace/admin/project-admin-dashboard.js +252 -0
- package/dist/workspace/admin/project-admin-nav.d.ts +20 -0
- package/dist/workspace/admin/project-admin-nav.js +41 -0
- package/dist/workspace/home/welcome-body.js +25 -3
- package/dist/workspace/index.d.ts +6 -2
- package/dist/workspace/index.js +12 -2
- package/dist/workspace/layout/new-session-create.js +3 -3
- package/dist/workspace/layout/project-home.js +3 -3
- package/dist/workspace/memory/memory-labels.js +5 -0
- package/dist/workspace/repository-disconnected.js +2 -2
- package/dist/workspace/sessions/board-dispatch.d.ts +52 -0
- package/dist/workspace/sessions/board-dispatch.js +110 -0
- package/dist/workspace/sessions/board-grouping.d.ts +63 -0
- package/dist/workspace/sessions/board-grouping.js +141 -0
- package/dist/workspace/sessions/board-peek.d.ts +15 -0
- package/dist/workspace/sessions/board-peek.js +54 -0
- package/dist/workspace/sessions/board-state-mark.d.ts +15 -0
- package/dist/workspace/sessions/board-state-mark.js +24 -0
- package/dist/workspace/sessions/project-sessions-view.js +42 -31
- package/dist/workspace/sessions/sessions-board.d.ts +12 -0
- package/dist/workspace/sessions/sessions-board.js +214 -0
- package/dist/workspace/sidebar/footer/project-manifest-issues-alert.d.ts +46 -0
- package/dist/workspace/sidebar/footer/project-manifest-issues-alert.js +85 -0
- package/dist/workspace/sidebar/footer/sidebar-alert.js +1 -1
- package/dist/workspace/sidebar/new-agent-modal-provider.d.ts +12 -0
- package/dist/workspace/sidebar/new-agent-modal-provider.js +19 -0
- package/dist/workspace/sidebar/project-nav-items.d.ts +3 -1
- package/dist/workspace/sidebar/project-nav-items.js +53 -5
- package/dist/workspace/sidebar/project-session-list.js +35 -12
- package/dist/workspace/sidebar/project-sidebar.js +6 -3
- package/dist/workspace/sidebar/session-filter-menu.js +2 -1
- package/dist/workspace/space/space-blocks.d.ts +25 -0
- package/dist/workspace/space/space-blocks.js +124 -0
- package/dist/workspace/space/space-filter-tabs.d.ts +17 -0
- package/dist/workspace/space/space-filter-tabs.js +31 -0
- package/dist/workspace/space/space-page.d.ts +24 -0
- package/dist/workspace/space/space-page.js +157 -0
- package/dist/workspace/space/space-room.d.ts +20 -0
- package/dist/workspace/space/space-room.js +27 -0
- package/dist/workspace/space/space-tab-menu.d.ts +14 -0
- package/dist/workspace/space/space-tab-menu.js +127 -0
- package/dist/workspace/space/space-tab-panels.d.ts +9 -0
- package/dist/workspace/space/space-tab-panels.js +203 -0
- package/dist/workspace/space/space-templates.d.ts +34 -0
- package/dist/workspace/space/space-templates.js +71 -0
- package/dist/workspace/space/use-space-filter.d.ts +10 -0
- package/dist/workspace/space/use-space-filter.js +40 -0
- package/dist/workspace/space/use-space-manifest.d.ts +8 -0
- package/dist/workspace/space/use-space-manifest.js +27 -0
- package/dist/workspace/spaces/space-timeline.js +2 -2
- package/package.json +56 -53
- package/skills/kortix-ui/SKILL.md +1 -1
- package/skills/kortix-ui/references/custom-dashboard.md +10 -4
- package/skills/kortix-ui/references/modules.md +10 -8
- package/dist/_vendor/shared/meta-agent.d.ts +0 -7
- package/dist/customize/agents/agent-grant-pages.d.ts +0 -37
- package/dist/customize/agents/agent-grant-pages.js +0 -226
- package/dist/customize/agents/agent-triggers-section.d.ts +0 -17
- package/dist/customize/agents/agent-triggers-section.js +0 -109
- package/dist/customize/migrate-to-v2/index.d.ts +0 -5
- package/dist/customize/migrate-to-v2/index.js +0 -5
- package/dist/customize/migrate-to-v2/migration-prompt.d.ts +0 -16
- package/dist/customize/migrate-to-v2/migration-prompt.js +0 -59
- package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +0 -30
- package/dist/customize/migrate-to-v2/upgrade-defs.js +0 -43
- package/dist/customize/migrate-to-v2/upgrade-view.d.ts +0 -32
- package/dist/customize/migrate-to-v2/upgrade-view.js +0 -152
- package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +0 -18
- package/dist/customize/migrate-to-v2/use-run-upgrade.js +0 -16
- package/dist/customize/shared/capability-tabs.d.ts +0 -3
- package/dist/customize/shared/capability-tabs.js +0 -137
- package/dist/customize/skills/skill-scope.d.ts +0 -14
- package/dist/customize/skills/skill-scope.js +0 -18
- package/dist/internal/lib/manifest-version.d.ts +0 -21
- package/dist/internal/lib/manifest-version.js +0 -55
- package/dist/session/composer/hooks/use-composer-escape-stop.d.ts +0 -6
- package/dist/session/composer/hooks/use-composer-escape-stop.js +0 -28
- package/dist/session/thread/sub-session-modal-content.d.ts +0 -8
- package/dist/session/thread/sub-session-modal-content.js +0 -23
- package/dist/session/thread/sub-session-modal.d.ts +0 -2
- package/dist/session/thread/sub-session-modal.js +0 -14
- package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.d.ts +0 -13
- package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +0 -48
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { AgentDraft } from '../sections/view/agent-editor.js';
|
|
3
|
+
export declare function AgentApprovalRules({ projectId, editor, rules, }: {
|
|
4
|
+
projectId: string;
|
|
5
|
+
editor: AgentDraft;
|
|
6
|
+
/** The rules editor Edit rules unfolds. */
|
|
7
|
+
rules: ReactNode;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { capabilityGranted } from '@kortix/sdk';
|
|
4
|
+
import { ShieldIcon } from '@phosphor-icons/react';
|
|
5
|
+
import { useState } from 'react';
|
|
6
|
+
import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
|
|
7
|
+
import { useProjectCapabilities } from '../../internal/hooks/projects/use-agent-config.js';
|
|
8
|
+
import { Button } from '../../primitives/button.js';
|
|
9
|
+
import { deniedPatterns, toolRule } from '../shared/tool-rules.js';
|
|
10
|
+
export function AgentApprovalRules({ projectId, editor, rules, }) {
|
|
11
|
+
const t = useI18nTranslations('agentEditor.tabs');
|
|
12
|
+
const [open, setOpen] = useState(false);
|
|
13
|
+
const tools = useProjectCapabilities(projectId).data?.tools ?? [];
|
|
14
|
+
const permission = editor.oc.permission;
|
|
15
|
+
const asking = tools.filter((tool) => capabilityGranted(editor.draft.tools, tool.id, 'all') && toolRule(permission, tool.id) === 'ask').length;
|
|
16
|
+
const denied = deniedPatterns(permission);
|
|
17
|
+
const sentence = asking === 0 && denied.length === 0
|
|
18
|
+
? t('approvalNone')
|
|
19
|
+
: [
|
|
20
|
+
asking > 0 ? t('approvalAsk', { count: asking }) : null,
|
|
21
|
+
denied.length > 0 ? t('approvalDenied', { list: denied.join(', ') }) : null,
|
|
22
|
+
]
|
|
23
|
+
.filter(Boolean)
|
|
24
|
+
.join(' ');
|
|
25
|
+
return (_jsxs("div", { className: "space-y-5", children: [_jsxs("div", { className: "bg-popover flex items-center gap-3 rounded-lg px-4 py-3", children: [_jsx(ShieldIcon, { className: "text-muted-foreground size-4 shrink-0" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-foreground text-sm font-medium", children: t('approvalTitle') }), _jsx("p", { className: "text-muted-foreground text-xs text-pretty", children: sentence })] }), _jsx(Button, { variant: "secondary", size: "sm", "aria-expanded": open, onClick: () => setOpen((v) => !v), children: open ? t('hideRules') : t('editRules') })] }), open ? rules : null] }));
|
|
26
|
+
}
|
|
@@ -5,6 +5,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
*
|
|
6
6
|
* Kortix permissions (kortix.yaml) ∩ ceiling role (IAM) − human-only
|
|
7
7
|
*
|
|
8
|
+
* The UI says "Granted in kortix.yaml" and "Maximum allowed". The fixed
|
|
9
|
+
* human-only set is named in the effective-permissions help, not as a row.
|
|
10
|
+
*
|
|
8
11
|
* This is how Kortix works, not a mode the project chose: there is no switch,
|
|
9
12
|
* so the card states it flatly.
|
|
10
13
|
*
|
|
@@ -38,7 +41,7 @@ export function AgentAuthorityCard({ projectId, agentName, grant, }) {
|
|
|
38
41
|
: authority.declared.length === 0
|
|
39
42
|
? t('declaredNone')
|
|
40
43
|
: t('declaredCount', { count: authority.declared.length });
|
|
41
|
-
return (_jsx("div", { "data-testid": "agent-authority", children: _jsxs(EditorSection, { title: t('title'), description: t('description'), children: [_jsx(SettingRow, { label: t('kortixPermissions'), help: t('kortixPermissionsHelp', { agent: agentName }), children: _jsx("span", { className: "text-foreground block text-sm sm:text-right", children: declaredLabel }) }), _jsx(SettingRow, { label: t('ceiling'), help: t('ceilingHelp'), children: _jsxs("div", { className: "flex flex-wrap items-center gap-1.5 sm:justify-end", "data-testid": "agent-ceiling", children: [ceiling.kind === 'loading' ? (_jsx(Skeleton, { className: "h-5 w-32" })) : ceiling.kind === 'hidden' ? (_jsx("span", { className: "text-muted-foreground text-sm", children: t('ceilingHidden') })) : ceiling.kind === 'default' ? (_jsx("span", { className: "text-foreground text-sm", children: t('ceilingDefault') })) : (ceiling.roleKeys.map((key) => (_jsx(Badge, { variant: "outline", size: "sm", className: "capitalize", children: key }, key)))), accountId && ceiling.kind !== 'hidden' && ceiling.kind !== 'loading' ? (_jsx(Button, { asChild: true, variant: "secondary", size: "sm", children: _jsx(HubLink, { to: hubTarget(accountId, { tab: 'access-projects', project: projectId }), children: t('changeCeiling') }) })) : null] }) }),
|
|
44
|
+
return (_jsx("div", { "data-testid": "agent-authority", children: _jsxs(EditorSection, { title: t('title'), description: t('description'), children: [_jsx(SettingRow, { label: t('kortixPermissions'), help: t('kortixPermissionsHelp', { agent: agentName }), children: _jsx("span", { className: "text-foreground block text-sm sm:text-right", children: declaredLabel }) }), _jsx(SettingRow, { label: t('ceiling'), help: t('ceilingHelp'), children: _jsxs("div", { className: "flex flex-wrap items-center gap-1.5 sm:justify-end", "data-testid": "agent-ceiling", children: [ceiling.kind === 'loading' ? (_jsx(Skeleton, { className: "h-5 w-32" })) : ceiling.kind === 'hidden' ? (_jsx("span", { className: "text-muted-foreground text-sm", children: t('ceilingHidden') })) : ceiling.kind === 'default' ? (_jsx("span", { className: "text-foreground text-sm", children: t('ceilingDefault') })) : (ceiling.roleKeys.map((key) => (_jsx(Badge, { variant: "outline", size: "sm", className: "capitalize", children: key }, key)))), accountId && ceiling.kind !== 'hidden' && ceiling.kind !== 'loading' ? (_jsx(Button, { asChild: true, variant: "secondary", size: "sm", children: _jsx(HubLink, { to: hubTarget(accountId, { tab: 'access-projects', project: projectId }), children: t('changeCeiling') }) })) : null] }) }), _jsxs(SettingBlock, { label: t('effective'), help: t('effectiveHelp'), children: [_jsx("ul", { className: "flex flex-wrap gap-1", "data-testid": "agent-effective-permissions", children: authority.effective.map((permission) => (_jsx("li", { children: _jsx(Badge, { variant: "outline", size: "xs", className: "font-mono", children: permission }) }, permission))) }), authority.outsideCeiling.length > 0 ? (_jsx(DroppedList, { label: t('outsideCeiling'), permissions: authority.outsideCeiling, testId: "agent-outside-ceiling" })) : null, authority.humanOnly.length > 0 ? (_jsx(DroppedList, { label: t('droppedHumanOnly'), permissions: authority.humanOnly, testId: "agent-dropped-human-only" })) : null] })] }) }));
|
|
42
45
|
}
|
|
43
46
|
function DroppedList({ label, permissions, testId, }) {
|
|
44
47
|
return (_jsxs("div", { className: "space-y-1.5", "data-testid": testId, children: [_jsx("p", { className: "text-muted-foreground text-xs", children: label }), _jsx("ul", { className: "flex flex-wrap gap-1", children: permissions.map((permission) => (_jsx("li", { children: _jsx(Badge, { variant: "muted", size: "xs", className: "font-mono line-through", children: permission }) }, permission))) })] }));
|
|
@@ -4,7 +4,7 @@ import type { ReactNode } from 'react';
|
|
|
4
4
|
* every agent a face that is the same wherever the agent appears, so a long
|
|
5
5
|
* list is scanned by shape and tone before names are read.
|
|
6
6
|
*/
|
|
7
|
-
export declare function AgentCoverCard({ slug, href, onIntent, title, description, badges, meta, coverLabel, }: {
|
|
7
|
+
export declare function AgentCoverCard({ slug, href, onIntent, title, description, badges, meta, coverLabel, action, }: {
|
|
8
8
|
slug: string;
|
|
9
9
|
href: string;
|
|
10
10
|
onIntent?: () => void;
|
|
@@ -14,4 +14,7 @@ export declare function AgentCoverCard({ slug, href, onIntent, title, descriptio
|
|
|
14
14
|
meta?: ReactNode;
|
|
15
15
|
/** A short pill on the cover's top-left corner — "Default". */
|
|
16
16
|
coverLabel?: string;
|
|
17
|
+
/** A control on the cover's top-right corner (the pin). A sibling of the
|
|
18
|
+
* card's link, never inside it: a button may not sit in a link. */
|
|
19
|
+
action?: ReactNode;
|
|
17
20
|
}): import("react").JSX.Element;
|
|
@@ -8,6 +8,6 @@ import { cn } from '../../internal/lib/utils.js';
|
|
|
8
8
|
* every agent a face that is the same wherever the agent appears, so a long
|
|
9
9
|
* list is scanned by shape and tone before names are read.
|
|
10
10
|
*/
|
|
11
|
-
export function AgentCoverCard({ slug, href, onIntent, title, description, badges, meta, coverLabel, }) {
|
|
12
|
-
return (_jsxs(Link, { href: href, prefetch: true, onPointerEnter: onIntent, onFocus: onIntent, style: agentMarkVars(slug), className: cn('group bg-card border-border/60 flex flex-col overflow-hidden rounded-md border text-left', 'hover:border-border transition-[border-color] duration-(--duration-normal) ease-out', 'focus-visible:ring-ring/50 focus-visible:ring-2 focus-visible:outline-none'), children: [_jsxs("span", { className: "relative flex h-31 items-center justify-center bg-(--mark-tile)", children: [_jsx(AgentMarkGlyph, { slug: slug, size: 56 }), coverLabel ? (_jsx("span", { className: "bg-background/20 absolute top-2.5 left-2.5 rounded-sm px-2 py-0.5 text-xs font-medium text-(--mark-ink) backdrop-blur-sm", children: coverLabel })) : null] }), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-1 px-3.5 pt-3 pb-3.5", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-foreground truncate text-sm font-medium", children: title }), badges] }), description ? (_jsx("span", { className: "text-muted-foreground line-clamp-2 text-xs text-pretty", children: description })) : null, meta ? (_jsx("span", { className: "text-muted-foreground mt-auto flex flex-wrap items-center gap-x-2 gap-y-0.5 pt-1.5 text-xs", children: meta })) : null] })] }));
|
|
11
|
+
export function AgentCoverCard({ slug, href, onIntent, title, description, badges, meta, coverLabel, action, }) {
|
|
12
|
+
return (_jsxs("div", { className: "group/card relative flex", children: [_jsxs(Link, { href: href, prefetch: true, onPointerEnter: onIntent, onFocus: onIntent, style: agentMarkVars(slug), className: cn('group bg-card flex-1 border-border/60 flex flex-col overflow-hidden rounded-md border text-left', 'hover:border-border transition-[border-color] duration-(--duration-normal) ease-out', 'focus-visible:ring-ring/50 focus-visible:ring-2 focus-visible:outline-none'), children: [_jsxs("span", { className: "relative flex h-31 items-center justify-center bg-(--mark-tile)", children: [_jsx(AgentMarkGlyph, { slug: slug, size: 56 }), coverLabel ? (_jsx("span", { className: "bg-background/20 absolute top-2.5 left-2.5 rounded-sm px-2 py-0.5 text-xs font-medium text-(--mark-ink) backdrop-blur-sm", children: coverLabel })) : null] }), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-1 px-3.5 pt-3 pb-3.5", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-foreground truncate text-sm font-medium", children: title }), badges] }), description ? (_jsx("span", { className: "text-muted-foreground line-clamp-2 text-xs text-pretty", children: description })) : null, meta ? (_jsx("span", { className: "text-muted-foreground mt-auto flex flex-wrap items-center gap-x-2 gap-y-0.5 pt-1.5 text-xs", children: meta })) : null] })] }), action ? _jsx("span", { className: "absolute top-2 right-2", children: action }) : null] }));
|
|
13
13
|
}
|
|
@@ -11,8 +11,7 @@ export declare function AgentModel({ projectId, agentName }: {
|
|
|
11
11
|
agentName: string;
|
|
12
12
|
}): import("react").JSX.Element;
|
|
13
13
|
/**
|
|
14
|
-
* An agent's manifest allowlist (`agents:` in kortix.yaml
|
|
15
|
-
* `[[agents]]` in kortix.toml) — which secrets it receives in $ENV, which
|
|
14
|
+
* An agent's manifest allowlist (`agents:` in kortix.yaml) — which secrets it receives in $ENV, which
|
|
16
15
|
* connectors it may call, which Kortix permissions it has. Editors EDIT
|
|
17
16
|
* secrets + connectors here (persisted straight to the manifest); everyone
|
|
18
17
|
* else sees the read-only mirror. `kortix_permissions` stays read-only (a sharper
|
|
@@ -2,20 +2,18 @@
|
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
|
|
4
4
|
/**
|
|
5
|
-
* The
|
|
6
|
-
*
|
|
5
|
+
* The read-only cards of the agent page, plus the scope-checklist helpers the
|
|
6
|
+
* editor shares with them.
|
|
7
7
|
*
|
|
8
|
-
* `AgentModel` and `AgentScope` are what
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* (`capabilities/agents/agent-page.tsx`) renders neither; its Model and Access
|
|
13
|
-
* sections write the manifest block directly.
|
|
8
|
+
* `AgentModel` and `AgentScope` are what the read-only agent page shows in
|
|
9
|
+
* place of the full editor — the per-agent gateway model pin and the scope
|
|
10
|
+
* mirror. The editable page (`agent-page.tsx`) renders neither; its Model and
|
|
11
|
+
* Access sections write the manifest block directly.
|
|
14
12
|
*
|
|
15
13
|
* Historically this file was the whole right-hand aside of the agent detail
|
|
16
14
|
* MODAL (assignments + configuration summary). The modal is gone — an agent
|
|
17
15
|
* is a routed page now, Customize being agent-centric (Marko, 2026-09-01) —
|
|
18
|
-
* and the assignments moved to `agent-
|
|
16
|
+
* and the assignments moved to `agent-share-dialog.tsx`.
|
|
19
17
|
*/
|
|
20
18
|
import { Badge } from '../../primitives/badge.js';
|
|
21
19
|
import { Button } from '../../primitives/button.js';
|
|
@@ -66,8 +64,7 @@ export function AgentModel({ projectId, agentName }) {
|
|
|
66
64
|
} })] })) : (_jsx("span", { className: "text-foreground block truncate text-sm sm:text-right", children: nameOf(resolved) ?? tI18nComplete.raw('text1f0a5246c481') })) }) }));
|
|
67
65
|
}
|
|
68
66
|
/**
|
|
69
|
-
* An agent's manifest allowlist (`agents:` in kortix.yaml
|
|
70
|
-
* `[[agents]]` in kortix.toml) — which secrets it receives in $ENV, which
|
|
67
|
+
* An agent's manifest allowlist (`agents:` in kortix.yaml) — which secrets it receives in $ENV, which
|
|
71
68
|
* connectors it may call, which Kortix permissions it has. Editors EDIT
|
|
72
69
|
* secrets + connectors here (persisted straight to the manifest); everyone
|
|
73
70
|
* else sees the read-only mirror. `kortix_permissions` stays read-only (a sharper
|
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the
|
|
2
|
+
* Drives as mounts, ONE component in two modes (Marko, 2026-10-27: "folder
|
|
3
|
+
* mount based, exactly", "one component, agent-based or project-wide"):
|
|
4
|
+
*
|
|
5
|
+
* - **Project** (Project admin → Drives): the folders EVERY new session
|
|
6
|
+
* mounts, the ones shared with everyone in the project.
|
|
7
|
+
* - **Agent** (Access → Drives): what a new session of this agent mounts,
|
|
8
|
+
* its own folders plus the project's.
|
|
9
|
+
*
|
|
10
|
+
* Each row is one folder a new session mounts: where
|
|
11
|
+
* it appears (`/drives/...`), which Files folder it is, who it comes through
|
|
12
|
+
* (this agent, or everyone in the project) and whether it is read-only. The
|
|
13
|
+
* list is the server's own plan (`GET /drives/:id/agents/:name/mounts`, the
|
|
14
|
+
* functions a session boot runs), so it never guesses.
|
|
15
|
+
*
|
|
16
|
+
* Mounting, changing the level and unmounting share or unshare the folder
|
|
17
|
+
* with the agent at once, the same grant Files > Share makes; they do not
|
|
18
|
+
* wait for the page's Save. A folder that comes through the project is
|
|
19
|
+
* changed in Files, where its sharing lives.
|
|
7
20
|
*/
|
|
8
|
-
export declare function AgentDrivesSection({ projectId, agentName }: {
|
|
21
|
+
export declare function AgentDrivesSection({ projectId, agentName, repositoryAccess, }: {
|
|
9
22
|
projectId: string;
|
|
10
|
-
|
|
23
|
+
/** Absent: the project's mounts (Project admin). */
|
|
24
|
+
agentName?: string;
|
|
25
|
+
/** Whether sessions of the agent get the project repository at /workspace. Agent mode only. */
|
|
26
|
+
repositoryAccess?: boolean;
|
|
11
27
|
}): import("react").JSX.Element;
|
|
@@ -1,66 +1,132 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useAgentMounts, useProjectMounts } from '@kortix/sdk/react';
|
|
4
|
+
import { CaretRightIcon, FolderSimpleIcon, HardDrivesIcon, PlusIcon, XIcon } from '@phosphor-icons/react';
|
|
5
|
+
import { useState } from 'react';
|
|
6
|
+
import { useDriveFolder, useFolderAccess, useProjectDrive, useShareFolder, useUnshareFolder } from '../../files/drives/use-drives.js';
|
|
7
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
8
|
+
import { agentDisplayName } from '../../internal/components/agent-mark.js';
|
|
3
9
|
import { uiRoutes } from '../../lib/routes.js';
|
|
10
|
+
import { Button } from '../../primitives/button.js';
|
|
11
|
+
import { ConfirmDialog } from '../../primitives/confirm-dialog.js';
|
|
12
|
+
import { EmptyArt } from '../../primitives/empty-art.js';
|
|
4
13
|
import { EmptyState } from '../../primitives/empty-state.js';
|
|
5
14
|
import { ErrorState } from '../../primitives/error-state.js';
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
15
|
+
import Hint from '../../primitives/hint.js';
|
|
16
|
+
import { Modal, ModalBody, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTitle } from '../../primitives/modal.js';
|
|
17
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../primitives/select.js';
|
|
8
18
|
import { Skeleton } from '../../primitives/skeleton.js';
|
|
9
|
-
import { Switch } from '../../primitives/switch.js';
|
|
10
19
|
import { errorToast } from '../../primitives/toast.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
20
|
+
import { ManageButton } from '../sections/view/agent-editor-access-fields.js';
|
|
21
|
+
import { EditorList } from '../sections/view/agent-editor-primitives.js';
|
|
22
|
+
import { CapabilityPageShell } from '../shared/capability-page-shell.js';
|
|
14
23
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* the
|
|
24
|
+
* Drives as mounts, ONE component in two modes (Marko, 2026-10-27: "folder
|
|
25
|
+
* mount based, exactly", "one component, agent-based or project-wide"):
|
|
26
|
+
*
|
|
27
|
+
* - **Project** (Project admin → Drives): the folders EVERY new session
|
|
28
|
+
* mounts, the ones shared with everyone in the project.
|
|
29
|
+
* - **Agent** (Access → Drives): what a new session of this agent mounts,
|
|
30
|
+
* its own folders plus the project's.
|
|
31
|
+
*
|
|
32
|
+
* Each row is one folder a new session mounts: where
|
|
33
|
+
* it appears (`/drives/...`), which Files folder it is, who it comes through
|
|
34
|
+
* (this agent, or everyone in the project) and whether it is read-only. The
|
|
35
|
+
* list is the server's own plan (`GET /drives/:id/agents/:name/mounts`, the
|
|
36
|
+
* functions a session boot runs), so it never guesses.
|
|
37
|
+
*
|
|
38
|
+
* Mounting, changing the level and unmounting share or unshare the folder
|
|
39
|
+
* with the agent at once, the same grant Files > Share makes; they do not
|
|
40
|
+
* wait for the page's Save. A folder that comes through the project is
|
|
41
|
+
* changed in Files, where its sharing lives.
|
|
20
42
|
*/
|
|
21
|
-
export function AgentDrivesSection({ projectId, agentName }) {
|
|
22
|
-
const t = useTranslations('
|
|
43
|
+
export function AgentDrivesSection({ projectId, agentName, repositoryAccess = true, }) {
|
|
44
|
+
const t = useTranslations('agentMounts');
|
|
23
45
|
const drive = useProjectDrive(projectId);
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
46
|
+
const driveId = drive.data?.driveId ?? null;
|
|
47
|
+
const agentPlan = useAgentMounts(agentName ? driveId : null, agentName ?? '');
|
|
48
|
+
const projectPlan = useProjectMounts(agentName ? null : driveId);
|
|
49
|
+
const plan = agentName ? agentPlan : projectPlan;
|
|
50
|
+
const showRepository = !!agentName && repositoryAccess;
|
|
51
|
+
const root = useFolderAccess(driveId, '/');
|
|
52
|
+
// Mounting needs `manage` on the folder; someone who holds it at the top holds it below.
|
|
53
|
+
const canMount = root.data?.access === 'manage';
|
|
54
|
+
const [picking, setPicking] = useState(false);
|
|
27
55
|
let body;
|
|
28
|
-
if (drive.isLoading ||
|
|
29
|
-
body = (_jsx(EditorList, { children: [0, 1].map((i) => (_jsx("li", { className: "flex items-center gap-3 px-4 py-
|
|
56
|
+
if (drive.isLoading || plan.isLoading) {
|
|
57
|
+
body = (_jsx(EditorList, { children: [0, 1].map((i) => (_jsx("li", { className: "flex min-h-12 items-center gap-3 px-4 py-2", children: _jsx(Skeleton, { className: "h-4 w-48 rounded-sm" }) }, i))) }));
|
|
30
58
|
}
|
|
31
|
-
else if (drive.isError ||
|
|
32
|
-
body = (_jsx(ErrorState, { size: "sm", title: t('loadError'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => void
|
|
59
|
+
else if (drive.isError || plan.isError || !driveId || !plan.data) {
|
|
60
|
+
body = (_jsx(ErrorState, { size: "sm", title: t('loadError'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => void plan.refetch(), children: t('retry') }) }));
|
|
33
61
|
}
|
|
34
|
-
else if (
|
|
35
|
-
body = _jsx(EmptyState, {
|
|
62
|
+
else if (plan.data.mounts.length === 0 && !showRepository) {
|
|
63
|
+
body = (_jsx(EmptyState, { media: _jsx(EmptyArt, { icon: HardDrivesIcon }), title: t('emptyTitle'), description: t('emptyDescription') }));
|
|
36
64
|
}
|
|
37
65
|
else {
|
|
38
|
-
body = (
|
|
66
|
+
body = (_jsxs("div", { className: "space-y-3", children: [_jsxs(EditorList, { children: [showRepository ? (_jsxs("li", { className: "flex min-h-12 items-center gap-3 px-4 py-2", children: [_jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("code", { className: "text-foreground block truncate font-mono text-sm", children: "/workspace" }), _jsx("span", { className: "text-muted-foreground block truncate text-xs", children: t('repository') })] }), _jsx("span", { className: "text-muted-foreground shrink-0 text-xs", children: t('readWrite') })] })) : null, plan.data.mounts.map((mount) => (_jsx(MountRow, { driveId: driveId, agentName: agentName, mount: mount }, mount.path)))] }), plan.data.skipped.length > 0 ? (_jsx("p", { className: "text-muted-foreground text-xs text-pretty", children: t('skipped', { slots: plan.data.slots, list: plan.data.skipped.join(', ') }) })) : null] }));
|
|
39
67
|
}
|
|
40
|
-
return (
|
|
68
|
+
return (_jsxs(CapabilityPageShell, { title: t('title'), description: agentName ? t('lead') : t('projectLead'), action: _jsxs(_Fragment, { children: [canMount && driveId ? (_jsxs(Button, { variant: "secondary", size: "sm", className: "gap-1.5", onClick: () => setPicking(true), children: [_jsx(PlusIcon, { className: "size-3.5 shrink-0" }), t('mount')] })) : null, _jsx(ManageButton, { href: (id) => uiRoutes().drive(id) })] }), children: [_jsx("div", { "data-testid": "drive-mounts", children: body }), driveId ? (_jsx(FolderPicker, { open: picking, onOpenChange: setPicking, driveId: driveId, agentName: agentName, mounted: new Set(plan.data?.mounts.map((m) => m.path)) })) : null] }));
|
|
41
69
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
70
|
+
/** The level a mount gives: read only, or read and write. `manage` mounts read and write. */
|
|
71
|
+
const levelValue = (level) => (level === 'read' ? 'read' : 'write');
|
|
72
|
+
/** Who a mount is shared with: the agent, or everyone in the project. */
|
|
73
|
+
const principalOf = (agentName) => agentName ? { principalType: 'agent', principalId: agentName } : { principalType: 'project' };
|
|
74
|
+
function MountRow({ driveId, agentName, mount }) {
|
|
75
|
+
const t = useTranslations('agentMounts');
|
|
46
76
|
const share = useShareFolder();
|
|
47
77
|
const unshare = useUnshareFolder();
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const inherited = !own && grants.some((g) => g.principalType === 'project' || (g.principalType === 'agent' && g.principalId === agentName));
|
|
52
|
-
const canManage = access.data?.access === 'manage' && !!access.data?.grantable;
|
|
78
|
+
const access = useFolderAccess(driveId, mount.path, !!mount.grantId);
|
|
79
|
+
const canChange = !!mount.grantId && access.data?.access === 'manage';
|
|
80
|
+
const [confirming, setConfirming] = useState(false);
|
|
53
81
|
const pending = share.isPending || unshare.isPending;
|
|
54
|
-
const
|
|
82
|
+
const setLevel = async (level) => {
|
|
83
|
+
try {
|
|
84
|
+
await share.mutateAsync({ driveId, path: mount.path, ...principalOf(agentName), level });
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
errorToast(t('changeFailed'));
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const unmount = async () => {
|
|
91
|
+
try {
|
|
92
|
+
await unshare.mutateAsync({ driveId, grantId: mount.grantId });
|
|
93
|
+
setConfirming(false);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
errorToast(t('changeFailed'));
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const who = mount.via === 'agent' ? t('viaAgent') : t('viaProject');
|
|
100
|
+
return (_jsxs("li", { className: "flex min-h-12 items-center gap-3 px-4 py-2", children: [_jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "text-foreground block truncate font-mono text-sm", children: mount.mountPath }), _jsx("span", { className: "text-muted-foreground block truncate text-xs", children: t('from', { path: mount.path, who }) })] }), canChange ? (_jsxs(_Fragment, { children: [_jsxs(Select, { value: levelValue(mount.level), onValueChange: (v) => void setLevel(v), disabled: pending, children: [_jsx(SelectTrigger, { size: "sm", className: "w-36 shrink-0", "aria-label": t('levelFor', { path: mount.path }), children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { align: "end", children: [_jsx(SelectItem, { value: "read", children: t('readOnly') }), _jsx(SelectItem, { value: "write", children: t('readWrite') })] })] }), _jsx(Hint, { label: t('unmountLabel', { path: mount.path }), children: _jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": t('unmountLabel', { path: mount.path }), onClick: () => setConfirming(true), disabled: pending, children: _jsx(XIcon, { className: "size-4" }) }) }), _jsx(ConfirmDialog, { open: confirming, onOpenChange: setConfirming, title: t('unmountTitle', { path: mount.mountPath }), description: agentName ? t('unmountDescription', { agent: agentDisplayName(agentName) }) : t('unmountProjectDescription'), confirmLabel: t('unmount'), confirmVariant: "destructive", isPending: unshare.isPending, onConfirm: () => void unmount() })] })) : (_jsx("span", { className: "text-muted-foreground shrink-0 text-xs", children: mount.readOnly ? t('readOnly') : t('readWrite') }))] }));
|
|
101
|
+
}
|
|
102
|
+
/** Pick a folder in Files and the level, then mount it for the agent. */
|
|
103
|
+
function FolderPicker({ open, onOpenChange, driveId, agentName, mounted, }) {
|
|
104
|
+
const t = useTranslations('agentMounts');
|
|
105
|
+
const [path, setPath] = useState('/');
|
|
106
|
+
const [level, setLevel] = useState('read');
|
|
107
|
+
const folder = useDriveFolder(open ? driveId : null, path);
|
|
108
|
+
const share = useShareFolder();
|
|
109
|
+
// Personal folders under /Users are their owners' to share, never a mount to pick here.
|
|
110
|
+
const dirs = (folder.data?.entries ?? []).filter((e) => e.type === 'dir' && !(path === '/' && /^\/?Users$/.test(e.path)));
|
|
111
|
+
const crumbs = path.split('/').filter(Boolean);
|
|
112
|
+
const close = (next) => {
|
|
113
|
+
if (share.isPending)
|
|
114
|
+
return;
|
|
115
|
+
if (!next)
|
|
116
|
+
setPath('/');
|
|
117
|
+
onOpenChange(next);
|
|
118
|
+
};
|
|
119
|
+
const mount = async () => {
|
|
55
120
|
try {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
else if (own)
|
|
59
|
-
await unshare.mutateAsync({ driveId, grantId: own.grantId });
|
|
121
|
+
await share.mutateAsync({ driveId, path, ...principalOf(agentName), level });
|
|
122
|
+
close(false);
|
|
60
123
|
}
|
|
61
124
|
catch {
|
|
62
|
-
errorToast(t('
|
|
125
|
+
errorToast(t('changeFailed'));
|
|
63
126
|
}
|
|
64
127
|
};
|
|
65
|
-
return (_jsxs("
|
|
128
|
+
return (_jsx(Modal, { open: open, onOpenChange: close, children: _jsxs(ModalContent, { className: "lg:max-w-lg", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: t('pickerTitle') }), _jsx(ModalDescription, { children: agentName ? t('pickerDescription', { agent: agentDisplayName(agentName) }) : t('pickerProjectDescription') })] }), _jsxs(ModalBody, { className: "space-y-3", children: [_jsxs("nav", { "aria-label": t('pickerPath'), className: "flex min-w-0 flex-wrap items-center gap-1 text-sm", children: [_jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground rounded-sm", onClick: () => setPath('/'), children: t('pickerRoot') }), crumbs.map((name, i) => (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(CaretRightIcon, { "aria-hidden": true, className: "text-muted-foreground size-3" }), _jsx("button", { type: "button", className: i === crumbs.length - 1 ? 'text-foreground' : 'text-muted-foreground hover:text-foreground', onClick: () => setPath(`/${crumbs.slice(0, i + 1).join('/')}`), children: name })] }, i)))] }), _jsx(EditorList, { className: "max-h-72 overflow-y-auto", children: folder.isLoading ? (_jsx("li", { className: "flex min-h-10 items-center px-4 py-2", children: _jsx(Skeleton, { className: "h-4 w-40 rounded-sm" }) })) : dirs.length === 0 ? (_jsx("li", { className: "text-muted-foreground px-4 py-3 text-sm", children: t('pickerEmpty') })) : (dirs.map((entry) => {
|
|
129
|
+
const next = entry.path.startsWith('/') ? entry.path : `/${entry.path}`;
|
|
130
|
+
return (_jsx("li", { children: _jsxs("button", { type: "button", onClick: () => setPath(next), className: "hover:bg-hover flex min-h-10 w-full items-center gap-2 px-4 py-2 text-left text-sm", children: [_jsx(FolderSimpleIcon, { "aria-hidden": true, className: "text-muted-foreground size-4 shrink-0" }), _jsx("span", { className: "text-foreground min-w-0 flex-1 truncate", children: entry.name }), mounted.has(next) ? _jsx("span", { className: "text-muted-foreground text-xs", children: t('alreadyMounted') }) : null, _jsx(CaretRightIcon, { "aria-hidden": true, className: "text-muted-foreground size-3.5 shrink-0" })] }) }, next));
|
|
131
|
+
})) })] }), _jsxs(ModalFooter, { className: "flex items-center justify-between gap-2", children: [_jsxs(Select, { value: level, onValueChange: (v) => setLevel(v), children: [_jsx(SelectTrigger, { size: "sm", className: "w-36 shrink-0", "aria-label": t('levelFor', { path }), children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "read", children: t('readOnly') }), _jsx(SelectItem, { value: "write", children: t('readWrite') })] })] }), _jsx(Button, { onClick: () => void mount(), disabled: path === '/' || share.isPending, "aria-busy": share.isPending, children: path === '/' ? t('pickerChoose') : t('pickerMount', { path }) })] })] }) }));
|
|
66
132
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function wordCount(text: string): number;
|
|
2
|
+
export declare function AgentInstructions({ value, onChange, onAskMyKortix, autoFocus, }: {
|
|
3
|
+
/** The instructions as Markdown; null while a reader's source file loads. */
|
|
4
|
+
value: string | null;
|
|
5
|
+
/** Writes the draft. Without it the document is read-only. */
|
|
6
|
+
onChange?: (next: string) => void;
|
|
7
|
+
/** Opens a configure thread that asks My Kortix to edit the instructions. */
|
|
8
|
+
onAskMyKortix?: () => void;
|
|
9
|
+
/** Open unfolded with the cursor in it (the old `?tab=instructions` link). */
|
|
10
|
+
autoFocus?: boolean;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* The agent's instructions on the Overview, edited in place: the formatted
|
|
5
|
+
* document is the editor. A person clicks into it and types, like a doc; the
|
|
6
|
+
* Markdown file (`agents/<name>.md`) never shows its `**` or `##`. It is the
|
|
7
|
+
* same editor as doc artifacts (`markdown/doc-editor`), so Kortix has one
|
|
8
|
+
* document editor, and a file opened and saved unchanged stays byte for byte
|
|
9
|
+
* the same (`doc-round-trip.test.ts`).
|
|
10
|
+
*
|
|
11
|
+
* Edits go to the page's draft on every change; the save bar, ⌘S and the
|
|
12
|
+
* leave guard save them. A long document opens folded under a fade that runs
|
|
13
|
+
* to the block's bottom edge; Show more or a click into it unfolds it, for
|
|
14
|
+
* good. Escape leaves the editor.
|
|
15
|
+
*/
|
|
16
|
+
import { ARTIFACT_DOC_CSS } from '../../_vendor/kortix-shared.js';
|
|
17
|
+
import { CaretDownIcon, PencilSimpleIcon } from '@phosphor-icons/react';
|
|
18
|
+
import { EditorContent, useEditor } from '@tiptap/react';
|
|
19
|
+
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
20
|
+
import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
|
|
21
|
+
import { cn } from '../../internal/lib/utils.js';
|
|
22
|
+
import { docExtensions } from '../../markdown/doc-editor/doc-extensions.js';
|
|
23
|
+
import { DocMenus } from '../../markdown/doc-editor/doc-menus.js';
|
|
24
|
+
import { htmlToMarkdown, markdownToHtml } from '../../markdown/doc-editor/markdown.js';
|
|
25
|
+
import { Button } from '../../primitives/button.js';
|
|
26
|
+
import { ConfirmDialog } from '../../primitives/confirm-dialog.js';
|
|
27
|
+
import Hint from '../../primitives/hint.js';
|
|
28
|
+
import { Skeleton } from '../../primitives/skeleton.js';
|
|
29
|
+
export function wordCount(text) {
|
|
30
|
+
const trimmed = text.trim();
|
|
31
|
+
return trimmed ? trimmed.split(/\s+/).length : 0;
|
|
32
|
+
}
|
|
33
|
+
export function AgentInstructions({ value, onChange, onAskMyKortix, autoFocus = false, }) {
|
|
34
|
+
const t = useI18nTranslations('agentEditor.page');
|
|
35
|
+
const tTabs = useI18nTranslations('agentEditor.tabs');
|
|
36
|
+
const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
|
|
37
|
+
const editable = onChange !== undefined;
|
|
38
|
+
const [unfolded, setUnfolded] = useState(autoFocus);
|
|
39
|
+
// Taller than the fold: measured while folded, kept once unfolded.
|
|
40
|
+
const [long, setLong] = useState(false);
|
|
41
|
+
const frame = useRef(null);
|
|
42
|
+
// The Markdown the editor last wrote. A value that differs came from
|
|
43
|
+
// outside (Discard, a save's read-back) and reloads the document.
|
|
44
|
+
const written = useRef(value);
|
|
45
|
+
// The document as loaded: its source, and what the editor saves it as.
|
|
46
|
+
// Saving the loaded document gives back the source, byte for byte.
|
|
47
|
+
const loaded = useRef({ source: value ?? '', saved: null });
|
|
48
|
+
const latest = useRef(onChange);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
latest.current = onChange;
|
|
51
|
+
});
|
|
52
|
+
const editor = useEditor({
|
|
53
|
+
immediatelyRender: false,
|
|
54
|
+
editable,
|
|
55
|
+
autofocus: autoFocus ? 'start' : false,
|
|
56
|
+
extensions: docExtensions({ editable, placeholder: () => tTabs('instructionsPlaceholder') }),
|
|
57
|
+
content: value === null ? '' : markdownToHtml(value),
|
|
58
|
+
editorProps: {
|
|
59
|
+
attributes: { 'aria-label': t('instructions') },
|
|
60
|
+
handleKeyDown: (view, event) => {
|
|
61
|
+
if (event.key !== 'Escape')
|
|
62
|
+
return false;
|
|
63
|
+
view.dom.blur();
|
|
64
|
+
return true;
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
onCreate: ({ editor: e }) => {
|
|
68
|
+
loaded.current = { source: value ?? '', saved: htmlToMarkdown(e.getHTML()) };
|
|
69
|
+
},
|
|
70
|
+
onFocus: () => setUnfolded(true),
|
|
71
|
+
onUpdate: ({ editor: e }) => {
|
|
72
|
+
// Only a person's edit writes the draft. The editor's own fix-ups on
|
|
73
|
+
// load (a trailing paragraph after a list) are not an edit.
|
|
74
|
+
if (!e.isFocused)
|
|
75
|
+
return;
|
|
76
|
+
const saved = htmlToMarkdown(e.getHTML());
|
|
77
|
+
const next = saved === loaded.current.saved ? loaded.current.source : saved;
|
|
78
|
+
written.current = next;
|
|
79
|
+
latest.current?.(next);
|
|
80
|
+
},
|
|
81
|
+
}, [editable, value === null]);
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (!editor || value === null || value === written.current)
|
|
84
|
+
return;
|
|
85
|
+
written.current = value;
|
|
86
|
+
editor.commands.setContent(markdownToHtml(value), { emitUpdate: false });
|
|
87
|
+
loaded.current = { source: value, saved: htmlToMarkdown(editor.getHTML()) };
|
|
88
|
+
}, [editor, value]);
|
|
89
|
+
// Fold only a document taller than the fold.
|
|
90
|
+
useLayoutEffect(() => {
|
|
91
|
+
const el = frame.current;
|
|
92
|
+
if (!el || unfolded)
|
|
93
|
+
return;
|
|
94
|
+
const measure = () => setLong(el.scrollHeight > el.clientHeight + 1);
|
|
95
|
+
measure();
|
|
96
|
+
const observer = new ResizeObserver(measure);
|
|
97
|
+
observer.observe(el);
|
|
98
|
+
return () => observer.disconnect();
|
|
99
|
+
}, [editor, unfolded]);
|
|
100
|
+
const [confirmEdit, setConfirmEdit] = useState(false);
|
|
101
|
+
const words = wordCount(value ?? '');
|
|
102
|
+
const folded = long && !unfolded;
|
|
103
|
+
return (_jsxs("section", { className: "space-y-3", children: [_jsx("div", { className: "flex items-center justify-between gap-3", children: _jsxs("h2", { className: "text-muted-foreground text-sm font-medium", children: [t('instructions'), words > 0 ? (_jsx("span", { className: "text-muted-foreground ml-2 font-normal tabular-nums", children: t('words', { count: words }) })) : null] }) }), _jsxs("div", { className: cn(
|
|
104
|
+
// A filled block, no border. Folded, it has no bottom inset: the fade meets the edge.
|
|
105
|
+
'bg-popover relative overflow-hidden rounded-lg px-5 pt-4',
|
|
106
|
+
// Room for the pencil in the top-right corner.
|
|
107
|
+
onAskMyKortix && 'pr-12', folded ? 'pb-0' : 'pb-4', editable && 'cursor-text'), children: [_jsx("style", { children: ARTIFACT_DOC_CSS }), onAskMyKortix ? (
|
|
108
|
+
// The Description box's pencil, in the same corner. My Kortix edits the
|
|
109
|
+
// instructions in a new session, so a click asks first.
|
|
110
|
+
_jsx(Hint, { label: tTabs('askToEdit'), side: "top", children: _jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": tTabs('askToEdit'), onClick: () => setConfirmEdit(true), className: "text-muted-foreground hover:text-foreground absolute top-3 right-3 z-10", children: _jsx(PencilSimpleIcon, { className: "size-3.5" }) }) })) : null, _jsx("div", { ref: frame, className: cn('kx-doc kx-doc-inline', !unfolded && 'max-h-80 overflow-hidden'), children: value === null || !editor ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-4 w-full" }), _jsx(Skeleton, { className: "h-4 w-5/6" })] })) : (_jsxs(_Fragment, { children: [editable ? _jsx(DocMenus, { editor: editor }) : null, _jsx(EditorContent, { editor: editor })] })) }), folded ? (_jsx("div", { className: "to-popover absolute inset-x-0 bottom-0 flex h-32 items-end justify-center bg-gradient-to-b from-transparent to-80% pb-4", children: _jsxs(Button, { variant: "secondary", size: "sm", onClick: () => setUnfolded(true), children: [tI18nComplete.raw('textf5c9bd131486'), _jsx(CaretDownIcon, { className: "size-3" })] }) })) : null] }), onAskMyKortix ? (_jsx(ConfirmDialog, { open: confirmEdit, onOpenChange: setConfirmEdit, title: tTabs('editInstructionsConfirmTitle'), description: tTabs('editInstructionsConfirmBody'), confirmLabel: tTabs('askToEdit'), onConfirm: () => {
|
|
111
|
+
setConfirmEdit(false);
|
|
112
|
+
onAskMyKortix();
|
|
113
|
+
} })) : null] }));
|
|
114
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent page's Model view, in the Settings dialect the rest of the agent
|
|
3
|
+
* page uses (`EditorSection` in `panel` style): a title per group, no
|
|
4
|
+
* sentence under it, and the settings as rows in one bordered group. The
|
|
5
|
+
* model (the project default or a pinned one) and its thinking effort, then
|
|
6
|
+
* sampling and limits, then the provider options. Every control writes the
|
|
7
|
+
* page's draft through `setOc`, the same keys `ModelSection` writes.
|
|
8
|
+
*/
|
|
9
|
+
import { type RuntimeAgentConfig } from '@kortix/sdk';
|
|
10
|
+
import { type ReactNode } from 'react';
|
|
11
|
+
type SetRuntime = <K extends keyof RuntimeAgentConfig>(key: K, value: RuntimeAgentConfig[K]) => void;
|
|
12
|
+
export declare function AgentModelView({ oc, setOc, footer }: {
|
|
13
|
+
oc: RuntimeAgentConfig;
|
|
14
|
+
setOc: SetRuntime;
|
|
15
|
+
footer?: ReactNode;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* The agent page's Model view, in the Settings dialect the rest of the agent
|
|
5
|
+
* page uses (`EditorSection` in `panel` style): a title per group, no
|
|
6
|
+
* sentence under it, and the settings as rows in one bordered group. The
|
|
7
|
+
* model (the project default or a pinned one) and its thinking effort, then
|
|
8
|
+
* sampling and limits, then the provider options. Every control writes the
|
|
9
|
+
* page's draft through `setOc`, the same keys `ModelSection` writes.
|
|
10
|
+
*/
|
|
11
|
+
import { modelRefToKey } from '@kortix/sdk';
|
|
12
|
+
import { flattenModels, modelKeyToWire, modelProviderMode, useRuntimeProviders } from '@kortix/sdk/react';
|
|
13
|
+
import { useState } from 'react';
|
|
14
|
+
import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
|
|
15
|
+
import { Input } from '../../primitives/input.js';
|
|
16
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../primitives/select.js';
|
|
17
|
+
import { Slider } from '../../primitives/slider.js';
|
|
18
|
+
import { Textarea } from '../../primitives/textarea.js';
|
|
19
|
+
import { ModelSelector } from '../../session/models/model-selector.js';
|
|
20
|
+
import { isSliderAtDefault } from '../sections/view/agent-editor-basics-fields.js';
|
|
21
|
+
import { EditorSection, EditorSectionStyleProvider, SettingBlock, SettingRow, } from '../sections/view/agent-editor-primitives.js';
|
|
22
|
+
/** The select's value for "no variant": the model decides. */
|
|
23
|
+
const AUTO = '__auto__';
|
|
24
|
+
/** A slider that can be unset: `—` and no Reset while it follows the default. */
|
|
25
|
+
function SliderField({ label, help, value, fallback, min, max, step, onChange, }) {
|
|
26
|
+
const t = useI18nTranslations('agentEditor.modelView');
|
|
27
|
+
return (_jsx(SettingBlock, { label: label, help: help, children: _jsxs("div", { className: "flex items-center gap-4", children: [_jsx(Slider, { className: "flex-1", value: [value ?? fallback], min: min, max: max, step: step, thumbLabel: label, formatValue: (v) => v.toFixed(2), onValueChange: ([v]) => onChange(v) }), _jsxs("div", { className: "flex w-24 shrink-0 items-baseline justify-end gap-2.5 text-sm tabular-nums", children: [isSliderAtDefault(value, fallback) ? null : (_jsx("button", { type: "button", onClick: () => onChange(undefined), className: "text-muted-foreground hover:text-foreground transition-colors duration-fast", children: t('reset') })), _jsx("span", { className: value === undefined ? 'text-muted-foreground' : 'text-foreground', children: value === undefined ? '—' : value.toFixed(2) })] })] }) }));
|
|
28
|
+
}
|
|
29
|
+
/** `options` as JSON: the draft changes only when the text parses to an object. */
|
|
30
|
+
function ProviderOptions({ value, onChange, }) {
|
|
31
|
+
const tTabs = useI18nTranslations('agentEditor.tabs');
|
|
32
|
+
const [text, setText] = useState(() => (value ? JSON.stringify(value, null, 2) : ''));
|
|
33
|
+
const [invalid, setInvalid] = useState(false);
|
|
34
|
+
const commit = (next) => {
|
|
35
|
+
setText(next);
|
|
36
|
+
if (!next.trim()) {
|
|
37
|
+
setInvalid(false);
|
|
38
|
+
return onChange(undefined);
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const parsed = JSON.parse(next);
|
|
42
|
+
const ok = !!parsed && typeof parsed === 'object' && !Array.isArray(parsed);
|
|
43
|
+
setInvalid(!ok);
|
|
44
|
+
if (ok)
|
|
45
|
+
onChange(parsed);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
setInvalid(true);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
return (
|
|
52
|
+
// The section title names it; the row holds the rule and the field.
|
|
53
|
+
_jsxs("div", { className: "space-y-2.5 px-4 py-3", children: [_jsx("p", { className: "text-muted-foreground text-xs leading-normal text-pretty", children: tTabs('providerOptionsHelp') }), _jsx(Textarea, { "aria-label": tTabs('providerOptions'), value: text, placeholder: JSON.stringify({ reasoning: 'high' }), className: "min-h-20 font-mono text-xs", "aria-invalid": invalid || undefined, onChange: (e) => commit(e.target.value) }), invalid ? _jsx("p", { className: "text-destructive text-xs", children: tTabs('providerOptionsInvalid') }) : null] }));
|
|
54
|
+
}
|
|
55
|
+
export function AgentModelView({ oc, setOc, footer }) {
|
|
56
|
+
const t = useI18nTranslations('agentEditor.modelView');
|
|
57
|
+
const tTabs = useI18nTranslations('agentEditor.tabs');
|
|
58
|
+
const { data: providers } = useRuntimeProviders();
|
|
59
|
+
const models = flattenModels(providers, { providerMode: modelProviderMode(providers) });
|
|
60
|
+
const pinned = oc.model ? modelRefToKey(oc.model) : null;
|
|
61
|
+
const pinnedModel = pinned
|
|
62
|
+
? models.find((m) => m.providerID === pinned.providerID && m.modelID === pinned.modelID)
|
|
63
|
+
: undefined;
|
|
64
|
+
// The pinned model's published variants: the composer's thinking-effort choices.
|
|
65
|
+
const variants = pinnedModel?.variants ? Object.keys(pinnedModel.variants) : [];
|
|
66
|
+
return (_jsx(EditorSectionStyleProvider, { value: "panel", children: _jsxs("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-8", children: [_jsxs(EditorSection, { title: t('title'), lead: true, children: [_jsx(SettingRow, { label: pinned ? (pinnedModel?.modelName ?? pinned.modelID) : t('projectDefault'), help: pinned ? (_jsxs(_Fragment, { children: [t('pinned'), " \u00B7", ' ', _jsx("button", { type: "button", onClick: () => setOc('model', undefined), className: "text-foreground decoration-border hover:decoration-foreground underline underline-offset-4 transition-colors", children: t('followDefault') })] })) : (t('followsDefault')), children: _jsx("div", { className: "flex sm:justify-end", children: _jsx(ModelSelector, { models: models, providers: providers, selectedModel: pinned, unsetLabel: t('pinModel'), triggerVariant: "secondary", onSelect: (m) => setOc('model', m ? modelKeyToWire(m) : undefined) }) }) }), _jsx(SettingRow, { label: t('thinkingEffort'), help: variants.length > 0 ? (oc.variant ? t('effortSetHelp') : t('effortAutoHelp')) : t('effortNoVariantsHelp'), children: variants.length > 0 ? (_jsxs(Select, { value: oc.variant && variants.includes(oc.variant) ? oc.variant : AUTO, onValueChange: (v) => setOc('variant', v === AUTO ? undefined : v), children: [_jsx(SelectTrigger, { "aria-label": t('thinkingEffort'), size: "sm", className: "w-full", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: AUTO, children: t('auto') }), variants.map((v) => (_jsx(SelectItem, { value: v, className: "capitalize", children: v }, v)))] })] })) : (_jsx(Input, { "aria-label": t('thinkingEffort'), value: oc.variant ?? '', placeholder: t('auto'), className: "h-8", onChange: (e) => setOc('variant', e.target.value || undefined) })) })] }), _jsxs(EditorSection, { title: t('samplingTitle'), children: [_jsx(SliderField, { label: t('temperature'), help: `${t('temperatureMin')} · ${t('temperatureMax')}`, value: oc.temperature, fallback: 0, min: 0, max: 2, step: 0.05, onChange: (v) => setOc('temperature', v) }), _jsx(SliderField, { label: t('topP'), help: t('topPHelp'), value: oc.top_p, fallback: 1, min: 0, max: 1, step: 0.01, onChange: (v) => setOc('top_p', v) }), _jsx(SettingRow, { label: t('stepLimit'), help: t('stepLimitHelp'), children: _jsxs("div", { className: "relative", children: [_jsx(Input, { "aria-label": t('stepLimit'), type: "number", min: 1, value: oc.steps ?? '', placeholder: t('noLimit'), className: "h-8 pr-12 tabular-nums", onChange: (e) => setOc('steps', e.target.value ? Math.max(1, Number(e.target.value)) : undefined) }), _jsx("span", { className: "text-muted-foreground pointer-events-none absolute inset-y-0 right-2.5 flex items-center text-xs", children: t('steps') })] }) })] }), _jsx(EditorSection, { title: tTabs('providerOptions'), children: _jsx(ProviderOptions, { value: oc.options, onChange: (next) => setOc('options', next) }) }), footer] }) }));
|
|
67
|
+
}
|