@agent-native/core 0.98.0 → 0.98.2
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +32 -0
- package/corpus/core/docs/content/locales/ar-SA/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/pr-visual-recap.mdx +25 -1
- package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +1 -1
- package/corpus/core/docs/content/pr-visual-recap.mdx +50 -1
- package/corpus/core/docs/content/template-plan.mdx +1 -1
- package/corpus/core/package.json +2 -2
- package/corpus/core/src/action-change-marker.ts +8 -1
- package/corpus/core/src/changelog/parse.ts +8 -3
- package/corpus/core/src/cli/plan-local.ts +43 -11
- package/corpus/core/src/cli/pr-visual-recap-workflow.ts +2 -9
- package/corpus/core/src/cli/recap.ts +356 -4
- package/corpus/core/src/cli/skills-content/local-files.ts +17 -12
- package/corpus/core/src/client/AgentPanel.tsx +2 -3
- package/corpus/core/src/client/AssistantChat.tsx +83 -39
- package/corpus/core/src/client/analytics.ts +125 -14
- package/corpus/core/src/client/blocks/library/wireframe-kit.tsx +16 -2
- package/corpus/core/src/client/chat-model-groups.ts +28 -0
- package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +442 -85
- package/corpus/core/src/client/composer/TiptapComposer.tsx +46 -29
- package/corpus/core/src/client/composer/VoiceButton.tsx +2 -1
- package/corpus/core/src/client/composer/index.ts +5 -0
- package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +1206 -67
- package/corpus/core/src/client/index.ts +10 -0
- package/corpus/core/src/client/progress/RunsTray.tsx +13 -1
- package/corpus/core/src/client/session-replay.ts +10 -0
- package/corpus/core/src/client/settings/DemoModeSection.tsx +4 -28
- package/corpus/core/src/client/settings/SecretsSection.tsx +387 -266
- package/corpus/core/src/client/settings/SettingsPanel.tsx +117 -38
- package/corpus/core/src/client/url-scrub.ts +13 -0
- package/corpus/core/src/client/use-action.ts +12 -0
- package/corpus/core/src/client/use-agent-chat-home-handoff.ts +8 -1
- package/corpus/core/src/client/use-agent-engine-configured.ts +17 -3
- package/corpus/core/src/client/use-db-sync.ts +84 -34
- package/corpus/core/src/client/use-demo-mode-status.ts +44 -0
- package/corpus/core/src/client/use-pausing-interval.ts +14 -4
- package/corpus/core/src/integrations/scope-store.ts +1 -1
- package/corpus/core/src/integrations/usage-budget-store.ts +1 -1
- package/corpus/core/src/localization/default-messages.ts +44 -1
- package/corpus/core/src/mcp-client/workspace-servers.ts +4 -4
- package/corpus/core/src/secrets/crypto.ts +28 -8
- package/corpus/core/src/server/action-change.ts +5 -1
- package/corpus/core/src/server/action-routes.ts +8 -0
- package/corpus/core/src/server/poll.ts +1 -0
- package/corpus/core/src/server/realtime-voice.ts +299 -13
- package/corpus/core/src/styles/agent-native.css +2 -2
- package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +7 -3
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -9
- package/corpus/core/src/vite/client.ts +9 -1
- package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +10 -5
- package/corpus/templates/analytics/AGENTS.md +17 -13
- package/corpus/templates/analytics/actions/navigate.ts +59 -5
- package/corpus/templates/analytics/actions/view-screen.ts +3 -6
- package/corpus/templates/analytics/app/components/ProviderCorpusJobNotifier.tsx +20 -3
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +20 -5
- package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +21 -6
- package/corpus/templates/analytics/app/global.css +19 -20
- package/corpus/templates/analytics/app/lib/demo-chart-trend.ts +156 -0
- package/corpus/templates/analytics/app/lib/provider-corpus-job-sync.ts +26 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +35 -341
- package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +38 -7
- package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +1 -1
- package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +3 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +333 -272
- package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +72 -17
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +297 -108
- package/corpus/templates/analytics/app/root.tsx +28 -8
- package/corpus/templates/analytics/changelog/2026-06-24-first-party-signup-and-pageview-panels-now-honor-dashboard-filters.md +2 -1
- package/corpus/templates/analytics/changelog/2026-06-25-referrer-dashboard-panels-show-external-domains.md +2 -1
- package/corpus/templates/analytics/changelog/2026-07-06-mobile-chat-header-is-more-compact-and-the-menu-button-opens-navigation.md +1 -0
- package/corpus/templates/analytics/changelog/2026-07-08-dashboard-history-and-chat-context.md +1 -0
- package/corpus/templates/analytics/changelog/2026-07-08-settings-are-cleaner-searchable-and-alerts-have-their-own-tab.md +1 -0
- package/corpus/templates/analytics/changelog/2026-07-08-sidebar-sections-stay-collapsed-until-opened.md +1 -0
- package/corpus/templates/analytics/changelog/2026-07-11-analytics-no-longer-repeatedly-restarts-background-requests-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-analytics-only-asks-for-replay-storage-when-you-enable-sessi.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-charts-now-show-their-loading-skeleton-while-refreshing.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-realtime-voice-now-shows-a-clear-connection-indicator-comple.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-replay-event-counts-stay-hidden-until-recordings-finish-load.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-replay-storage-key-mismatches-show-actionable-setup-guidance.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-replay-timelines-group-continuous-scrolling-and-dev-tools-co.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-session-filters-now-stay-compact-in-a-settings-menu-at-mediu.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-session-replay-console-errors-now-link-to-matching-issues-or.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-session-replays-load-large-recordings-faster-and-surface-fai.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-session-replays-preserve-recorded-styles-and-viewport-layout.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-11-session-replays-stay-centered-instead-of-clipping-wide-recor.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-daily-dashboard-emails-reliably-include-the-complete-dashboa.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-demo-mode-charts-trend-upward.md +6 -0
- package/corpus/templates/analytics/package.json +1 -1
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +1 -303
- package/corpus/templates/analytics/server/handlers/session-replay.ts +57 -0
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +2 -0
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +1 -1
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +17 -33
- package/corpus/templates/analytics/server/lib/demo-dashboards.ts +16 -3
- package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +12 -0
- package/corpus/templates/analytics/server/lib/session-replay.ts +208 -2
- package/corpus/templates/analytics/server/plugins/onboarding.ts +7 -79
- package/corpus/templates/analytics/server/routes/api/session-replay/recordings/[recordingId]/chunks.get.ts +1 -0
- package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/templates/assets/app/global.css +4 -4
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +0 -1
- package/corpus/templates/assets/app/routes/library.tsx +0 -1
- package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/templates/brain/app/global.css +5 -5
- package/corpus/templates/brain/app/root.tsx +0 -3
- package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/templates/calendar/app/root.tsx +1 -0
- package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/templates/clips/app/components/player/video-player.tsx +5 -1
- package/corpus/templates/clips/app/hooks/use-auto-title.ts +74 -8
- package/corpus/templates/clips/app/hooks/use-library.ts +12 -25
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +20 -22
- package/corpus/templates/clips/changelog/2026-07-11-clips-no-longer-stay-stuck-on-preparing-clip-when-they-are-r.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-11-generated-titles-no-longer-cause-continuous-background-refreshes.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-11-s3-storage-setup-stays-collapsed-until-you-choose-it-as-the-.md +6 -0
- package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +2 -2
- package/corpus/templates/content/app/hooks/use-comments.ts +0 -1
- package/corpus/templates/content/changelog/2026-07-11-comments-now-update-from-live-collaboration-events-without-c.md +6 -0
- package/corpus/templates/content/changelog/2026-07-12-the-left-sidebar-stays-fixed-horizontally-while-scrolling-on.md +6 -0
- package/corpus/templates/design/app/components/layout/Header.tsx +1 -1
- package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +1 -2
- package/corpus/templates/macros/app/root.tsx +0 -3
- package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/templates/mail/app/hooks/use-compose-state.ts +1 -0
- package/corpus/templates/mail/app/root.tsx +1 -12
- package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/corpus/templates/plan/.agents/skills/visual-plan/references/local-files.md +17 -12
- package/corpus/templates/plan/.agents/skills/visual-recap/references/local-files.md +17 -12
- package/corpus/templates/plan/actions/validate-local-plan-source.ts +4 -4
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +2 -1
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +5 -2
- package/corpus/templates/plan/app/hooks/use-plans.ts +6 -13
- package/corpus/templates/plan/app/lib/plan-local-bridge.ts +41 -0
- package/corpus/templates/plan/app/lib/plan-tracking.ts +3 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +14 -36
- package/corpus/templates/plan/app/root.tsx +13 -3
- package/corpus/templates/plan/changelog/2026-07-11-plan-refreshes-only-when-content-changes.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-12-local-plan-source-now-stays-on-device.md +6 -0
- package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +4 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +1 -1
- package/corpus/templates/slides/app/components/layout/Header.tsx +1 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +1 -0
- package/corpus/templates/slides/app/hooks/use-slide-comments.ts +7 -31
- package/corpus/templates/slides/changelog/2026-07-11-comments-now-update-from-live-collaboration-events-without-c.md +6 -0
- package/dist/action-change-marker.d.ts +1 -0
- package/dist/action-change-marker.d.ts.map +1 -1
- package/dist/action-change-marker.js +7 -1
- package/dist/action-change-marker.js.map +1 -1
- package/dist/changelog/parse.d.ts +4 -2
- package/dist/changelog/parse.d.ts.map +1 -1
- package/dist/changelog/parse.js +5 -3
- package/dist/changelog/parse.js.map +1 -1
- package/dist/cli/plan-local.d.ts +6 -6
- package/dist/cli/plan-local.d.ts.map +1 -1
- package/dist/cli/plan-local.js +36 -7
- package/dist/cli/plan-local.js.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts +2 -8
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.js +2 -8
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/cli/recap.d.ts +22 -1
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +286 -2
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills-content/local-files.d.ts +1 -1
- package/dist/cli/skills-content/local-files.d.ts.map +1 -1
- package/dist/cli/skills-content/local-files.js +17 -12
- package/dist/cli/skills-content/local-files.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +2 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +7 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +62 -40
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/analytics.d.ts +8 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +103 -13
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.d.ts +2 -0
- package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.js +9 -2
- package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
- package/dist/client/chat-model-groups.d.ts.map +1 -1
- package/dist/client/chat-model-groups.js +24 -0
- package/dist/client/chat-model-groups.js.map +1 -1
- package/dist/client/composer/RealtimeVoiceMode.d.ts +40 -4
- package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -1
- package/dist/client/composer/RealtimeVoiceMode.js +172 -42
- package/dist/client/composer/RealtimeVoiceMode.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +4 -0
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +47 -29
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts.map +1 -1
- package/dist/client/composer/VoiceButton.js +2 -2
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/composer/index.d.ts +2 -2
- package/dist/client/composer/index.d.ts.map +1 -1
- package/dist/client/composer/index.js +1 -1
- package/dist/client/composer/index.js.map +1 -1
- package/dist/client/composer/useRealtimeVoiceMode.d.ts +100 -3
- package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -1
- package/dist/client/composer/useRealtimeVoiceMode.js +952 -51
- package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -1
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/progress/RunsTray.d.ts.map +1 -1
- package/dist/client/progress/RunsTray.js +10 -1
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/session-replay.d.ts +2 -0
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +7 -0
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/settings/DemoModeSection.d.ts.map +1 -1
- package/dist/client/settings/DemoModeSection.js +4 -23
- package/dist/client/settings/DemoModeSection.js.map +1 -1
- package/dist/client/settings/SecretsSection.d.ts +2 -3
- package/dist/client/settings/SecretsSection.d.ts.map +1 -1
- package/dist/client/settings/SecretsSection.js +46 -22
- package/dist/client/settings/SecretsSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts +9 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +46 -12
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/url-scrub.d.ts.map +1 -1
- package/dist/client/url-scrub.js +14 -0
- package/dist/client/url-scrub.js.map +1 -1
- package/dist/client/use-action.d.ts +2 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +10 -0
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-agent-chat-home-handoff.d.ts +2 -0
- package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -1
- package/dist/client/use-agent-chat-home-handoff.js +7 -1
- package/dist/client/use-agent-chat-home-handoff.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +17 -3
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/client/use-db-sync.d.ts +8 -2
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +57 -32
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-demo-mode-status.d.ts +12 -0
- package/dist/client/use-demo-mode-status.d.ts.map +1 -0
- package/dist/client/use-demo-mode-status.js +30 -0
- package/dist/client/use-demo-mode-status.js.map +1 -0
- package/dist/client/use-pausing-interval.d.ts.map +1 -1
- package/dist/client/use-pausing-interval.js +16 -4
- package/dist/client/use-pausing-interval.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/integrations/scope-store.js +1 -1
- package/dist/integrations/scope-store.js.map +1 -1
- package/dist/integrations/usage-budget-store.js +1 -1
- package/dist/integrations/usage-budget-store.js.map +1 -1
- package/dist/localization/default-messages.d.ts +41 -1
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +41 -1
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp-client/workspace-servers.js +4 -4
- package/dist/mcp-client/workspace-servers.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/secrets/crypto.d.ts +7 -6
- package/dist/secrets/crypto.d.ts.map +1 -1
- package/dist/secrets/crypto.js +30 -11
- package/dist/secrets/crypto.js.map +1 -1
- package/dist/server/action-change.d.ts +1 -0
- package/dist/server/action-change.d.ts.map +1 -1
- package/dist/server/action-change.js +4 -1
- package/dist/server/action-change.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +5 -0
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +1 -0
- package/dist/server/poll.js.map +1 -1
- package/dist/server/realtime-voice.d.ts +7 -0
- package/dist/server/realtime-voice.d.ts.map +1 -1
- package/dist/server/realtime-voice.js +222 -12
- package/dist/server/realtime-voice.js.map +1 -1
- package/dist/styles/agent-native.css +2 -2
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +7 -3
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -9
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +6 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/locales/ar-SA/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/ar-SA/template-plan.mdx +1 -1
- package/docs/content/locales/de-DE/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/de-DE/template-plan.mdx +1 -1
- package/docs/content/locales/es-ES/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/es-ES/template-plan.mdx +1 -1
- package/docs/content/locales/fr-FR/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/fr-FR/template-plan.mdx +1 -1
- package/docs/content/locales/hi-IN/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/hi-IN/template-plan.mdx +1 -1
- package/docs/content/locales/ja-JP/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/ja-JP/template-plan.mdx +1 -1
- package/docs/content/locales/ko-KR/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/ko-KR/template-plan.mdx +1 -1
- package/docs/content/locales/pt-BR/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/pt-BR/template-plan.mdx +1 -1
- package/docs/content/locales/zh-CN/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/zh-CN/template-plan.mdx +1 -1
- package/docs/content/locales/zh-TW/pr-visual-recap.mdx +25 -1
- package/docs/content/locales/zh-TW/template-plan.mdx +1 -1
- package/docs/content/pr-visual-recap.mdx +50 -1
- package/docs/content/template-plan.mdx +1 -1
- package/package.json +2 -2
- package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +2 -2
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +7 -3
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DemoModeSection.d.ts","sourceRoot":"","sources":["../../../src/client/settings/DemoModeSection.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"DemoModeSection.d.ts","sourceRoot":"","sources":["../../../src/client/settings/DemoModeSection.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAYH,wBAAgB,eAAe,gCA2E9B;AAED,wBAAgB,YAAY,gCAE3B"}
|
|
@@ -13,29 +13,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
13
13
|
* accidentally turned off on stage.
|
|
14
14
|
*/
|
|
15
15
|
import { IconEyeOff } from "@tabler/icons-react";
|
|
16
|
-
import { useQuery } from "@tanstack/react-query";
|
|
17
16
|
import { useEffect, useState } from "react";
|
|
18
17
|
import { agentNativePath } from "../api-path.js";
|
|
19
|
-
import {
|
|
20
|
-
const DEMO_STATUS_URL = agentNativePath("/_agent-native/demo/status");
|
|
18
|
+
import { useDemoModeStatus } from "../use-demo-mode-status.js";
|
|
21
19
|
const DEMO_MODE_WRITE_URL = agentNativePath("/_agent-native/application-state/demo-mode");
|
|
22
20
|
export function DemoModeSection() {
|
|
23
21
|
const [enabled, setEnabled] = useState(null);
|
|
24
|
-
const
|
|
25
|
-
const { data } = useQuery({
|
|
26
|
-
queryKey: ["agent-native", "demo-mode", demoModeVersion],
|
|
27
|
-
queryFn: async () => {
|
|
28
|
-
const res = await fetch(DEMO_STATUS_URL, {
|
|
29
|
-
credentials: "same-origin",
|
|
30
|
-
});
|
|
31
|
-
if (!res.ok)
|
|
32
|
-
return null;
|
|
33
|
-
return (await res.json());
|
|
34
|
-
},
|
|
35
|
-
staleTime: Infinity,
|
|
36
|
-
});
|
|
37
|
-
const serverEnabled = data?.enabled;
|
|
38
|
-
const forced = data?.forced === true;
|
|
22
|
+
const { enabled: serverEnabled, forced, isLoading } = useDemoModeStatus();
|
|
39
23
|
// Surface the server value once it arrives (and on subsequent polls), but
|
|
40
24
|
// never clobber an in-flight optimistic toggle with a stale read. When
|
|
41
25
|
// forced by env, always reflect the locked-on state.
|
|
@@ -43,13 +27,10 @@ export function DemoModeSection() {
|
|
|
43
27
|
if (forced) {
|
|
44
28
|
setEnabled(true);
|
|
45
29
|
}
|
|
46
|
-
else if (
|
|
30
|
+
else if (!isLoading) {
|
|
47
31
|
setEnabled((prev) => (prev === null ? serverEnabled : prev));
|
|
48
32
|
}
|
|
49
|
-
|
|
50
|
-
setEnabled((prev) => (prev === null ? false : prev));
|
|
51
|
-
}
|
|
52
|
-
}, [serverEnabled, forced, data]);
|
|
33
|
+
}, [serverEnabled, forced, isLoading]);
|
|
53
34
|
const toggle = async (next) => {
|
|
54
35
|
if (forced)
|
|
55
36
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DemoModeSection.js","sourceRoot":"","sources":["../../../src/client/settings/DemoModeSection.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"DemoModeSection.js","sourceRoot":"","sources":["../../../src/client/settings/DemoModeSection.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <DemoModeSection /> — toggle that replaces contact/free-text names, emails,\n * and numbers with realistic fake data everywhere (UI + what the agent sees)\n * while preserving labels, IDs, and structure so the app keeps working.\n *\n * The toggle is stored in application_state under `demo-mode`\n * (`{ enabled: boolean }`) and written via `PUT\n * /_agent-native/application-state/demo-mode` (optimistic — flip first,\n * write in the background). It READS from `/_agent-native/demo/status`\n * instead, which ORs the per-user toggle with the `DEMO_MODE` env: a hosted\n * demo deployment is forced on and the switch is locked so it can't be\n * accidentally turned off on stage.\n */\n\nimport { IconEyeOff } from \"@tabler/icons-react\";\nimport { useEffect, useState } from \"react\";\n\nimport { agentNativePath } from \"../api-path.js\";\nimport { useDemoModeStatus } from \"../use-demo-mode-status.js\";\n\nconst DEMO_MODE_WRITE_URL = agentNativePath(\n \"/_agent-native/application-state/demo-mode\",\n);\n\nexport function DemoModeSection() {\n const [enabled, setEnabled] = useState<boolean | null>(null);\n const { enabled: serverEnabled, forced, isLoading } = useDemoModeStatus();\n\n // Surface the server value once it arrives (and on subsequent polls), but\n // never clobber an in-flight optimistic toggle with a stale read. When\n // forced by env, always reflect the locked-on state.\n useEffect(() => {\n if (forced) {\n setEnabled(true);\n } else if (!isLoading) {\n setEnabled((prev) => (prev === null ? serverEnabled : prev));\n }\n }, [serverEnabled, forced, isLoading]);\n\n const toggle = async (next: boolean) => {\n if (forced) return;\n const previous = enabled;\n // Optimistic: flip immediately, write in the background.\n setEnabled(next);\n try {\n const res = await fetch(DEMO_MODE_WRITE_URL, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n credentials: \"include\",\n body: JSON.stringify({ enabled: next }),\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n } catch {\n setEnabled(previous);\n }\n };\n\n return (\n <div className=\"flex items-start justify-between gap-3 rounded-md border border-border bg-accent/30 px-2.5 py-2\">\n <div className=\"min-w-0\">\n <div className=\"text-[11px] font-medium text-foreground\">\n Enable demo mode\n </div>\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">\n Replace contact/free-text names, emails, and numbers with realistic\n fake data everywhere — in the UI and what the agent sees. Labels, IDs,\n and structure are preserved so the app keeps working.\n </p>\n {forced && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">\n Enforced by the <code>DEMO_MODE</code> environment variable — can't\n be turned off here.\n </p>\n )}\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={!!enabled}\n aria-label=\"Enable demo mode\"\n disabled={enabled === null || forced}\n onClick={() => toggle(!enabled)}\n // Theme tokens; streaming agent owns layout.\n className={`relative inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-full transition-colors ${\n enabled\n ? \"bg-primary\"\n : \"bg-muted-foreground/30 hover:bg-muted-foreground/50\"\n } ${enabled === null || forced ? \"opacity-60\" : \"\"}`}\n >\n <span\n className={`inline-block h-3 w-3 transform rounded-full bg-background transition-transform ${\n enabled ? \"translate-x-3.5\" : \"translate-x-0.5\"\n }`}\n />\n </button>\n </div>\n );\n}\n\nexport function DemoModeIcon() {\n return <IconEyeOff size={14} />;\n}\n"]}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* <SecretsSection /> — renders the registered secrets from the framework
|
|
3
|
-
* secrets registry.
|
|
4
|
-
*
|
|
5
|
-
* buttons (api-key kind) or a Connect / Disconnect button (oauth kind).
|
|
3
|
+
* secrets registry. Configured keys stay compact; adding or editing one
|
|
4
|
+
* progressively discloses its controls.
|
|
6
5
|
*/
|
|
7
6
|
import React from "react";
|
|
8
7
|
export interface SecretsSectionProps {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecretsSection.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SecretsSection.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"SecretsSection.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SecretsSection.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,OAAO,KAAoD,MAAM,OAAO,CAAC;AA4CzE,MAAM,WAAW,mBAAmB;IAClC,yFAAyF;IACzF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,mBAAmB,qBA8G/D"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* <SecretsSection /> — renders the registered secrets from the framework
|
|
4
|
-
* secrets registry.
|
|
5
|
-
*
|
|
6
|
-
* buttons (api-key kind) or a Connect / Disconnect button (oauth kind).
|
|
4
|
+
* secrets registry. Configured keys stay compact; adding or editing one
|
|
5
|
+
* progressively discloses its controls.
|
|
7
6
|
*/
|
|
8
|
-
import { IconCheck, IconExternalLink, IconLoader2, IconPlugConnected, IconPlus, IconTrash, IconRefresh, } from "@tabler/icons-react";
|
|
7
|
+
import { IconCheck, IconChevronRight, IconExternalLink, IconLoader2, IconPlugConnected, IconPlus, IconTrash, IconRefresh, } from "@tabler/icons-react";
|
|
9
8
|
import React, { useEffect, useMemo, useState, useCallback } from "react";
|
|
10
9
|
import { agentNativePath } from "../api-path.js";
|
|
10
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "../components/ui/dropdown-menu.js";
|
|
11
11
|
import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
12
12
|
const ENDPOINT = agentNativePath("/_agent-native/secrets");
|
|
13
13
|
function notifySecretsChanged() {
|
|
@@ -21,6 +21,8 @@ export function SecretsSection({ focusKey }) {
|
|
|
21
21
|
const [secrets, setSecrets] = useState(null);
|
|
22
22
|
const [error, setError] = useState(null);
|
|
23
23
|
const [reloadToken, setReloadToken] = useState(0);
|
|
24
|
+
const [openSecretKey, setOpenSecretKey] = useState(focusKey ?? null);
|
|
25
|
+
const [customKeyOpen, setCustomKeyOpen] = useState(false);
|
|
24
26
|
useEffect(() => {
|
|
25
27
|
let cancelled = false;
|
|
26
28
|
fetch(ENDPOINT)
|
|
@@ -43,6 +45,12 @@ export function SecretsSection({ focusKey }) {
|
|
|
43
45
|
};
|
|
44
46
|
}, [reloadToken]);
|
|
45
47
|
const reload = useCallback(() => setReloadToken((t) => t + 1), []);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (focusKey) {
|
|
50
|
+
setCustomKeyOpen(false);
|
|
51
|
+
setOpenSecretKey(focusKey);
|
|
52
|
+
}
|
|
53
|
+
}, [focusKey]);
|
|
46
54
|
if (error) {
|
|
47
55
|
return (_jsxs("p", { className: "text-[10px] text-red-500", children: ["Failed to load secrets: ", error] }));
|
|
48
56
|
}
|
|
@@ -50,21 +58,36 @@ export function SecretsSection({ focusKey }) {
|
|
|
50
58
|
return (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [_jsx(IconLoader2, { size: 10, className: "animate-spin" }), "Loading\u2026"] }));
|
|
51
59
|
}
|
|
52
60
|
if (secrets.length === 0) {
|
|
53
|
-
return (_jsxs("div", { className: "space-y-
|
|
61
|
+
return (_jsxs("div", { className: "space-y-3", children: [_jsx(KeysHeader, { onCustomKey: () => setCustomKeyOpen(true) }), _jsx(AdHocKeysSection, { showForm: customKeyOpen, onShowFormChange: setCustomKeyOpen, showEmptyState: true })] }));
|
|
54
62
|
}
|
|
55
|
-
|
|
63
|
+
const visibleSecrets = secrets.filter((secret) => secret.status !== "unset" || secret.key === openSecretKey);
|
|
64
|
+
const availableSecrets = secrets.filter((secret) => secret.status === "unset" && secret.key !== openSecretKey);
|
|
65
|
+
return (_jsxs("div", { className: "space-y-3", children: [_jsx(KeysHeader, { availableSecrets: availableSecrets, onSecret: (key) => {
|
|
66
|
+
setCustomKeyOpen(false);
|
|
67
|
+
setOpenSecretKey(key);
|
|
68
|
+
}, onCustomKey: () => {
|
|
69
|
+
setOpenSecretKey(null);
|
|
70
|
+
setCustomKeyOpen(true);
|
|
71
|
+
} }), visibleSecrets.length > 0 && (_jsx("div", { className: "overflow-hidden rounded-md border border-border", children: visibleSecrets.map((secret) => (_jsx(SecretCard, { secret: secret, onChanged: reload, open: openSecretKey === secret.key, onOpenChange: (open) => {
|
|
72
|
+
if (open)
|
|
73
|
+
setCustomKeyOpen(false);
|
|
74
|
+
setOpenSecretKey(open ? secret.key : null);
|
|
75
|
+
}, focusInput: openSecretKey === secret.key }, secret.key))) })), _jsx(AdHocKeysSection, { showForm: customKeyOpen, onShowFormChange: setCustomKeyOpen, showEmptyState: visibleSecrets.length === 0 })] }));
|
|
76
|
+
}
|
|
77
|
+
function KeysHeader({ availableSecrets = [], onSecret, onCustomKey, }) {
|
|
78
|
+
return (_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-[11px] font-medium text-foreground", children: "Keys" }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-accent/40 hover:text-foreground", children: [_jsx(IconPlus, { size: 11 }), "New"] }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-60", children: [availableSecrets.length > 0 && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuLabel, { children: "Choose a key" }), availableSecrets.map((secret) => (_jsxs(DropdownMenuItem, { onSelect: () => onSecret?.(secret.key), className: "flex items-center justify-between gap-3", children: [_jsx("span", { className: "truncate", children: secret.label }), secret.required && (_jsx("span", { className: "text-[9px] font-semibold uppercase tracking-wide text-amber-600 dark:text-amber-400", children: "Required" }))] }, secret.key))), _jsx(DropdownMenuSeparator, {})] })), _jsxs(DropdownMenuItem, { onSelect: onCustomKey, children: [_jsx(IconPlus, { size: 14 }), "Custom"] })] })] })] }));
|
|
56
79
|
}
|
|
57
|
-
function SecretCard({ secret, onChanged, focusInput }) {
|
|
80
|
+
function SecretCard({ secret, onChanged, open, onOpenChange, focusInput, }) {
|
|
58
81
|
const [value, setValue] = useState("");
|
|
59
82
|
const [busy, setBusy] = useState(null);
|
|
60
83
|
const [confirmDelete, setConfirmDelete] = useState(false);
|
|
61
84
|
const [toast, setToast] = useState(null);
|
|
62
85
|
const inputRef = React.useRef(null);
|
|
63
86
|
useEffect(() => {
|
|
64
|
-
if (focusInput && inputRef.current) {
|
|
87
|
+
if (open && focusInput && inputRef.current) {
|
|
65
88
|
inputRef.current.focus();
|
|
66
89
|
}
|
|
67
|
-
}, [focusInput]);
|
|
90
|
+
}, [focusInput, open]);
|
|
68
91
|
const setToastAndClear = (kind, text, ms = 2500) => {
|
|
69
92
|
setToast({ kind, text });
|
|
70
93
|
setTimeout(() => setToast(null), ms);
|
|
@@ -153,19 +176,18 @@ function SecretCard({ secret, onChanged, focusInput }) {
|
|
|
153
176
|
return (_jsx("span", { className: "rounded-full bg-accent/60 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Optional" }));
|
|
154
177
|
}, [secret.status, secret.required]);
|
|
155
178
|
const isOAuth = secret.kind === "oauth";
|
|
156
|
-
return (_jsxs("div", { className: "
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
179
|
+
return (_jsxs("div", { className: "border-b border-border last:border-b-0", children: [_jsxs("button", { type: "button", "aria-expanded": open, onClick: () => onOpenChange(!open), className: "flex w-full items-center gap-2 px-2.5 py-2 text-start transition-colors hover:bg-accent/30", children: [_jsx(IconChevronRight, { size: 13, className: `shrink-0 text-muted-foreground transition-transform ${open ? "rotate-90" : ""}` }), _jsx("span", { className: "min-w-0 flex-1 truncate text-[11px] font-medium text-foreground", children: secret.label }), secret.status === "set" && secret.last4 && (_jsxs("code", { className: "text-[10px] text-muted-foreground", children: ["\u2022\u2022\u2022\u2022", secret.last4] })), _jsx("span", { className: "shrink-0", children: pill })] }), open && (_jsxs("div", { className: "border-t border-border/60 bg-accent/20 px-3 pb-3 pt-2.5", children: [secret.description && (_jsx("p", { className: "mb-2 text-[10px] leading-relaxed text-muted-foreground", children: secret.description })), isOAuth ? (_jsxs("div", { className: "mt-2 flex items-center gap-1.5", children: [secret.oauthConnectUrl && (_jsxs("a", { href: secret.oauthConnectUrl, className: "inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium no-underline", style: { backgroundColor: "#00B5FF", color: "white" }, children: [_jsx(IconPlugConnected, { size: 10 }), secret.status === "set" ? "Reconnect" : "Connect"] })), secret.docsUrl && (_jsxs("a", { href: secret.docsUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground", children: ["Docs", _jsx(IconExternalLink, { size: 10 })] }))] })) : (_jsxs("div", { className: "mt-2 space-y-1.5", children: [secret.status === "set" && (_jsxs("div", { className: "flex items-center gap-2 text-[10px] text-muted-foreground", children: [_jsx("span", { children: "Stored value ending in" }), _jsx("code", { className: "rounded bg-background px-1 py-0.5 text-foreground", children: secret.last4 })] })), _jsxs("div", { className: "flex gap-1.5", children: [_jsx("input", { ref: inputRef, type: "password", "aria-label": secret.label, value: value, onChange: (e) => setValue(e.target.value), onKeyDown: (e) => {
|
|
180
|
+
if (e.key === "Enter")
|
|
181
|
+
handleSave();
|
|
182
|
+
}, placeholder: secret.status === "set"
|
|
183
|
+
? "Enter new value to rotate"
|
|
184
|
+
: "Paste key", className: "flex-1 rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent" }), _jsx("button", { type: "button", onClick: handleSave, disabled: !value.trim() || busy !== null, className: "inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40", style: { backgroundColor: "#00B5FF", color: "white" }, children: busy === "save" ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : secret.status === "set" ? (_jsxs(_Fragment, { children: [_jsx(IconRefresh, { size: 10 }), "Rotate"] })) : ("Save") })] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [secret.status === "set" && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: handleTest, disabled: busy !== null, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-foreground disabled:opacity-40", children: busy === "test" ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : ("Test") }), _jsxs("button", { type: "button", onClick: () => setConfirmDelete(true), disabled: busy !== null, className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-red-500 disabled:opacity-40", children: [_jsx(IconTrash, { size: 10 }), "Remove"] })] })), secret.docsUrl && (_jsxs("a", { href: secret.docsUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground ms-auto", children: ["Get key", _jsx(IconExternalLink, { size: 10 })] }))] }), confirmDelete && (_jsxs("div", { className: "flex items-center gap-1.5 rounded border border-red-500/30 bg-red-500/10 px-2 py-1.5 text-[10px] text-red-500", children: [_jsx("span", { className: "min-w-0 flex-1", children: "Remove this saved value?" }), _jsx("button", { type: "button", onClick: handleDelete, disabled: busy !== null, className: "inline-flex items-center gap-1 rounded border border-red-500/40 px-1.5 py-0.5 font-medium disabled:opacity-40", children: busy === "delete" ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : ("Confirm") }), _jsx("button", { type: "button", onClick: () => setConfirmDelete(false), disabled: busy !== null, className: "rounded border border-border px-1.5 py-0.5 text-muted-foreground hover:text-foreground disabled:opacity-40", children: "Cancel" })] }))] })), toast && (_jsx("p", { className: `mt-1.5 text-[10px] ${toast.kind === "ok" ? "text-green-500" : "text-red-500"}`, children: toast.text }))] }))] }));
|
|
162
185
|
}
|
|
163
186
|
const ADHOC_ENDPOINT = agentNativePath("/_agent-native/secrets/adhoc");
|
|
164
|
-
function AdHocKeysSection() {
|
|
187
|
+
function AdHocKeysSection({ showForm, onShowFormChange, showEmptyState, }) {
|
|
165
188
|
const [keys, setKeys] = useState([]);
|
|
166
189
|
const [loading, setLoading] = useState(true);
|
|
167
190
|
const [reloadToken, setReloadToken] = useState(0);
|
|
168
|
-
const [showForm, setShowForm] = useState(false);
|
|
169
191
|
const [formName, setFormName] = useState("");
|
|
170
192
|
const [formValue, setFormValue] = useState("");
|
|
171
193
|
const [formDescription, setFormDescription] = useState("");
|
|
@@ -206,13 +228,13 @@ function AdHocKeysSection() {
|
|
|
206
228
|
};
|
|
207
229
|
}, [reloadToken]);
|
|
208
230
|
const resetForm = useCallback(() => {
|
|
209
|
-
|
|
231
|
+
onShowFormChange(false);
|
|
210
232
|
setFormName("");
|
|
211
233
|
setFormValue("");
|
|
212
234
|
setFormDescription("");
|
|
213
235
|
setFormScope("user");
|
|
214
236
|
setFormError(null);
|
|
215
|
-
}, []);
|
|
237
|
+
}, [onShowFormChange]);
|
|
216
238
|
const handleAdd = useCallback(async () => {
|
|
217
239
|
const name = formName.trim();
|
|
218
240
|
const value = formValue.trim();
|
|
@@ -241,6 +263,7 @@ function AdHocKeysSection() {
|
|
|
241
263
|
}
|
|
242
264
|
resetForm();
|
|
243
265
|
showToast("ok", "Key saved");
|
|
266
|
+
notifySecretsChanged();
|
|
244
267
|
reload();
|
|
245
268
|
}
|
|
246
269
|
catch (err) {
|
|
@@ -272,14 +295,15 @@ function AdHocKeysSection() {
|
|
|
272
295
|
}
|
|
273
296
|
showToast("ok", "Key deleted");
|
|
274
297
|
setConfirmDeleteName(null);
|
|
298
|
+
notifySecretsChanged();
|
|
275
299
|
reload();
|
|
276
300
|
}
|
|
277
301
|
finally {
|
|
278
302
|
setDeletingName(null);
|
|
279
303
|
}
|
|
280
304
|
}, [showToast, reload]);
|
|
281
|
-
return (_jsxs("div", { className: "
|
|
282
|
-
|
|
283
|
-
|
|
305
|
+
return (_jsxs("div", { className: "space-y-2", children: [showForm && (_jsxs("div", { className: "rounded-md border border-border px-2.5 py-2 bg-accent/30 space-y-1.5", children: [_jsx("input", { value: formName, onChange: (e) => setFormName(e.target.value.toUpperCase().replace(/[^A-Z0-9_-]/g, "")), className: "w-full rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent", "aria-label": "Key name", placeholder: "KEY_NAME" }), _jsx("input", { type: "password", "aria-label": "Secret value", value: formValue, onChange: (e) => setFormValue(e.target.value), className: "w-full rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent", placeholder: "Secret value" }), _jsx("input", { value: formDescription, "aria-label": "Description", onChange: (e) => setFormDescription(e.target.value), className: "w-full rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent", placeholder: "Description (optional)" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("select", { "aria-label": "Scope", value: formScope, onChange: (e) => setFormScope(e.target.value), className: "rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none focus:ring-1 focus:ring-accent", children: [_jsx("option", { value: "user", children: "Personal" }), _jsx("option", { value: "workspace", children: "Workspace" })] }), _jsxs("div", { className: "ms-auto flex items-center gap-1.5", children: [_jsx("button", { type: "button", onClick: resetForm, className: "rounded border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground hover:text-foreground", children: "Cancel" }), _jsx("button", { type: "button", onClick: handleAdd, disabled: !formName.trim() || !formValue.trim() || formBusy, className: "inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40", style: { backgroundColor: "#00B5FF", color: "white" }, children: formBusy ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : ("Save") })] })] }), formError && _jsx("p", { className: "text-[10px] text-red-500", children: formError })] })), loading ? (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [_jsx(IconLoader2, { size: 10, className: "animate-spin" }), "Loading..."] })) : keys.length === 0 && !showForm && showEmptyState ? (_jsx("p", { className: "text-[10px] text-muted-foreground", children: "No keys added yet." })) : keys.length > 0 ? (_jsx("div", { className: "overflow-hidden rounded-md border border-border", children: keys.map((key) => (_jsx("div", { className: "border-b border-border px-2.5 py-2 last:border-b-0", children: _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-[11px] font-medium text-foreground font-mono truncate", children: key.name }), _jsx("span", { className: `rounded-full px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${key.scope === "workspace"
|
|
306
|
+
? "bg-blue-500/15 text-blue-500"
|
|
307
|
+
: "bg-accent/60 text-muted-foreground"}`, children: key.scope === "workspace" ? "workspace" : "personal" })] }), key.description && (_jsx("p", { className: "text-[10px] text-muted-foreground mt-0.5", children: key.description })), _jsx("div", { className: "flex items-center gap-2 text-[10px] text-muted-foreground mt-0.5", children: _jsxs("span", { children: ["Ending in", " ", _jsx("code", { className: "rounded bg-background px-1 py-0.5 text-foreground", children: key.last4 })] }) })] }), _jsx("div", { className: "shrink-0", children: confirmDeleteName === key.name ? (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { type: "button", onClick: () => handleDelete(key.name), disabled: deletingName === key.name, className: "rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-red-500/15 text-red-500 hover:bg-red-500/25 disabled:opacity-40", children: deletingName === key.name ? (_jsx(IconLoader2, { size: 10, className: "animate-spin" })) : ("Confirm") }), _jsx("button", { type: "button", onClick: () => setConfirmDeleteName(null), className: "rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-accent/60 text-muted-foreground hover:text-foreground", children: "Cancel" })] })) : (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => setConfirmDeleteName(key.name), className: "text-muted-foreground hover:text-red-500", children: _jsx(IconTrash, { size: 12 }) }) }), _jsx(TooltipContent, { children: "Delete" })] })) })] }) }, `${key.scope}-${key.name}`))) })) : null, toast && (_jsx("p", { className: `text-[10px] ${toast.kind === "ok" ? "text-green-500" : "text-red-500"}`, children: toast.text }))] }));
|
|
284
308
|
}
|
|
285
309
|
//# sourceMappingURL=SecretsSection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecretsSection.js","sourceRoot":"","sources":["../../../src/client/settings/SecretsSection.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <SecretsSection /> — renders the registered secrets from the framework\n * secrets registry. Fetches `/_agent-native/secrets` on mount and shows a\n * card per secret with a masked input + Save / Rotate / Delete / Test\n * buttons (api-key kind) or a Connect / Disconnect button (oauth kind).\n */\n\nimport {\n IconCheck,\n IconExternalLink,\n IconLoader2,\n IconPlugConnected,\n IconPlus,\n IconTrash,\n IconRefresh,\n} from \"@tabler/icons-react\";\nimport React, { useEffect, useMemo, useState, useCallback } from \"react\";\n\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\n\ninterface SecretStatus {\n key: string;\n label: string;\n description?: string;\n docsUrl?: string;\n scope: \"user\" | \"workspace\";\n kind: \"api-key\" | \"oauth\";\n required: boolean;\n status: \"set\" | \"unset\" | \"invalid\";\n last4?: string;\n updatedAt?: number;\n oauthProvider?: string;\n oauthConnectUrl?: string;\n error?: string;\n}\n\nconst ENDPOINT = agentNativePath(\"/_agent-native/secrets\");\n\nfunction notifySecretsChanged() {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agent-engine:configured-changed\", {\n detail: { source: \"secrets\" },\n }),\n );\n}\n\nexport interface SecretsSectionProps {\n /** Optional hash fragment to focus a specific secret (e.g. \"secrets:OPENAI_API_KEY\"). */\n focusKey?: string;\n}\n\nexport function SecretsSection({ focusKey }: SecretsSectionProps) {\n const [secrets, setSecrets] = useState<SecretStatus[] | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [reloadToken, setReloadToken] = useState(0);\n\n useEffect(() => {\n let cancelled = false;\n fetch(ENDPOINT)\n .then(async (r) => {\n if (!r.ok) {\n throw new Error(`Failed to load secrets (${r.status})`);\n }\n return (await r.json()) as SecretStatus[];\n })\n .then((data) => {\n if (!cancelled) setSecrets(data);\n })\n .catch((err) => {\n if (!cancelled) setError(err?.message ?? \"Failed to load\");\n });\n return () => {\n cancelled = true;\n };\n }, [reloadToken]);\n\n const reload = useCallback(() => setReloadToken((t) => t + 1), []);\n\n if (error) {\n return (\n <p className=\"text-[10px] text-red-500\">\n Failed to load secrets: {error}\n </p>\n );\n }\n if (secrets === null) {\n return (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading…\n </div>\n );\n }\n if (secrets.length === 0) {\n return (\n <div className=\"space-y-2\">\n <p className=\"text-[10px] text-muted-foreground\">\n No secrets registered yet. Templates register API keys and connections\n via <code>registerRequiredSecret()</code>.\n </p>\n <AdHocKeysSection />\n </div>\n );\n }\n\n return (\n <div className=\"space-y-2\">\n {secrets.map((secret) => (\n <SecretCard\n key={secret.key}\n secret={secret}\n onChanged={reload}\n focusInput={focusKey === secret.key}\n />\n ))}\n <AdHocKeysSection />\n </div>\n );\n}\n\ninterface SecretCardProps {\n secret: SecretStatus;\n onChanged: () => void;\n focusInput?: boolean;\n}\n\nfunction SecretCard({ secret, onChanged, focusInput }: SecretCardProps) {\n const [value, setValue] = useState(\"\");\n const [busy, setBusy] = useState<null | \"save\" | \"delete\" | \"test\">(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (focusInput && inputRef.current) {\n inputRef.current.focus();\n }\n }, [focusInput]);\n\n const setToastAndClear = (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n setTimeout(() => setToast(null), ms);\n };\n\n const handleSave = async () => {\n if (!value.trim() || busy) return;\n setBusy(\"save\");\n try {\n const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ value: value.trim() }),\n });\n if (!res.ok) {\n const err = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setToastAndClear(\"err\", err ?? `Save failed (${res.status})`);\n return;\n }\n setValue(\"\");\n setConfirmDelete(false);\n setToastAndClear(\"ok\", \"Saved\");\n notifySecretsChanged();\n onChanged();\n } finally {\n setBusy(null);\n }\n };\n\n const handleDelete = async () => {\n if (busy) return;\n setBusy(\"delete\");\n try {\n const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n if (!res.ok) {\n const err = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setToastAndClear(\"err\", err ?? `Delete failed (${res.status})`);\n return;\n }\n setToastAndClear(\"ok\", \"Removed\");\n setConfirmDelete(false);\n notifySecretsChanged();\n onChanged();\n } finally {\n setBusy(null);\n }\n };\n\n const handleTest = async () => {\n if (busy) return;\n setBusy(\"test\");\n try {\n const res = await fetch(\n `${ENDPOINT}/${encodeURIComponent(secret.key)}/test`,\n {\n method: \"POST\",\n },\n );\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n };\n if (res.ok && body.ok) {\n setToastAndClear(\"ok\", \"Working\");\n } else {\n setToastAndClear(\n \"err\",\n body.error ?? (body.ok === false ? \"Invalid\" : `Test failed`),\n );\n }\n } finally {\n setBusy(null);\n }\n };\n\n const pill = useMemo(() => {\n if (secret.status === \"set\") {\n return (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Set\n </span>\n );\n }\n if (secret.required) {\n return (\n <span className=\"rounded-full bg-red-500/15 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-red-500\">\n Required\n </span>\n );\n }\n return (\n <span className=\"rounded-full bg-accent/60 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-muted-foreground\">\n Optional\n </span>\n );\n }, [secret.status, secret.required]);\n\n const isOAuth = secret.kind === \"oauth\";\n\n return (\n <div className=\"rounded-md border border-border px-2.5 py-2 bg-accent/30\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"text-[11px] font-medium text-foreground truncate\">\n {secret.label}\n </div>\n {secret.description && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">\n {secret.description}\n </p>\n )}\n </div>\n <div className=\"shrink-0\">{pill}</div>\n </div>\n\n {isOAuth ? (\n <div className=\"mt-2 flex items-center gap-1.5\">\n {secret.oauthConnectUrl && (\n <a\n href={secret.oauthConnectUrl}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium no-underline\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n <IconPlugConnected size={10} />\n {secret.status === \"set\" ? \"Reconnect\" : \"Connect\"}\n </a>\n )}\n {secret.docsUrl && (\n <a\n href={secret.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground\"\n >\n Docs\n <IconExternalLink size={10} />\n </a>\n )}\n </div>\n ) : (\n <div className=\"mt-2 space-y-1.5\">\n {secret.status === \"set\" && (\n <div className=\"flex items-center gap-2 text-[10px] text-muted-foreground\">\n <span>Stored value ending in</span>\n <code className=\"rounded bg-background px-1 py-0.5 text-foreground\">\n {secret.last4}\n </code>\n </div>\n )}\n <div className=\"flex gap-1.5\">\n <input\n ref={inputRef}\n type=\"password\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleSave();\n }}\n placeholder={\n secret.status === \"set\"\n ? \"Enter new value to rotate\"\n : \"Paste key\"\n }\n className=\"flex-1 rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n />\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={!value.trim() || busy !== null}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n {busy === \"save\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : secret.status === \"set\" ? (\n <>\n <IconRefresh size={10} />\n Rotate\n </>\n ) : (\n \"Save\"\n )}\n </button>\n </div>\n <div className=\"flex items-center gap-1.5\">\n {secret.status === \"set\" && (\n <>\n <button\n type=\"button\"\n onClick={handleTest}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n {busy === \"test\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Test\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmDelete(true)}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-red-500 disabled:opacity-40\"\n >\n <IconTrash size={10} />\n Remove\n </button>\n </>\n )}\n {secret.docsUrl && (\n <a\n href={secret.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground ms-auto\"\n >\n Get key\n <IconExternalLink size={10} />\n </a>\n )}\n </div>\n {confirmDelete && (\n <div className=\"flex items-center gap-1.5 rounded border border-red-500/30 bg-red-500/10 px-2 py-1.5 text-[10px] text-red-500\">\n <span className=\"min-w-0 flex-1\">Remove this saved value?</span>\n <button\n type=\"button\"\n onClick={handleDelete}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-red-500/40 px-1.5 py-0.5 font-medium disabled:opacity-40\"\n >\n {busy === \"delete\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Confirm\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmDelete(false)}\n disabled={busy !== null}\n className=\"rounded border border-border px-1.5 py-0.5 text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n Cancel\n </button>\n </div>\n )}\n </div>\n )}\n\n {toast && (\n <p\n className={`mt-1.5 text-[10px] ${\n toast.kind === \"ok\" ? \"text-green-500\" : \"text-red-500\"\n }`}\n >\n {toast.text}\n </p>\n )}\n </div>\n );\n}\n\n// ─── Ad-hoc Keys Section ──────────────────────────────────────────────────\n\ninterface AdHocKey {\n name: string;\n scope: \"user\" | \"workspace\";\n scopeId: string;\n description: string | null;\n last4: string;\n createdAt: number;\n updatedAt: number;\n}\n\nconst ADHOC_ENDPOINT = agentNativePath(\"/_agent-native/secrets/adhoc\");\n\nfunction AdHocKeysSection() {\n const [keys, setKeys] = useState<AdHocKey[]>([]);\n const [loading, setLoading] = useState(true);\n const [reloadToken, setReloadToken] = useState(0);\n const [showForm, setShowForm] = useState(false);\n const [formName, setFormName] = useState(\"\");\n const [formValue, setFormValue] = useState(\"\");\n const [formDescription, setFormDescription] = useState(\"\");\n const [formScope, setFormScope] = useState<\"user\" | \"workspace\">(\"user\");\n const [formBusy, setFormBusy] = useState(false);\n const [formError, setFormError] = useState<string | null>(null);\n const [confirmDeleteName, setConfirmDeleteName] = useState<string | null>(\n null,\n );\n const [deletingName, setDeletingName] = useState<string | null>(null);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n\n const showToast = useCallback(\n (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n setTimeout(() => setToast(null), ms);\n },\n [],\n );\n\n const reload = useCallback(() => setReloadToken((t) => t + 1), []);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n fetch(ADHOC_ENDPOINT)\n .then(async (r) => {\n if (!r.ok) throw new Error(`Failed to load (${r.status})`);\n return (await r.json()) as AdHocKey[];\n })\n .then((data) => {\n if (!cancelled) {\n setKeys(data);\n setLoading(false);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setKeys([]);\n setLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [reloadToken]);\n\n const resetForm = useCallback(() => {\n setShowForm(false);\n setFormName(\"\");\n setFormValue(\"\");\n setFormDescription(\"\");\n setFormScope(\"user\");\n setFormError(null);\n }, []);\n\n const handleAdd = useCallback(async () => {\n const name = formName.trim();\n const value = formValue.trim();\n if (!name || !value || formBusy) return;\n setFormBusy(true);\n setFormError(null);\n try {\n const res = await fetch(ADHOC_ENDPOINT, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n name,\n value,\n description: formDescription.trim() || undefined,\n scope: formScope,\n }),\n });\n if (!res.ok) {\n const body = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setFormError(body ?? `Save failed (${res.status})`);\n return;\n }\n resetForm();\n showToast(\"ok\", \"Key saved\");\n reload();\n } catch (err: any) {\n setFormError(err?.message ?? \"Failed to save\");\n } finally {\n setFormBusy(false);\n }\n }, [\n formName,\n formValue,\n formDescription,\n formScope,\n formBusy,\n resetForm,\n showToast,\n reload,\n ]);\n\n const handleDelete = useCallback(\n async (name: string) => {\n setDeletingName(name);\n try {\n const res = await fetch(\n `${ADHOC_ENDPOINT}/${encodeURIComponent(name)}`,\n {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n if (!res.ok) {\n showToast(\"err\", \"Failed to delete key\");\n return;\n }\n showToast(\"ok\", \"Key deleted\");\n setConfirmDeleteName(null);\n reload();\n } finally {\n setDeletingName(null);\n }\n },\n [showToast, reload],\n );\n\n return (\n <div className=\"mt-3 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-[11px] font-medium text-foreground\">\n Additional Keys\n </p>\n {!showForm && (\n <button\n type=\"button\"\n onClick={() => setShowForm(true)}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] font-medium text-muted-foreground hover:text-foreground hover:bg-accent/40\"\n >\n <IconPlus size={10} />\n Add Key\n </button>\n )}\n </div>\n <p className=\"text-[10px] text-muted-foreground/60 leading-relaxed\">\n Keys are referenced in automations as{\" \"}\n <code className=\"rounded bg-background px-1 py-0.5 text-[9px]\">\n {\"${keys.KEY_NAME}\"}\n </code>\n . Values are encrypted and never shown to the AI agent.\n </p>\n\n {showForm && (\n <div className=\"rounded-md border border-border px-2.5 py-2 bg-accent/30 space-y-1.5\">\n <input\n value={formName}\n onChange={(e) =>\n setFormName(\n e.target.value.toUpperCase().replace(/[^A-Z0-9_-]/g, \"\"),\n )\n }\n className=\"w-full rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"KEY_NAME (e.g. SLACK_WEBHOOK)\"\n />\n <input\n type=\"password\"\n value={formValue}\n onChange={(e) => setFormValue(e.target.value)}\n className=\"w-full rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"Secret value\"\n />\n <input\n value={formDescription}\n onChange={(e) => setFormDescription(e.target.value)}\n className=\"w-full rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"Description (optional)\"\n />\n <div className=\"flex items-center gap-2\">\n <select\n value={formScope}\n onChange={(e) =>\n setFormScope(e.target.value as \"user\" | \"workspace\")\n }\n className=\"rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none focus:ring-1 focus:ring-accent\"\n >\n <option value=\"user\">Personal</option>\n <option value=\"workspace\">Workspace</option>\n </select>\n <div className=\"ms-auto flex items-center gap-1.5\">\n <button\n type=\"button\"\n onClick={resetForm}\n className=\"rounded border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleAdd}\n disabled={!formName.trim() || !formValue.trim() || formBusy}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n {formBusy ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Save\"\n )}\n </button>\n </div>\n </div>\n {formError && <p className=\"text-[10px] text-red-500\">{formError}</p>}\n </div>\n )}\n\n {loading ? (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading...\n </div>\n ) : keys.length === 0 && !showForm ? (\n <p className=\"text-[10px] text-muted-foreground\">\n No additional keys yet.\n </p>\n ) : (\n keys.map((key) => (\n <div\n key={`${key.scope}-${key.name}`}\n className=\"rounded-md border border-border px-2.5 py-2 bg-accent/30\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-[11px] font-medium text-foreground font-mono truncate\">\n {key.name}\n </span>\n <span\n className={`rounded-full px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${\n key.scope === \"workspace\"\n ? \"bg-blue-500/15 text-blue-500\"\n : \"bg-accent/60 text-muted-foreground\"\n }`}\n >\n {key.scope === \"workspace\" ? \"workspace\" : \"personal\"}\n </span>\n </div>\n {key.description && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">\n {key.description}\n </p>\n )}\n <div className=\"flex items-center gap-2 text-[10px] text-muted-foreground mt-0.5\">\n <span>\n Ending in{\" \"}\n <code className=\"rounded bg-background px-1 py-0.5 text-foreground\">\n {key.last4}\n </code>\n </span>\n </div>\n </div>\n <div className=\"shrink-0\">\n {confirmDeleteName === key.name ? (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => handleDelete(key.name)}\n disabled={deletingName === key.name}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-red-500/15 text-red-500 hover:bg-red-500/25 disabled:opacity-40\"\n >\n {deletingName === key.name ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Confirm\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmDeleteName(null)}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-accent/60 text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setConfirmDeleteName(key.name)}\n className=\"text-muted-foreground hover:text-red-500\"\n >\n <IconTrash size={12} />\n </button>\n </TooltipTrigger>\n <TooltipContent>Delete</TooltipContent>\n </Tooltip>\n )}\n </div>\n </div>\n </div>\n ))\n )}\n\n {toast && (\n <p\n className={`text-[10px] ${toast.kind === \"ok\" ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {toast.text}\n </p>\n )}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SecretsSection.js","sourceRoot":"","sources":["../../../src/client/settings/SecretsSection.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <SecretsSection /> — renders the registered secrets from the framework\n * secrets registry. Configured keys stay compact; adding or editing one\n * progressively discloses its controls.\n */\n\nimport {\n IconCheck,\n IconChevronRight,\n IconExternalLink,\n IconLoader2,\n IconPlugConnected,\n IconPlus,\n IconTrash,\n IconRefresh,\n} from \"@tabler/icons-react\";\nimport React, { useEffect, useMemo, useState, useCallback } from \"react\";\n\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../components/ui/dropdown-menu.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\n\ninterface SecretStatus {\n key: string;\n label: string;\n description?: string;\n docsUrl?: string;\n scope: \"user\" | \"workspace\";\n kind: \"api-key\" | \"oauth\";\n required: boolean;\n status: \"set\" | \"unset\" | \"invalid\";\n last4?: string;\n updatedAt?: number;\n oauthProvider?: string;\n oauthConnectUrl?: string;\n error?: string;\n}\n\nconst ENDPOINT = agentNativePath(\"/_agent-native/secrets\");\n\nfunction notifySecretsChanged() {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agent-engine:configured-changed\", {\n detail: { source: \"secrets\" },\n }),\n );\n}\n\nexport interface SecretsSectionProps {\n /** Optional hash fragment to focus a specific secret (e.g. \"secrets:OPENAI_API_KEY\"). */\n focusKey?: string;\n}\n\nexport function SecretsSection({ focusKey }: SecretsSectionProps) {\n const [secrets, setSecrets] = useState<SecretStatus[] | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [reloadToken, setReloadToken] = useState(0);\n const [openSecretKey, setOpenSecretKey] = useState<string | null>(\n focusKey ?? null,\n );\n const [customKeyOpen, setCustomKeyOpen] = useState(false);\n\n useEffect(() => {\n let cancelled = false;\n fetch(ENDPOINT)\n .then(async (r) => {\n if (!r.ok) {\n throw new Error(`Failed to load secrets (${r.status})`);\n }\n return (await r.json()) as SecretStatus[];\n })\n .then((data) => {\n if (!cancelled) setSecrets(data);\n })\n .catch((err) => {\n if (!cancelled) setError(err?.message ?? \"Failed to load\");\n });\n return () => {\n cancelled = true;\n };\n }, [reloadToken]);\n\n const reload = useCallback(() => setReloadToken((t) => t + 1), []);\n\n useEffect(() => {\n if (focusKey) {\n setCustomKeyOpen(false);\n setOpenSecretKey(focusKey);\n }\n }, [focusKey]);\n\n if (error) {\n return (\n <p className=\"text-[10px] text-red-500\">\n Failed to load secrets: {error}\n </p>\n );\n }\n if (secrets === null) {\n return (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading…\n </div>\n );\n }\n if (secrets.length === 0) {\n return (\n <div className=\"space-y-3\">\n <KeysHeader onCustomKey={() => setCustomKeyOpen(true)} />\n <AdHocKeysSection\n showForm={customKeyOpen}\n onShowFormChange={setCustomKeyOpen}\n showEmptyState\n />\n </div>\n );\n }\n\n const visibleSecrets = secrets.filter(\n (secret) => secret.status !== \"unset\" || secret.key === openSecretKey,\n );\n const availableSecrets = secrets.filter(\n (secret) => secret.status === \"unset\" && secret.key !== openSecretKey,\n );\n\n return (\n <div className=\"space-y-3\">\n <KeysHeader\n availableSecrets={availableSecrets}\n onSecret={(key) => {\n setCustomKeyOpen(false);\n setOpenSecretKey(key);\n }}\n onCustomKey={() => {\n setOpenSecretKey(null);\n setCustomKeyOpen(true);\n }}\n />\n {visibleSecrets.length > 0 && (\n <div className=\"overflow-hidden rounded-md border border-border\">\n {visibleSecrets.map((secret) => (\n <SecretCard\n key={secret.key}\n secret={secret}\n onChanged={reload}\n open={openSecretKey === secret.key}\n onOpenChange={(open) => {\n if (open) setCustomKeyOpen(false);\n setOpenSecretKey(open ? secret.key : null);\n }}\n focusInput={openSecretKey === secret.key}\n />\n ))}\n </div>\n )}\n <AdHocKeysSection\n showForm={customKeyOpen}\n onShowFormChange={setCustomKeyOpen}\n showEmptyState={visibleSecrets.length === 0}\n />\n </div>\n );\n}\n\nfunction KeysHeader({\n availableSecrets = [],\n onSecret,\n onCustomKey,\n}: {\n availableSecrets?: SecretStatus[];\n onSecret?: (key: string) => void;\n onCustomKey: () => void;\n}) {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <p className=\"text-[11px] font-medium text-foreground\">Keys</p>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-accent/40 hover:text-foreground\"\n >\n <IconPlus size={11} />\n New\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-60\">\n {availableSecrets.length > 0 && (\n <>\n <DropdownMenuLabel>Choose a key</DropdownMenuLabel>\n {availableSecrets.map((secret) => (\n <DropdownMenuItem\n key={secret.key}\n onSelect={() => onSecret?.(secret.key)}\n className=\"flex items-center justify-between gap-3\"\n >\n <span className=\"truncate\">{secret.label}</span>\n {secret.required && (\n <span className=\"text-[9px] font-semibold uppercase tracking-wide text-amber-600 dark:text-amber-400\">\n Required\n </span>\n )}\n </DropdownMenuItem>\n ))}\n <DropdownMenuSeparator />\n </>\n )}\n <DropdownMenuItem onSelect={onCustomKey}>\n <IconPlus size={14} />\n Custom\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n}\n\ninterface SecretCardProps {\n secret: SecretStatus;\n onChanged: () => void;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n focusInput?: boolean;\n}\n\nfunction SecretCard({\n secret,\n onChanged,\n open,\n onOpenChange,\n focusInput,\n}: SecretCardProps) {\n const [value, setValue] = useState(\"\");\n const [busy, setBusy] = useState<null | \"save\" | \"delete\" | \"test\">(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (open && focusInput && inputRef.current) {\n inputRef.current.focus();\n }\n }, [focusInput, open]);\n\n const setToastAndClear = (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n setTimeout(() => setToast(null), ms);\n };\n\n const handleSave = async () => {\n if (!value.trim() || busy) return;\n setBusy(\"save\");\n try {\n const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ value: value.trim() }),\n });\n if (!res.ok) {\n const err = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setToastAndClear(\"err\", err ?? `Save failed (${res.status})`);\n return;\n }\n setValue(\"\");\n setConfirmDelete(false);\n setToastAndClear(\"ok\", \"Saved\");\n notifySecretsChanged();\n onChanged();\n } finally {\n setBusy(null);\n }\n };\n\n const handleDelete = async () => {\n if (busy) return;\n setBusy(\"delete\");\n try {\n const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n if (!res.ok) {\n const err = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setToastAndClear(\"err\", err ?? `Delete failed (${res.status})`);\n return;\n }\n setToastAndClear(\"ok\", \"Removed\");\n setConfirmDelete(false);\n notifySecretsChanged();\n onChanged();\n } finally {\n setBusy(null);\n }\n };\n\n const handleTest = async () => {\n if (busy) return;\n setBusy(\"test\");\n try {\n const res = await fetch(\n `${ENDPOINT}/${encodeURIComponent(secret.key)}/test`,\n {\n method: \"POST\",\n },\n );\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n };\n if (res.ok && body.ok) {\n setToastAndClear(\"ok\", \"Working\");\n } else {\n setToastAndClear(\n \"err\",\n body.error ?? (body.ok === false ? \"Invalid\" : `Test failed`),\n );\n }\n } finally {\n setBusy(null);\n }\n };\n\n const pill = useMemo(() => {\n if (secret.status === \"set\") {\n return (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Set\n </span>\n );\n }\n if (secret.required) {\n return (\n <span className=\"rounded-full bg-red-500/15 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-red-500\">\n Required\n </span>\n );\n }\n return (\n <span className=\"rounded-full bg-accent/60 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-muted-foreground\">\n Optional\n </span>\n );\n }, [secret.status, secret.required]);\n\n const isOAuth = secret.kind === \"oauth\";\n\n return (\n <div className=\"border-b border-border last:border-b-0\">\n <button\n type=\"button\"\n aria-expanded={open}\n onClick={() => onOpenChange(!open)}\n className=\"flex w-full items-center gap-2 px-2.5 py-2 text-start transition-colors hover:bg-accent/30\"\n >\n <IconChevronRight\n size={13}\n className={`shrink-0 text-muted-foreground transition-transform ${open ? \"rotate-90\" : \"\"}`}\n />\n <span className=\"min-w-0 flex-1 truncate text-[11px] font-medium text-foreground\">\n {secret.label}\n </span>\n {secret.status === \"set\" && secret.last4 && (\n <code className=\"text-[10px] text-muted-foreground\">\n ••••{secret.last4}\n </code>\n )}\n <span className=\"shrink-0\">{pill}</span>\n </button>\n\n {open && (\n <div className=\"border-t border-border/60 bg-accent/20 px-3 pb-3 pt-2.5\">\n {secret.description && (\n <p className=\"mb-2 text-[10px] leading-relaxed text-muted-foreground\">\n {secret.description}\n </p>\n )}\n {isOAuth ? (\n <div className=\"mt-2 flex items-center gap-1.5\">\n {secret.oauthConnectUrl && (\n <a\n href={secret.oauthConnectUrl}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium no-underline\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n <IconPlugConnected size={10} />\n {secret.status === \"set\" ? \"Reconnect\" : \"Connect\"}\n </a>\n )}\n {secret.docsUrl && (\n <a\n href={secret.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground\"\n >\n Docs\n <IconExternalLink size={10} />\n </a>\n )}\n </div>\n ) : (\n <div className=\"mt-2 space-y-1.5\">\n {secret.status === \"set\" && (\n <div className=\"flex items-center gap-2 text-[10px] text-muted-foreground\">\n <span>Stored value ending in</span>\n <code className=\"rounded bg-background px-1 py-0.5 text-foreground\">\n {secret.last4}\n </code>\n </div>\n )}\n <div className=\"flex gap-1.5\">\n <input\n ref={inputRef}\n type=\"password\"\n aria-label={secret.label}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleSave();\n }}\n placeholder={\n secret.status === \"set\"\n ? \"Enter new value to rotate\"\n : \"Paste key\"\n }\n className=\"flex-1 rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n />\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={!value.trim() || busy !== null}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n {busy === \"save\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : secret.status === \"set\" ? (\n <>\n <IconRefresh size={10} />\n Rotate\n </>\n ) : (\n \"Save\"\n )}\n </button>\n </div>\n <div className=\"flex items-center gap-1.5\">\n {secret.status === \"set\" && (\n <>\n <button\n type=\"button\"\n onClick={handleTest}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n {busy === \"test\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Test\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmDelete(true)}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-red-500 disabled:opacity-40\"\n >\n <IconTrash size={10} />\n Remove\n </button>\n </>\n )}\n {secret.docsUrl && (\n <a\n href={secret.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground ms-auto\"\n >\n Get key\n <IconExternalLink size={10} />\n </a>\n )}\n </div>\n {confirmDelete && (\n <div className=\"flex items-center gap-1.5 rounded border border-red-500/30 bg-red-500/10 px-2 py-1.5 text-[10px] text-red-500\">\n <span className=\"min-w-0 flex-1\">\n Remove this saved value?\n </span>\n <button\n type=\"button\"\n onClick={handleDelete}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-red-500/40 px-1.5 py-0.5 font-medium disabled:opacity-40\"\n >\n {busy === \"delete\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Confirm\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmDelete(false)}\n disabled={busy !== null}\n className=\"rounded border border-border px-1.5 py-0.5 text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n Cancel\n </button>\n </div>\n )}\n </div>\n )}\n\n {toast && (\n <p\n className={`mt-1.5 text-[10px] ${\n toast.kind === \"ok\" ? \"text-green-500\" : \"text-red-500\"\n }`}\n >\n {toast.text}\n </p>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// ─── Ad-hoc Keys Section ──────────────────────────────────────────────────\n\ninterface AdHocKey {\n name: string;\n scope: \"user\" | \"workspace\";\n scopeId: string;\n description: string | null;\n last4: string;\n createdAt: number;\n updatedAt: number;\n}\n\nconst ADHOC_ENDPOINT = agentNativePath(\"/_agent-native/secrets/adhoc\");\n\nfunction AdHocKeysSection({\n showForm,\n onShowFormChange,\n showEmptyState,\n}: {\n showForm: boolean;\n onShowFormChange: (show: boolean) => void;\n showEmptyState: boolean;\n}) {\n const [keys, setKeys] = useState<AdHocKey[]>([]);\n const [loading, setLoading] = useState(true);\n const [reloadToken, setReloadToken] = useState(0);\n const [formName, setFormName] = useState(\"\");\n const [formValue, setFormValue] = useState(\"\");\n const [formDescription, setFormDescription] = useState(\"\");\n const [formScope, setFormScope] = useState<\"user\" | \"workspace\">(\"user\");\n const [formBusy, setFormBusy] = useState(false);\n const [formError, setFormError] = useState<string | null>(null);\n const [confirmDeleteName, setConfirmDeleteName] = useState<string | null>(\n null,\n );\n const [deletingName, setDeletingName] = useState<string | null>(null);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n\n const showToast = useCallback(\n (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n setTimeout(() => setToast(null), ms);\n },\n [],\n );\n\n const reload = useCallback(() => setReloadToken((t) => t + 1), []);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n fetch(ADHOC_ENDPOINT)\n .then(async (r) => {\n if (!r.ok) throw new Error(`Failed to load (${r.status})`);\n return (await r.json()) as AdHocKey[];\n })\n .then((data) => {\n if (!cancelled) {\n setKeys(data);\n setLoading(false);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setKeys([]);\n setLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [reloadToken]);\n\n const resetForm = useCallback(() => {\n onShowFormChange(false);\n setFormName(\"\");\n setFormValue(\"\");\n setFormDescription(\"\");\n setFormScope(\"user\");\n setFormError(null);\n }, [onShowFormChange]);\n\n const handleAdd = useCallback(async () => {\n const name = formName.trim();\n const value = formValue.trim();\n if (!name || !value || formBusy) return;\n setFormBusy(true);\n setFormError(null);\n try {\n const res = await fetch(ADHOC_ENDPOINT, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n name,\n value,\n description: formDescription.trim() || undefined,\n scope: formScope,\n }),\n });\n if (!res.ok) {\n const body = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setFormError(body ?? `Save failed (${res.status})`);\n return;\n }\n resetForm();\n showToast(\"ok\", \"Key saved\");\n notifySecretsChanged();\n reload();\n } catch (err: any) {\n setFormError(err?.message ?? \"Failed to save\");\n } finally {\n setFormBusy(false);\n }\n }, [\n formName,\n formValue,\n formDescription,\n formScope,\n formBusy,\n resetForm,\n showToast,\n reload,\n ]);\n\n const handleDelete = useCallback(\n async (name: string) => {\n setDeletingName(name);\n try {\n const res = await fetch(\n `${ADHOC_ENDPOINT}/${encodeURIComponent(name)}`,\n {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n if (!res.ok) {\n showToast(\"err\", \"Failed to delete key\");\n return;\n }\n showToast(\"ok\", \"Key deleted\");\n setConfirmDeleteName(null);\n notifySecretsChanged();\n reload();\n } finally {\n setDeletingName(null);\n }\n },\n [showToast, reload],\n );\n\n return (\n <div className=\"space-y-2\">\n {showForm && (\n <div className=\"rounded-md border border-border px-2.5 py-2 bg-accent/30 space-y-1.5\">\n <input\n value={formName}\n onChange={(e) =>\n setFormName(\n e.target.value.toUpperCase().replace(/[^A-Z0-9_-]/g, \"\"),\n )\n }\n className=\"w-full rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n aria-label=\"Key name\"\n placeholder=\"KEY_NAME\"\n />\n <input\n type=\"password\"\n aria-label=\"Secret value\"\n value={formValue}\n onChange={(e) => setFormValue(e.target.value)}\n className=\"w-full rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"Secret value\"\n />\n <input\n value={formDescription}\n aria-label=\"Description\"\n onChange={(e) => setFormDescription(e.target.value)}\n className=\"w-full rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent\"\n placeholder=\"Description (optional)\"\n />\n <div className=\"flex items-center gap-2\">\n <select\n aria-label=\"Scope\"\n value={formScope}\n onChange={(e) =>\n setFormScope(e.target.value as \"user\" | \"workspace\")\n }\n className=\"rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none focus:ring-1 focus:ring-accent\"\n >\n <option value=\"user\">Personal</option>\n <option value=\"workspace\">Workspace</option>\n </select>\n <div className=\"ms-auto flex items-center gap-1.5\">\n <button\n type=\"button\"\n onClick={resetForm}\n className=\"rounded border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleAdd}\n disabled={!formName.trim() || !formValue.trim() || formBusy}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n {formBusy ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Save\"\n )}\n </button>\n </div>\n </div>\n {formError && <p className=\"text-[10px] text-red-500\">{formError}</p>}\n </div>\n )}\n\n {loading ? (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading...\n </div>\n ) : keys.length === 0 && !showForm && showEmptyState ? (\n <p className=\"text-[10px] text-muted-foreground\">No keys added yet.</p>\n ) : keys.length > 0 ? (\n <div className=\"overflow-hidden rounded-md border border-border\">\n {keys.map((key) => (\n <div\n key={`${key.scope}-${key.name}`}\n className=\"border-b border-border px-2.5 py-2 last:border-b-0\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-[11px] font-medium text-foreground font-mono truncate\">\n {key.name}\n </span>\n <span\n className={`rounded-full px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${\n key.scope === \"workspace\"\n ? \"bg-blue-500/15 text-blue-500\"\n : \"bg-accent/60 text-muted-foreground\"\n }`}\n >\n {key.scope === \"workspace\" ? \"workspace\" : \"personal\"}\n </span>\n </div>\n {key.description && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">\n {key.description}\n </p>\n )}\n <div className=\"flex items-center gap-2 text-[10px] text-muted-foreground mt-0.5\">\n <span>\n Ending in{\" \"}\n <code className=\"rounded bg-background px-1 py-0.5 text-foreground\">\n {key.last4}\n </code>\n </span>\n </div>\n </div>\n <div className=\"shrink-0\">\n {confirmDeleteName === key.name ? (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => handleDelete(key.name)}\n disabled={deletingName === key.name}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-red-500/15 text-red-500 hover:bg-red-500/25 disabled:opacity-40\"\n >\n {deletingName === key.name ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Confirm\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmDeleteName(null)}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-accent/60 text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setConfirmDeleteName(key.name)}\n className=\"text-muted-foreground hover:text-red-500\"\n >\n <IconTrash size={12} />\n </button>\n </TooltipTrigger>\n <TooltipContent>Delete</TooltipContent>\n </Tooltip>\n )}\n </div>\n </div>\n </div>\n ))}\n </div>\n ) : null}\n\n {toast && (\n <p\n className={`text-[10px] ${toast.kind === \"ok\" ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {toast.text}\n </p>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { SettingsTabItem } from "./SettingsTabsPage.js";
|
|
3
|
+
export declare function AppDefaultModelField({ engine, models, value, defaultModel, disabled, onValueChange, onEnter, }: {
|
|
4
|
+
engine: string;
|
|
5
|
+
models: string[];
|
|
6
|
+
value: string;
|
|
7
|
+
defaultModel?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
onValueChange: (value: string) => void;
|
|
10
|
+
onEnter?: () => void;
|
|
11
|
+
}): React.JSX.Element;
|
|
3
12
|
export interface SettingsPanelProps {
|
|
4
13
|
isDevMode: boolean;
|
|
5
14
|
onToggleDevMode: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsPanel.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsPanel.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAQN,MAAM,OAAO,CAAC;AA2Bf,OAAO,KAAK,EAEV,eAAe,EAChB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"SettingsPanel.d.ts","sourceRoot":"","sources":["../../../src/client/settings/SettingsPanel.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAQN,MAAM,OAAO,CAAC;AA2Bf,OAAO,KAAK,EAEV,eAAe,EAChB,MAAM,uBAAuB,CAAC;AAwoB/B,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,MAAM,EACN,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,OAAO,GACR,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,qBAqDA;AAs+CD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAw6BD,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,qBAEtD;AAED,wBAAgB,oBAAoB,IAAI,eAAe,EAAE,CAiFxD"}
|