@kortix/ui 0.14.5 → 0.14.7
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/dist/_vendor/kortix-shared.js +489 -381
- package/dist/access/access/access-dialog.js +8 -5
- package/dist/access/access/copy-row.js +2 -2
- package/dist/access/sharing-picker.js +2 -1
- package/dist/browser/app-in-browser.js +5 -3
- package/dist/browser/browser-panel.js +6 -6
- package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
- package/dist/browser/sandbox-browser-chrome.js +4 -3
- package/dist/customize/agents/agent-access.d.ts +20 -0
- package/dist/customize/agents/agent-access.js +17 -0
- package/dist/customize/agents/agent-authority-card.js +1 -2
- package/dist/customize/agents/agent-detail-aside.js +15 -14
- package/dist/customize/agents/agent-drives-section.js +5 -6
- package/dist/customize/agents/agent-grant-pages.js +73 -76
- package/dist/customize/agents/agent-nav.prototype.d.ts +35 -0
- package/dist/customize/agents/agent-nav.prototype.js +95 -0
- package/dist/customize/agents/agent-page.js +59 -23
- package/dist/customize/agents/agent-people-section.js +18 -17
- package/dist/customize/agents/agent-triggers-section.js +6 -5
- package/dist/customize/agents/agents-page.js +18 -1
- package/dist/customize/connectors/add-mcp/add-mcp-server.js +4 -2
- package/dist/customize/connectors/catalog/catalog-entry.d.ts +14 -0
- package/dist/customize/connectors/catalog/catalog-entry.js +18 -1
- package/dist/customize/connectors/catalog/connector-browse.d.ts +28 -0
- package/dist/customize/connectors/catalog/connector-browse.js +18 -5
- package/dist/customize/connectors/connector-routes.d.ts +3 -1
- package/dist/customize/connectors/connector-routes.js +18 -0
- package/dist/customize/connectors/connectors-page.js +23 -4
- package/dist/customize/connectors/detail/app-page.js +19 -5
- package/dist/customize/connectors/detail/connector-advanced-tools.js +4 -6
- package/dist/customize/connectors/detail/connector-modal.d.ts +10 -13
- package/dist/customize/connectors/detail/connector-modal.js +18 -101
- package/dist/customize/connectors/detail/connector-notice.js +6 -2
- package/dist/customize/connectors/detail/connector-page.d.ts +30 -0
- package/dist/customize/connectors/detail/connector-page.js +26 -13
- package/dist/customize/providers/provider-accordion.js +2 -1
- package/dist/customize/providers/provider-connect.js +2 -1
- package/dist/customize/sections/component/telegram-channel-row.js +1 -1
- package/dist/customize/sections/connector-connection-modal.js +11 -9
- package/dist/customize/sections/connectors-view.js +11 -13
- package/dist/customize/sections/llm-provider/custom-provider-form.js +24 -7
- package/dist/customize/sections/llm-provider/custom-provider-panel.js +44 -8
- package/dist/customize/sections/llm-provider/types.d.ts +3 -0
- package/dist/customize/sections/llm-provider/utils.js +2 -2
- package/dist/customize/sections/view/agent-editor-access-fields.d.ts +9 -16
- package/dist/customize/sections/view/agent-editor-access-fields.js +30 -30
- package/dist/customize/sections/view/agent-editor-basics-fields.js +3 -10
- package/dist/customize/sections/view/agent-editor-primitives.d.ts +28 -10
- package/dist/customize/sections/view/agent-editor-primitives.js +32 -19
- package/dist/customize/sections/view/agent-editor.js +3 -3
- package/dist/customize/sections/view/gateway/gateway-routing.js +18 -21
- package/dist/customize/sections/view/grant-mode-field.d.ts +2 -5
- package/dist/customize/sections/view/grant-mode-field.js +10 -18
- package/dist/customize/sections/view/permission-editor.js +11 -8
- package/dist/customize/sections/view/secrets-view.js +2 -1
- package/dist/customize/settings/rail-copy-context.js +5 -3
- package/dist/customize/settings/tabs/general-tab.d.ts +9 -2
- package/dist/customize/settings/tabs/general-tab.js +33 -11
- package/dist/customize/settings/tabs/sandbox-template-form.js +9 -12
- package/dist/customize/settings/tabs/transfer-workspace-dialog.d.ts +4 -0
- package/dist/customize/settings/tabs/transfer-workspace-dialog.js +82 -0
- package/dist/customize/shared/capability-tabs.js +2 -1
- package/dist/customize/skills/skills-page.js +3 -5
- package/dist/customize/triggers/schedule/event-trigger-copy.js +3 -2
- package/dist/customize/triggers/schedule/schedule-builder.js +7 -4
- package/dist/customize/triggers/schedule/trigger-composer.js +5 -2
- package/dist/customize/triggers/schedule/when-event.js +1 -1
- package/dist/diff/diff-view.js +9 -10
- package/dist/files/editor/code-editor.js +2 -3
- package/dist/files/project/api/runtime-files.js +3 -2
- package/dist/files/project/components/change-request-detail-dialog.d.ts +3 -1
- package/dist/files/project/components/change-request-detail-dialog.js +3 -5
- package/dist/files/project/components/change-request-status-badge.d.ts +12 -0
- package/dist/files/project/components/change-request-status-badge.js +27 -0
- package/dist/files/project/components/change-requests-panel.js +1 -1
- package/dist/files/project/components/drive-explorer.js +2 -1
- package/dist/files/project/components/drive-grid-view.js +11 -7
- package/dist/files/project/components/drive-list-view.js +4 -4
- package/dist/files/project/components/file-breadcrumbs.js +1 -1
- package/dist/files/project/components/file-explorer-page.js +1 -1
- package/dist/files/project/components/file-history-popover.js +1 -6
- package/dist/files/project/components/file-search.js +6 -1
- package/dist/files/project/components/open-change-request-dialog.js +2 -1
- package/dist/files/project/components/version-selector-logic.d.ts +11 -0
- package/dist/files/project/components/version-selector-logic.js +26 -0
- package/dist/files/project/components/version-selector.js +11 -20
- package/dist/files/project/file-source.js +18 -1
- package/dist/files/project/hooks/use-file-content.js +2 -0
- package/dist/files/project/hooks/use-server-health.js +17 -15
- package/dist/files/renderers/docx/docx-viewer.js +0 -5
- package/dist/files/renderers/image-renderer.js +6 -24
- package/dist/files/renderers/pdf/pdf-viewer.js +1 -1
- package/dist/files/renderers/presentation/FullScreenPresentationViewer.js +2 -11
- package/dist/files/renderers/show-content-renderer.js +1 -1
- package/dist/files/renderers/sqlite-renderer.js +8 -3
- package/dist/files/renderers/xlsx/xlsx-viewer.js +15 -16
- package/dist/files/tree/components/file-tree-item.js +1 -1
- package/dist/files/viewer/file-header.js +1 -1
- package/dist/files/viewer/file-preview-modal.d.ts +1 -1
- package/dist/files/viewer/file-preview-modal.js +13 -3
- package/dist/files/viewer/file-source.d.ts +3 -1
- package/dist/files/viewer/use-file-content-state.js +27 -8
- package/dist/files/viewer/viewer-actions.js +2 -2
- package/dist/i18n/en.d.ts +355 -12
- package/dist/i18n/en.js +360 -17
- package/dist/internal/desktop/desktop-back-button.js +5 -3
- package/dist/internal/files/types.d.ts +2 -0
- package/dist/internal/goals/goal-meta.d.ts +30 -0
- package/dist/internal/goals/goal-meta.js +55 -0
- package/dist/internal/hooks/use-auto-scroll.js +5 -3
- package/dist/internal/lib/query-client-singleton.d.ts +9 -3
- package/dist/internal/lib/query-client-singleton.js +18 -12
- package/dist/internal/notifications/notification-rows.js +2 -1
- package/dist/internal/outcomes/outcome-types.d.ts +5 -0
- package/dist/internal/share/session-shares-modal.js +3 -7
- package/dist/internal/stores/kortix-computer-store.js +14 -2
- package/dist/internal/stores/session-hover-store.d.ts +32 -0
- package/dist/internal/stores/session-hover-store.js +38 -0
- package/dist/internal/stores/sidebar-nav-store.d.ts +1 -1
- package/dist/internal/stores/sidebar-nav-store.js +3 -1
- package/dist/lib/routes.d.ts +2 -0
- package/dist/lib/routes.js +1 -0
- package/dist/markdown/code/inline-code.js +8 -0
- package/dist/markdown/code/output-paths-context.d.ts +18 -0
- package/dist/markdown/code/output-paths-context.js +35 -0
- package/dist/markdown/genui/components/charts.js +6 -5
- package/dist/primitives/map.js +2 -1
- package/dist/primitives/preview-image.js +4 -2
- package/dist/primitives/settings-section-header.d.ts +1 -1
- package/dist/primitives/textarea.js +1 -1
- package/dist/primitives/typed-title.js +12 -14
- package/dist/primitives/typing-animation.js +4 -2
- package/dist/session/composer/agent-selector.js +6 -1
- package/dist/session/composer/attachment-tile.d.ts +0 -2
- package/dist/session/composer/attachment-tile.js +0 -8
- package/dist/session/composer/clipboard-files.d.ts +2 -1
- package/dist/session/composer/composer-chat-input.js +5 -3
- package/dist/session/composer/composer-draft-recovery.d.ts +1 -2
- package/dist/session/composer/composer-draft-recovery.js +0 -13
- package/dist/session/composer/composer-logic.js +8 -7
- package/dist/session/composer/context-ring.d.ts +1 -1
- package/dist/session/composer/context-ring.js +2 -2
- package/dist/session/composer/context-usage.d.ts +3 -6
- package/dist/session/composer/context-usage.js +3 -6
- package/dist/session/composer/draft/composer-draft.js +4 -4
- package/dist/session/composer/inbox-row-claims.d.ts +2 -2
- package/dist/session/composer/inbox-row-claims.js +1 -1
- package/dist/session/composer/pasted-text.js +3 -2
- package/dist/session/composer/queue-projection.d.ts +3 -2
- package/dist/session/composer/queued-prompt-edit.d.ts +1 -1
- package/dist/session/composer/reasoning-effort-selector.d.ts +2 -1
- package/dist/session/composer/session-composer-readiness.d.ts +7 -22
- package/dist/session/composer/session-composer-readiness.js +12 -40
- package/dist/session/composer/stores/queued-draft-store.js +3 -2
- package/dist/session/composer/token-progress.d.ts +1 -1
- package/dist/session/composer/token-progress.js +2 -2
- package/dist/session/header/reminder-parts.d.ts +11 -2
- package/dist/session/header/reminder-parts.js +9 -4
- package/dist/session/header/session-goal-indicator.d.ts +1 -0
- package/dist/session/header/session-goal-indicator.js +41 -0
- package/dist/session/header/session-site-header.js +2 -1
- package/dist/session/media/sandbox-url-detector.js +0 -7
- package/dist/session/outcomes/change-request-outcomes.js +24 -3
- package/dist/session/overrides/provider-secret-pool-editor.js +2 -1
- package/dist/session/panel/advanced/advanced-panel.js +3 -7
- package/dist/session/panel/easy/app-preview.js +12 -2
- package/dist/session/panel/easy/easy-panel-logic.d.ts +1 -1
- package/dist/session/panel/easy/easy-panel-logic.js +1 -1
- package/dist/session/panel/easy/outputs-card.js +2 -1
- package/dist/session/panel/easy/panel-card.js +5 -3
- package/dist/session/panel/easy/preview-load.d.ts +14 -0
- package/dist/session/panel/easy/preview-load.js +15 -0
- package/dist/session/panel/easy/step-detail-body.js +2 -7
- package/dist/session/panel/session-action-panel-column.js +11 -1
- package/dist/session/panel/session-audit-shared.d.ts +0 -4
- package/dist/session/panel/session-audit-shared.js +1 -1
- package/dist/session/panel/session-changes-shared.d.ts +2 -1
- package/dist/session/panel/session-panel-provider.js +6 -2
- package/dist/session/panel/shared/use-panel-derivations.js +6 -4
- package/dist/session/panel/use-session-panel-layout.js +7 -5
- package/dist/session/print/session-print-header.js +9 -8
- package/dist/session/prompts/session-permission-prompt.js +6 -3
- package/dist/session/status/provisioning-failure.d.ts +2 -1
- package/dist/session/status/session-error-banner.js +8 -6
- package/dist/session/status/session-starting-loader.d.ts +24 -31
- package/dist/session/status/session-starting-loader.js +32 -81
- package/dist/session/thread/chat-minimap-items.d.ts +4 -4
- package/dist/session/thread/first-prompt-handover.d.ts +3 -2
- package/dist/session/thread/message-parsing.d.ts +3 -3
- package/dist/session/thread/session-chat.js +15 -19
- package/dist/session/thread/session-history-scroll.d.ts +2 -1
- package/dist/session/thread/session-history.js +3 -1
- package/dist/session/thread/session-thread.js +1 -1
- package/dist/session/thread/transcript.js +13 -7
- package/dist/session/tool/shared/file-list.js +19 -2
- package/dist/session/tool/shared/infrastructure-contexts.d.ts +7 -0
- package/dist/session/tool/shared/infrastructure-contexts.js +7 -0
- package/dist/session/tool/shared/infrastructure-output.js +9 -5
- package/dist/session/tool/shared/infrastructure-row-header.js +9 -1
- package/dist/session/tool/shared/infrastructure-rows.js +7 -5
- package/dist/session/tool/tools/bash-tool.js +10 -6
- package/dist/session/tool/tools/web-search-tool.js +25 -3
- package/dist/session/turn/recovered-failures.d.ts +8 -0
- package/dist/session/turn/recovered-failures.js +32 -0
- package/dist/session/turn/streaming-cadence.js +5 -8
- package/dist/styles.css +1 -1
- package/dist/terminal/pty-connection.d.ts +5 -4
- package/dist/terminal/session-terminal-panel.js +3 -5
- package/dist/theme/theme.js +2 -1
- package/dist/workspace/index.d.ts +1 -0
- package/dist/workspace/index.js +1 -0
- package/dist/workspace/projects/modal/github-import-pickers.js +7 -6
- package/dist/workspace/review/review-center.js +13 -10
- package/dist/workspace/saved-session-skeleton-shape.d.ts +4 -3
- package/dist/workspace/saved-session-skeleton.d.ts +5 -1
- package/dist/workspace/saved-session-skeleton.js +5 -4
- package/dist/workspace/session-workspace.js +9 -14
- package/dist/workspace/sessions/deleted-session-row.js +5 -2
- package/dist/workspace/sidebar/footer/project-computer-nav.js +6 -4
- package/dist/workspace/sidebar/footer/project-goals-nav.d.ts +6 -0
- package/dist/workspace/sidebar/footer/project-goals-nav.js +26 -0
- package/dist/workspace/sidebar/footer/project-mcp-nav.js +6 -2
- package/dist/workspace/sidebar/modal/rename-session-modal.js +8 -3
- package/dist/workspace/sidebar/modal/session-embed-section.d.ts +25 -0
- package/dist/workspace/sidebar/modal/session-embed-section.js +71 -0
- package/dist/workspace/sidebar/modal/share-session-modal.js +2 -2
- package/dist/workspace/sidebar/nav-row-meta.js +14 -2
- package/dist/workspace/sidebar/project-nav-items.js +3 -0
- package/dist/workspace/sidebar/project-session-list.js +12 -3
- package/dist/workspace/sidebar/session-brief-hover-card.js +5 -8
- package/package.json +4 -4
- package/skills/kortix-ui/references/modules.md +2 -0
- package/dist/session/status/use-readiness-settling.d.ts +0 -18
- package/dist/session/status/use-readiness-settling.js +0 -43
- package/dist/workspace/sidebar/modal/session-public-link-section.d.ts +0 -13
- package/dist/workspace/sidebar/modal/session-public-link-section.js +0 -66
|
@@ -3,75 +3,79 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
3
3
|
import { uiRoutes } from '../../lib/routes.js';
|
|
4
4
|
import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
|
|
5
5
|
/**
|
|
6
|
-
* The agent editor's Access pages — Skills, Connectors, Secrets
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* select mode: its checkbox says whether the agent is granted the thing, its
|
|
11
|
-
* body opens the thing itself — `EntityDetailModal` for a skill,
|
|
12
|
-
* `ConnectorModal` for a connector, `ProjectSecretDialog` for a secret.
|
|
6
|
+
* The agent editor's Access pages — Skills, Connectors, Secrets, Apps. Each
|
|
7
|
+
* opens the SAME modal as the project-wide tab of the same name:
|
|
8
|
+
* `EntityDetailModal` for a skill, `ConnectorModal` for a connector,
|
|
9
|
+
* `ProjectSecretDialog` for a secret.
|
|
13
10
|
*
|
|
14
|
-
*
|
|
15
|
-
* `grant-mode-field.tsx
|
|
16
|
-
*
|
|
11
|
+
* Layout is the Settings page's: the pane title, one All · Pick · None row
|
|
12
|
+
* (`grant-mode-field.tsx`), then the catalog as one bordered list. The list
|
|
13
|
+
* stays on screen in every mode, so a person can still open any entry.
|
|
17
14
|
*/
|
|
18
15
|
import { Badge } from '../../primitives/badge.js';
|
|
19
16
|
import { Button } from '../../primitives/button.js';
|
|
17
|
+
import { Checkbox } from '../../primitives/checkbox.js';
|
|
18
|
+
import { Skeleton } from '../../primitives/skeleton.js';
|
|
20
19
|
import { EmptyState } from '../../primitives/empty-state.js';
|
|
21
20
|
import { ErrorState } from '../../primitives/error-state.js';
|
|
22
21
|
import { connectorDisplayName } from '../connectors/connector-filter.js';
|
|
23
|
-
import { ConnectorAppIcon,
|
|
22
|
+
import { ConnectorAppIcon, ConnectorStatusBadge, } from '../connectors/connector-identity.js';
|
|
24
23
|
import { ConnectorModal } from '../connectors/detail/connector-modal.js';
|
|
25
24
|
import { providerLabel } from '../connectors/provider-label.js';
|
|
26
|
-
import { CatalogCard } from '../shared/catalog/catalog-card.js';
|
|
27
|
-
import { CatalogGridSkeleton } from '../shared/catalog/catalog-grid.js';
|
|
28
25
|
import { detailSelection } from '../shared/detail-selection.js';
|
|
29
26
|
import { EntityDetailModal } from '../shared/entity/entity-modal.js';
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import { EditorSection } from '../sections/view/agent-editor-primitives.js';
|
|
27
|
+
import { ManageButton, RequiredConnectorToggle, } from '../sections/view/agent-editor-access-fields.js';
|
|
28
|
+
import { EditorList, EditorSection } from '../sections/view/agent-editor-primitives.js';
|
|
33
29
|
import { GrantModeField } from '../sections/view/grant-mode-field.js';
|
|
34
30
|
import { buildRows, ProjectSecretDialog, } from '../sections/view/secrets-view.js';
|
|
35
31
|
import { toArray } from '../shared/utils.js';
|
|
36
32
|
import { PROJECT_ACTIONS } from '../../internal/lib/project-actions.js';
|
|
33
|
+
import { cn } from '../../internal/lib/utils.js';
|
|
37
34
|
import { useProjectCan } from '../../internal/lib/use-project-can.js';
|
|
38
35
|
import { listConnectors, listProjectSecrets, } from '@kortix/sdk';
|
|
39
36
|
import { contract, qk, useProjectAccountId, useProjectApps, } from '@kortix/sdk/react';
|
|
40
|
-
import {
|
|
37
|
+
import { PlusIcon } from '@phosphor-icons/react';
|
|
41
38
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
|
42
|
-
import {
|
|
39
|
+
import { useState } from 'react';
|
|
43
40
|
import { appGrantRows } from './agent-apps-grant.js';
|
|
44
41
|
/**
|
|
45
|
-
* All · Pick · None over
|
|
46
|
-
*
|
|
47
|
-
*
|
|
42
|
+
* All · Pick · None over the project's catalog, as one bordered list. The
|
|
43
|
+
* checkbox exists only in Pick mode, where it is the control; in All and
|
|
44
|
+
* None the mode row above already answers for every row. A granted id the
|
|
45
|
+
* catalog no longer has still renders, flagged, so a stale grant is visible
|
|
46
|
+
* rather than silently dropped.
|
|
48
47
|
*/
|
|
49
|
-
function GrantCatalog({ value, onChange,
|
|
48
|
+
function GrantCatalog({ value, onChange, items, isLoading, isError, onRetry, empty, trailingFor, }) {
|
|
50
49
|
const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
|
|
51
|
-
return (_jsx(GrantModeField, { value: value, onChange: onChange,
|
|
52
|
-
if (isLoading)
|
|
53
|
-
return _jsx(
|
|
50
|
+
return (_jsx(GrantModeField, { value: value, onChange: onChange, alwaysRender: true, children: ({ selected, toggle, mode }) => {
|
|
51
|
+
if (isLoading) {
|
|
52
|
+
return (_jsx(EditorList, { children: [0, 1, 2].map((i) => (_jsx("li", { className: "flex items-center gap-3 px-4 py-3", children: _jsx(Skeleton, { className: "h-4 w-40 rounded-sm" }) }, i))) }));
|
|
53
|
+
}
|
|
54
54
|
if (isError) {
|
|
55
55
|
return (_jsx(ErrorState, { size: "sm", title: tI18nComplete.raw('text3f2d97c61a7e'), action: onRetry ? (_jsx(Button, { variant: "outline", size: "sm", onClick: onRetry, children: tI18nComplete.raw('text942087cc2d41') })) : undefined }));
|
|
56
56
|
}
|
|
57
57
|
const known = new Set(items.map((i) => i.id));
|
|
58
|
-
const orphans = [...selected]
|
|
58
|
+
const orphans = [...selected]
|
|
59
|
+
.filter((id) => !known.has(id))
|
|
60
|
+
.map((id) => ({
|
|
61
|
+
id,
|
|
62
|
+
title: _jsx("span", { className: "font-mono", children: id }),
|
|
63
|
+
description: tI18nComplete.raw('textfecc36d012be'),
|
|
64
|
+
status: (_jsx(Badge, { variant: "destructive", size: "xs", children: tI18nComplete.raw('text6be36ca49ee8') })),
|
|
65
|
+
}));
|
|
59
66
|
if (items.length === 0 && orphans.length === 0)
|
|
60
67
|
return _jsx(_Fragment, { children: empty });
|
|
61
|
-
|
|
62
|
-
return (_jsxs("div", { className: "grid gap-2", children: [items.map((item) => (_jsx(CatalogCard, { ...item.card, trailing: _jsxs("span", { className: "flex items-center gap-1.5", children: [item.card.trailing, mode === 'pick' && selected.has(item.id) ? trailingFor?.(item.id) : null] }), onClick: item.onOpen, select: {
|
|
63
|
-
checked: checked(item.id),
|
|
64
|
-
onCheckedChange: () => toggle(item.id),
|
|
65
|
-
disabled: mode !== 'pick',
|
|
66
|
-
label: tI18nComplete('textd4170e74c3b0', { value0: item.id }),
|
|
67
|
-
} }, item.id))), orphans.map((id) => (_jsx(CatalogCard, { title: _jsx("span", { className: "font-mono", children: id }), description: tI18nComplete.raw('textfecc36d012be'), badges: _jsx(Badge, { variant: "destructive", size: "xs", children: tI18nComplete.raw('text6be36ca49ee8') }), select: {
|
|
68
|
-
checked: true,
|
|
69
|
-
onCheckedChange: () => toggle(id),
|
|
70
|
-
disabled: mode !== 'pick',
|
|
71
|
-
label: tI18nComplete('textd4170e74c3b0', { value0: id }),
|
|
72
|
-
} }, id)))] }));
|
|
68
|
+
return (_jsx(EditorList, { children: [...items, ...orphans].map((item) => (_jsx(GrantRow, { item: item, mode: mode, checked: selected.has(item.id), onToggle: () => toggle(item.id), checkLabel: tI18nComplete('textd4170e74c3b0', { value0: item.id }), trailing: mode === 'pick' && selected.has(item.id) ? trailingFor?.(item.id) : null }, item.id))) }));
|
|
73
69
|
} }));
|
|
74
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* One catalog row. The checkbox and the body are two sibling controls, never
|
|
73
|
+
* one nested in the other: the checkbox grants, the body opens the entity.
|
|
74
|
+
*/
|
|
75
|
+
function GrantRow({ item, mode, checked, onToggle, checkLabel, trailing, }) {
|
|
76
|
+
const body = (_jsxs(_Fragment, { children: [item.leading, _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "text-foreground block truncate text-sm font-medium", children: item.title }), item.description ? (_jsx("span", { className: "text-muted-foreground block truncate text-xs", children: item.description })) : null] })] }));
|
|
77
|
+
return (_jsxs("li", { className: cn('flex min-h-13 items-center gap-3 px-4 py-2 transition-colors duration-fast', item.onOpen && 'hover:bg-hover', mode === 'none' && 'opacity-60'), children: [mode === 'pick' ? (_jsx(Checkbox, { variant: "black", checked: checked, onCheckedChange: onToggle, "aria-label": checkLabel })) : null, item.onOpen ? (_jsx("button", { type: "button", onClick: item.onOpen, className: "focus-visible:ring-ring/50 flex min-w-0 flex-1 items-center gap-3 rounded-sm text-left focus-visible:ring-2 focus-visible:outline-none", children: body })) : (_jsx("span", { className: "flex min-w-0 flex-1 items-center gap-3", children: body })), item.status || trailing ? (_jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [item.status, trailing] })) : null] }));
|
|
78
|
+
}
|
|
75
79
|
// ─── Skills ──────────────────────────────────────────────────────────────
|
|
76
80
|
export function SkillsGrantPage({ projectId, config, editor, }) {
|
|
77
81
|
const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
|
|
@@ -82,11 +86,12 @@ export function SkillsGrantPage({ projectId, config, editor, }) {
|
|
|
82
86
|
record: skills.find((skill) => skill.path === selectedPath),
|
|
83
87
|
isSuccess: true,
|
|
84
88
|
});
|
|
85
|
-
return (_jsxs(_Fragment, { children: [_jsx(EditorSection, { title: tI18nComplete.raw('text66d0f523a379'), description: tI18nComplete.raw('text836cd8e8a791'), trailing: _jsx(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
return (_jsxs(_Fragment, { children: [_jsx(EditorSection, { title: tI18nComplete.raw('text66d0f523a379'), description: tI18nComplete.raw('text836cd8e8a791'), trailing: _jsx(ManageButton, { tab: "skills" }), lead: true, bare: true, children: _jsx(GrantCatalog, { value: editor.draft.skills, onChange: (v) => editor.set('skills', v), items: skills.map((skill) => ({
|
|
90
|
+
id: skill.name,
|
|
91
|
+
title: skill.name,
|
|
92
|
+
description: skill.description,
|
|
93
|
+
onOpen: () => setSelectedPath(skill.path),
|
|
94
|
+
})), empty: _jsx(EmptyState, { size: "sm", title: tI18nComplete.raw('text32ae9b80f832'), description: tI18nComplete.raw('text62d220bbfcc8') }) }) }), _jsx(EntityDetailModal, { projectId: projectId, entity: detail.record, kind: "skill", open: detail.open, isResolving: detail.isResolving, onOpenChange: (next) => {
|
|
90
95
|
if (!next)
|
|
91
96
|
setSelectedPath(null);
|
|
92
97
|
} })] }));
|
|
@@ -110,30 +115,26 @@ export function ConnectorsGrantPage({ projectId, editor, }) {
|
|
|
110
115
|
record: connectors.find((c) => c.slug === detailSlug),
|
|
111
116
|
isSuccess: connectorsQuery.isSuccess,
|
|
112
117
|
});
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
setDetailSlug(null);
|
|
116
|
-
}, [detail.isMissing]);
|
|
118
|
+
if (detail.isMissing)
|
|
119
|
+
setDetailSlug(null);
|
|
117
120
|
const invalidate = () => queryClient.invalidateQueries({ queryKey: qk.project.connectors(projectId) });
|
|
118
121
|
const { draft, set } = editor;
|
|
119
|
-
return (_jsxs(_Fragment, { children: [_jsx(EditorSection, { title: tI18nComplete.raw('textc3d2e79ebdd0'), description: tI18nComplete.raw('textc174fc077197'), trailing: _jsx(
|
|
122
|
+
return (_jsxs(_Fragment, { children: [_jsx(EditorSection, { title: tI18nComplete.raw('textc3d2e79ebdd0'), description: tI18nComplete.raw('textc174fc077197'), trailing: _jsx(ManageButton, { tab: "connectors" }), lead: true, bare: true, children: _jsxs("div", { className: "space-y-3", children: [_jsx(GrantCatalog, { value: draft.connectors, onChange: (v) => {
|
|
120
123
|
set('connectors', v);
|
|
121
124
|
const required = draft.connectors_required ?? [];
|
|
125
|
+
const picked = new Set(Array.isArray(v) ? v : []);
|
|
122
126
|
const kept = v === 'all' || v === 'none' || !Array.isArray(v)
|
|
123
127
|
? []
|
|
124
|
-
: required.filter((slug) =>
|
|
128
|
+
: required.filter((slug) => picked.has(slug));
|
|
125
129
|
if (kept.length !== required.length) {
|
|
126
130
|
set('connectors_required', kept.length ? kept : undefined);
|
|
127
131
|
}
|
|
128
|
-
},
|
|
132
|
+
}, isLoading: connectorsQuery.isLoading, isError: connectorsQuery.isError, onRetry: () => void connectorsQuery.refetch(), items: connectors.map((connector) => ({
|
|
129
133
|
id: connector.slug,
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
badges: _jsx(ConnectorStatusBadge, { connector: connector }),
|
|
135
|
-
trailing: connectorSetupStatus(connector) === 'connected' ? (_jsx(ConnectorConnectedMark, {})) : undefined,
|
|
136
|
-
},
|
|
134
|
+
leading: _jsx(ConnectorAppIcon, { connector: connector, size: "sm" }),
|
|
135
|
+
title: connectorDisplayName(connector),
|
|
136
|
+
description: `${providerLabel(connector.provider)} · ${connector.actions.length} ${connector.actions.length === 1 ? 'action' : 'actions'}`,
|
|
137
|
+
status: _jsx(ConnectorStatusBadge, { connector: connector }),
|
|
137
138
|
onOpen: () => setDetailSlug(connector.slug),
|
|
138
139
|
})), trailingFor: (slug) => (_jsx(RequiredConnectorToggle, { active: draft.connectors_required?.includes(slug) === true, onToggle: () => {
|
|
139
140
|
const current = draft.connectors_required ?? [];
|
|
@@ -161,16 +162,13 @@ export function SecretsGrantPage({ projectId, editor }) {
|
|
|
161
162
|
open: false,
|
|
162
163
|
row: null,
|
|
163
164
|
});
|
|
164
|
-
return (_jsxs(_Fragment, { children: [_jsx(EditorSection, { title: tI18nComplete.raw('textd8707d411d99'), description: tI18nComplete.raw('textbb74cc7dce98'), trailing:
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
},
|
|
172
|
-
onOpen: () => setDialog({ open: true, row }),
|
|
173
|
-
})), empty: _jsx(EmptyState, { icon: KeyIcon, size: "sm", title: tI18nComplete.raw('text5aa40906d187'), description: tI18nComplete.raw('textfc7605717e58'), action: canWrite ? (_jsxs(Button, { variant: "outline", size: "sm", className: "gap-1.5", onClick: () => setDialog({ open: true, row: null }), children: [_jsx(PlusIcon, { className: "size-4" }), tI18nComplete.raw('text98aa52b34c8f')] })) : undefined }) }) }) }), _jsx(ProjectSecretDialog, { projectId: projectId, row: dialog.row, open: dialog.open, onOpenChange: (open) => setDialog((d) => ({ ...d, open })) })] }));
|
|
165
|
+
return (_jsxs(_Fragment, { children: [_jsx(EditorSection, { title: tI18nComplete.raw('textd8707d411d99'), description: tI18nComplete.raw('textbb74cc7dce98'), trailing: canWrite ? (_jsxs(Button, { variant: "secondary", size: "sm", className: "gap-1.5", onClick: () => setDialog({ open: true, row: null }), children: [_jsx(PlusIcon, { className: "size-4" }), tI18nComplete.raw('text18fdd549b2ed')] })) : undefined, lead: true, bare: true, children: _jsx(GrantCatalog, { value: editor.draft.secrets, onChange: (v) => editor.set('secrets', v), isLoading: secretsQuery.isLoading, isError: secretsQuery.isError, onRetry: () => void secretsQuery.refetch(), items: rows.map((row) => ({
|
|
166
|
+
id: row.identifier,
|
|
167
|
+
title: _jsx("span", { className: "font-mono", children: row.identifier }),
|
|
168
|
+
description: row.purpose ?? (row.key !== row.identifier ? `Env var ${row.key}` : null),
|
|
169
|
+
status: !row.configured || row.system ? (_jsxs(_Fragment, { children: [!row.configured ? (_jsx(Badge, { variant: "destructive", size: "xs", children: tI18nComplete.raw('text4fd0272a5628') })) : null, row.system ? (_jsx(Badge, { variant: "muted", size: "xs", children: tI18nComplete.raw('text6725e7bbcd28') })) : null] })) : undefined,
|
|
170
|
+
onOpen: () => setDialog({ open: true, row }),
|
|
171
|
+
})), empty: _jsx(EmptyState, { size: "sm", title: tI18nComplete.raw('text5aa40906d187'), description: tI18nComplete.raw('textfc7605717e58'), action: canWrite ? (_jsxs(Button, { variant: "outline", size: "sm", className: "gap-1.5", onClick: () => setDialog({ open: true, row: null }), children: [_jsx(PlusIcon, { className: "size-4" }), tI18nComplete.raw('text98aa52b34c8f')] })) : undefined }) }) }), _jsx(ProjectSecretDialog, { projectId: projectId, row: dialog.row, open: dialog.open, onOpenChange: (open) => setDialog((d) => ({ ...d, open })) })] }));
|
|
174
172
|
}
|
|
175
173
|
// ─── Apps ────────────────────────────────────────────────────────────────
|
|
176
174
|
/**
|
|
@@ -191,13 +189,12 @@ export function AppsGrantPage({ projectId, editor }) {
|
|
|
191
189
|
const t = useI18nTranslations('agentApps');
|
|
192
190
|
const appsQuery = useProjectApps(projectId);
|
|
193
191
|
const rows = appGrantRows(appsQuery.data);
|
|
194
|
-
return (_jsx(EditorSection, { title: t('title'), description: t('description'), trailing: _jsx(
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
})), empty: _jsx(EmptyState, { icon: GlobeIcon, size: "sm", title: t('emptyTitle'), description: t('emptyDescription') }) }), _jsx("p", { className: "text-muted-foreground text-xs text-pretty", children: t('grantNote') })] }) }));
|
|
192
|
+
return (_jsx(EditorSection, { title: t('title'), description: t('description'), trailing: _jsx(ManageButton, { href: (id) => uiRoutes().apps(id) }), lead: true, bare: true, children: _jsx("div", { className: "space-y-3", "data-testid": "agent-apps-grant", children: _jsx(GrantCatalog, { value: editor.draft.apps, onChange: (v) => editor.set('apps', v), isLoading: appsQuery.isLoading, isError: appsQuery.isError, onRetry: () => void appsQuery.refetch(), items: rows.map((row) => ({
|
|
193
|
+
id: row.id,
|
|
194
|
+
title: _jsx("span", { className: "font-mono", children: row.id }),
|
|
195
|
+
description: row.name === row.id ? null : row.name,
|
|
196
|
+
// The grant decides admission for a restricted or private App, the
|
|
197
|
+
// normal case. Only an App that admits agents without it is flagged.
|
|
198
|
+
status: row.needsGrant ? undefined : (_jsx(Badge, { variant: "muted", size: "xs", children: t('openWithoutGrant') })),
|
|
199
|
+
})), empty: _jsx(EmptyState, { size: "sm", title: t('emptyTitle'), description: t('emptyDescription') }) }) }) }));
|
|
203
200
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export declare const PROTOTYPE_ENABLED: boolean;
|
|
3
|
+
export declare const NAV_VARIANTS: readonly [{
|
|
4
|
+
readonly key: "rail";
|
|
5
|
+
}, {
|
|
6
|
+
readonly key: "tabs";
|
|
7
|
+
}, {
|
|
8
|
+
readonly key: "groups";
|
|
9
|
+
}, {
|
|
10
|
+
readonly key: "inline";
|
|
11
|
+
}];
|
|
12
|
+
export type NavVariant = (typeof NAV_VARIANTS)[number]['key'];
|
|
13
|
+
export declare function useNavVariant(): NavVariant;
|
|
14
|
+
export interface NavItem {
|
|
15
|
+
key: string;
|
|
16
|
+
label: string;
|
|
17
|
+
group: string;
|
|
18
|
+
}
|
|
19
|
+
interface NavProps {
|
|
20
|
+
groups: {
|
|
21
|
+
group: string;
|
|
22
|
+
items: NavItem[];
|
|
23
|
+
}[];
|
|
24
|
+
section: string;
|
|
25
|
+
href: (key: string) => string;
|
|
26
|
+
/** The current value per topic — "All", "2 picked", the model name. */
|
|
27
|
+
summaries?: Partial<Record<string, string>>;
|
|
28
|
+
}
|
|
29
|
+
export declare function GroupedUnderlineTabs({ groups, section, href }: NavProps): import("react").JSX.Element;
|
|
30
|
+
export declare function GroupSwitchTabs({ groups, section, href }: NavProps): import("react").JSX.Element;
|
|
31
|
+
export declare function InlineVerticalTabs({ groups, section, href, summaries, children, }: NavProps & {
|
|
32
|
+
children: ReactNode;
|
|
33
|
+
}): import("react").JSX.Element;
|
|
34
|
+
export declare function PrototypeSwitcher(): import("react").JSX.Element | null;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* PROTOTYPE — throwaway. Answers one question: what replaces the agent page's
|
|
5
|
+
* left rail? Rendered on the real agent page, switched with `?variant=`:
|
|
6
|
+
*
|
|
7
|
+
* rail — today's left rail (the baseline; no param)
|
|
8
|
+
* tabs — grouped underline tabs under the header, no rail
|
|
9
|
+
* groups — General / Access / Runtime switch + that group's tabs
|
|
10
|
+
* inline — vertical tabs beside the content column, each with its value
|
|
11
|
+
*
|
|
12
|
+
* Read-only navigation over the same `?section=` links; nothing here mutates.
|
|
13
|
+
* Once a variant wins, fold it into `agent-page.tsx` properly and delete this
|
|
14
|
+
* file and the switcher. Dev builds only (`PROTOTYPE_ENABLED`).
|
|
15
|
+
*/
|
|
16
|
+
import { CaretLeftIcon, CaretRightIcon } from '@phosphor-icons/react';
|
|
17
|
+
import { useCallback, useEffect } from 'react';
|
|
18
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
19
|
+
import { cn } from '../../internal/lib/utils.js';
|
|
20
|
+
import { Tabs, TabsList, TabsTrigger } from '../../primitives/tabs.js';
|
|
21
|
+
import { UiLink as Link, useUiPathname as usePathname, useUiRouter as useRouter, useUiSearchParams as useSearchParams, } from '../../providers/ui-provider.js';
|
|
22
|
+
export const PROTOTYPE_ENABLED = process.env.NODE_ENV !== 'production';
|
|
23
|
+
export const NAV_VARIANTS = [{ key: 'rail' }, { key: 'tabs' }, { key: 'groups' }, { key: 'inline' }];
|
|
24
|
+
export function useNavVariant() {
|
|
25
|
+
const raw = useSearchParams().get('variant');
|
|
26
|
+
if (!PROTOTYPE_ENABLED)
|
|
27
|
+
return 'rail';
|
|
28
|
+
return NAV_VARIANTS.some((v) => v.key === raw) ? raw : 'rail';
|
|
29
|
+
}
|
|
30
|
+
/** `?section=` link that keeps `?variant=` so switching topics stays in the variant. */
|
|
31
|
+
function useVariantHref(href) {
|
|
32
|
+
const variant = useSearchParams().get('variant');
|
|
33
|
+
return (key) => (variant ? `${href(key)}&variant=${variant}` : href(key));
|
|
34
|
+
}
|
|
35
|
+
// ─── tabs: grouped underline tabs ──────────────────────────────────────────
|
|
36
|
+
export function GroupedUnderlineTabs({ groups, section, href }) {
|
|
37
|
+
const to = useVariantHref(href);
|
|
38
|
+
return (_jsx("nav", { className: "border-border/60 flex shrink-0 items-end gap-8 overflow-x-auto border-b px-5 pt-1", children: groups.map((g) => (_jsxs("div", { className: "flex shrink-0 flex-col gap-1", children: [_jsx("span", { className: "text-muted-foreground px-2 text-xs", children: g.group }), _jsx(Tabs, { value: section, children: _jsx(TabsList, { type: "underline", className: "h-auto gap-1 border-b-0", children: g.items.map((item) => (_jsx(TabsTrigger, { value: item.key, asChild: true, className: "w-fit flex-none px-2", children: _jsx(Link, { href: to(item.key), prefetch: true, children: item.label }) }, item.key))) }) })] }, g.group))) }));
|
|
39
|
+
}
|
|
40
|
+
// ─── groups: group switch + sub tabs ───────────────────────────────────────
|
|
41
|
+
export function GroupSwitchTabs({ groups, section, href }) {
|
|
42
|
+
const to = useVariantHref(href);
|
|
43
|
+
const active = groups.find((g) => g.items.some((i) => i.key === section)) ?? groups[0];
|
|
44
|
+
return (_jsxs("nav", { className: "border-border/60 flex shrink-0 items-center gap-5 overflow-x-auto border-b px-5 py-2", children: [_jsx(Tabs, { value: active?.group, children: _jsx(TabsList, { children: groups.map((g) => (_jsx(TabsTrigger, { value: g.group, asChild: true, className: "w-fit flex-none", children: _jsx(Link, { href: to(g.items[0].key), prefetch: true, children: g.group }) }, g.group))) }) }), _jsx(Tabs, { value: section, children: _jsx(TabsList, { type: "underline", className: "h-auto gap-1 border-b-0", children: active?.items.map((item) => (_jsx(TabsTrigger, { value: item.key, asChild: true, className: "w-fit flex-none px-2", children: _jsx(Link, { href: to(item.key), prefetch: true, children: item.label }) }, item.key))) }) })] }));
|
|
45
|
+
}
|
|
46
|
+
// ─── inline: vertical tabs beside the content, with values ────────────────
|
|
47
|
+
export function InlineVerticalTabs({ groups, section, href, summaries, children, }) {
|
|
48
|
+
const to = useVariantHref(href);
|
|
49
|
+
return (_jsxs("div", { className: "mx-auto flex w-full max-w-5xl items-start gap-14 px-4 py-10 pb-32 lg:py-14", children: [_jsx("nav", { className: "sticky top-0 flex w-52 shrink-0 flex-col gap-4", children: groups.map((g) => (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground px-2.5 pb-1 text-xs", children: g.group }), g.items.map((item) => {
|
|
50
|
+
const isActive = item.key === section;
|
|
51
|
+
return (_jsxs(Link, { href: to(item.key), prefetch: true, "aria-current": isActive ? 'page' : undefined, className: cn('flex items-center justify-between gap-3 rounded-md px-2.5 py-1.5 text-sm transition-none', isActive
|
|
52
|
+
? 'bg-active text-foreground font-medium'
|
|
53
|
+
: 'text-muted-foreground hover:bg-hover hover:text-foreground'), children: [_jsx("span", { className: "truncate", children: item.label }), summaries?.[item.key] ? (_jsx("span", { className: "text-muted-foreground shrink-0 text-xs font-normal tabular-nums", children: summaries[item.key] })) : null] }, item.key));
|
|
54
|
+
})] }, g.group))) }), _jsx("div", { className: "min-w-0 max-w-2xl flex-1", children: children })] }));
|
|
55
|
+
}
|
|
56
|
+
// ─── the floating switcher ────────────────────────────────────────────────
|
|
57
|
+
export function PrototypeSwitcher() {
|
|
58
|
+
const router = useRouter();
|
|
59
|
+
const pathname = usePathname();
|
|
60
|
+
const search = useSearchParams();
|
|
61
|
+
const current = useNavVariant();
|
|
62
|
+
const t = useTranslations('agentNavPrototype');
|
|
63
|
+
const labels = {
|
|
64
|
+
rail: t('variantRail'),
|
|
65
|
+
tabs: t('variantTabs'),
|
|
66
|
+
groups: t('variantGroups'),
|
|
67
|
+
inline: t('variantInline'),
|
|
68
|
+
};
|
|
69
|
+
const index = NAV_VARIANTS.findIndex((v) => v.key === current);
|
|
70
|
+
const go = useCallback((step) => {
|
|
71
|
+
const next = NAV_VARIANTS[(index + step + NAV_VARIANTS.length) % NAV_VARIANTS.length];
|
|
72
|
+
const params = new URLSearchParams(search.toString());
|
|
73
|
+
if (next.key === 'rail')
|
|
74
|
+
params.delete('variant');
|
|
75
|
+
else
|
|
76
|
+
params.set('variant', next.key);
|
|
77
|
+
router.replace(`${pathname}?${params.toString()}`, { scroll: false });
|
|
78
|
+
}, [index, pathname, router, search]);
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const onKey = (event) => {
|
|
81
|
+
const target = event.target;
|
|
82
|
+
if (target?.closest('input, textarea, select, [contenteditable="true"]'))
|
|
83
|
+
return;
|
|
84
|
+
if (event.key === 'ArrowLeft')
|
|
85
|
+
go(-1);
|
|
86
|
+
if (event.key === 'ArrowRight')
|
|
87
|
+
go(1);
|
|
88
|
+
};
|
|
89
|
+
window.addEventListener('keydown', onKey);
|
|
90
|
+
return () => window.removeEventListener('keydown', onKey);
|
|
91
|
+
}, [go]);
|
|
92
|
+
if (!PROTOTYPE_ENABLED)
|
|
93
|
+
return null;
|
|
94
|
+
return (_jsx("div", { className: "pointer-events-none fixed inset-x-0 bottom-20 z-50 flex justify-center", children: _jsxs("div", { className: "bg-foreground text-background pointer-events-auto flex items-center gap-1 rounded-full p-1 shadow-lg", children: [_jsx("button", { type: "button", "aria-label": t('previousVariant'), onClick: () => go(-1), className: "flex size-7 items-center justify-center rounded-full hover:bg-background/15", children: _jsx(CaretLeftIcon, { className: "size-3.5" }) }), _jsxs("span", { className: "min-w-56 px-2 text-center text-xs tabular-nums", children: [String.fromCharCode(65 + index), " \u00B7 ", labels[NAV_VARIANTS[index].key]] }), _jsx("button", { type: "button", "aria-label": t('nextVariant'), onClick: () => go(1), className: "flex size-7 items-center justify-center rounded-full hover:bg-background/15", children: _jsx(CaretRightIcon, { className: "size-3.5" }) })] }) }));
|
|
95
|
+
}
|