@agent-native/core 0.169.0 → 0.170.0
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/agent-native.eject.json +4 -1
- package/bin/agent-native.js +23 -5
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/analytics/actions/bigquery-table-info.ts +3 -2
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/actions/search-bigquery-schema.ts +130 -4
- package/corpus/templates/analytics/agent-native.config.ts +1 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +36 -23
- package/corpus/templates/analytics/app/i18n-data.ts +28 -0
- package/corpus/templates/analytics/app/lib/dashboard-visibility.ts +41 -0
- package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
- package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +34 -9
- package/corpus/templates/analytics/app/routes/$.tsx +10 -0
- package/corpus/templates/analytics/app/routes.ts +3 -1
- package/corpus/templates/analytics/changelog/2026-08-21-dashboard-filters-keep-other-users-dashboards-out-of-mine.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-fixed-the-agent-native-templates-first-party-dashboard-panel.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-org-admin-panels-no-longer-report-a-database-error-as-a-per.md +9 -0
- package/corpus/templates/analytics/changelog/2026-08-22-slack-requests-report-invalid-inputs.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-unknown-analytics-links-now-return-a-real-not-found-status.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +2 -1
- package/corpus/templates/analytics/docs/schemas/tracked-events.md +2 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +29 -7
- package/corpus/templates/analytics/server/handlers/slack.ts +59 -5
- package/corpus/templates/analytics/server/lib/db-admin-connections.ts +11 -6
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +132 -2
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +14 -3
- package/corpus/templates/analytics/server/lib/slack.ts +4 -2
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +33 -3
- package/corpus/templates/analytics/vitest.config.ts +6 -1
- package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/assets/app/routes/library.tsx +5 -3
- package/corpus/templates/assets/app/routes.ts +3 -1
- package/corpus/templates/assets/changelog/2026-08-22-library-page-loads-again-instead-of-crashing-on-open.md +6 -0
- package/corpus/templates/assets/vitest.config.ts +6 -1
- package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/brain/app/components/ui/pointer-lock.ts +1 -0
- package/corpus/templates/brain/app/routes/sources.tsx +8 -3
- package/corpus/templates/brain/changelog/2026-08-22-tuning-or-adding-a-source-no-longer-leaves-the-sources-page.md +6 -0
- package/corpus/templates/brain/server/lib/brain.ts +27 -2
- package/corpus/templates/brain/vitest.config.ts +1 -0
- package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/calendar/actions/list-booking-links.ts +83 -4
- package/corpus/templates/calendar/actions/update-booking-link.ts +4 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +11 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +1 -1
- package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +103 -44
- package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +28 -24
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +9 -2
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +47 -58
- package/corpus/templates/calendar/app/hooks/use-booking-links.ts +5 -1
- package/corpus/templates/calendar/app/lib/event-layout.ts +52 -26
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +126 -98
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +1 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +88 -81
- package/corpus/templates/calendar/app/routes.ts +3 -1
- package/corpus/templates/calendar/changelog/2026-08-22-booking-link-visibility-respects-shared-access.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-clicking-an-out-of-office-event-s-marker-no-longer-creates-a.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-event-detail-views-now-show-your-calendar-timezone.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-google-calendar-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-overlapping-events-now-show-each-others-boundaries.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-public-booking-pages-now-offer-time-slots-from-the-host-s-we.md +6 -0
- package/corpus/templates/calendar/server/handlers/bookings.ts +5 -7
- package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
- package/corpus/templates/calendar/server/lib/google-calendar.ts +139 -14
- package/corpus/templates/calendar/server/onboarding.ts +85 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/calendar/shared/api.ts +9 -1
- package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/chat/app/routes.ts +3 -1
- package/corpus/templates/chat/vitest.config.ts +8 -0
- package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/clips/actions/get-meeting.ts +9 -4
- package/corpus/templates/clips/actions/list-recordings.ts +16 -3
- package/corpus/templates/clips/actions/search-meetings.ts +1 -0
- package/corpus/templates/clips/actions/stop-meeting-recording.ts +87 -6
- package/corpus/templates/clips/actions/view-screen.ts +8 -1
- package/corpus/templates/clips/app/components/library/search-bar.tsx +1 -1
- package/corpus/templates/clips/app/components/meetings/meeting-history-row.tsx +32 -1
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +29 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +33 -4
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -0
- package/corpus/templates/clips/app/routes/access-request.approve.tsx +16 -9
- package/corpus/templates/clips/app/routes/embed.$shareId.tsx +17 -7
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +17 -7
- package/corpus/templates/clips/changelog/2026-08-21-camera-bubble-black-circle.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-22-screen-recordings-respect-the-microphone-toggle.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-22-the-recordings-library-no-longer-fails-right-after-server-start.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-23-the-agent-can-see-your-library-right-after-server-start.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +1 -2
- package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +39 -7
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +21 -25
- package/corpus/templates/clips/desktop/src/app.tsx +53 -24
- package/corpus/templates/clips/desktop/src/lib/bubble-playback.ts +68 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +3 -0
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +72 -14
- package/corpus/templates/clips/desktop/src/lib/updater.ts +8 -3
- package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +162 -20
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -6
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +150 -13
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +28 -3
- package/corpus/templates/clips/server/lib/emails.ts +17 -33
- package/corpus/templates/content/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +140 -15
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +12 -14
- package/corpus/templates/content/app/components/ui/pointer-lock.ts +1 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +18 -2
- package/corpus/templates/content/app/hooks/use-local-storage.ts +38 -22
- package/corpus/templates/content/app/i18n-data.ts +25 -0
- package/corpus/templates/content/app/routes.ts +3 -1
- package/corpus/templates/content/changelog/2026-08-22-code-blocks-inserted-from-the-slash-menu-no-longer-get-stuck.md +6 -0
- package/corpus/templates/content/changelog/2026-08-22-the-sidebar-page-tree-no-longer-flashes-empty-after-creating-a-page.md +6 -0
- package/corpus/templates/content/docs/solutions/2026-08-21-content-mermaid-rendering-shape.md +233 -0
- package/corpus/templates/content/server/plugins/agent-chat.ts +9 -2
- package/corpus/templates/content/vitest.config.ts +7 -1
- package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/design/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1386 -92
- package/corpus/templates/design/actions/generate-design.ts +98 -47
- package/corpus/templates/design/actions/get-design-system.ts +6 -1
- package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +146 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +70 -26
- package/corpus/templates/design/app/components/design/EditPanel.tsx +15 -47
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2060 -144
- package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +6 -2
- package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +4 -4
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +10 -8
- package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +19 -2
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -2
- package/corpus/templates/design/app/components/layout/Header.tsx +15 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +7 -2
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +13 -8
- package/corpus/templates/design/app/i18n-data.ts +11 -10
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +12 -0
- package/corpus/templates/design/app/lib/design-system-data.ts +68 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +99 -57
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +39 -8
- package/corpus/templates/design/app/pages/DesignSystems.tsx +137 -43
- package/corpus/templates/design/app/pages/Index.tsx +3 -1
- package/corpus/templates/design/app/pages/Templates.tsx +0 -10
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +10 -0
- package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +50 -0
- package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +10 -8
- package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +6 -6
- package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +18 -7
- package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +4 -90
- package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +2 -1
- package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +4 -3
- package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +12 -2
- package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +9 -2
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +11 -1
- package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +11 -19
- package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +6 -6
- package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +12 -15
- package/corpus/templates/design/app/pages/design-editor/preview-navigation.ts +25 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -59
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +8 -0
- package/corpus/templates/design/app/pages/design-editor/types.ts +3 -3
- package/corpus/templates/design/app/routes.ts +3 -1
- package/corpus/templates/design/changelog/2026-08-20-canvas-edits-patch-the-frame-instead-of-rebuilding-it.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-draw-mode-needs-shift-y.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-eyedropper-shortcut.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-figma-style-alignment-guides-and-snapping.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-group-transforms-keep-the-selection.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-inspector-fields-keep-focus-on-enter.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-pen-alt-keeps-the-incoming-handle.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-pen-on-the-board-creates-one-vector.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-scale-a-multi-selection-from-the-group-handles.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-scale-resizes-text-with-the-object.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-selecting-another-object-keeps-the-scale-tool-armed.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-the-shape-tool-remembers-the-shape-you-picked.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-vectors-drawn-in-a-frame-land-where-you-drew-them.md +6 -0
- package/corpus/templates/design/changelog/2026-08-22-multi-screen-generation-no-longer-loses-a-saved-screens-layo.md +6 -0
- package/corpus/templates/design/changelog/2026-08-22-rename-and-search-fields-are-labeled-for-screen-readers.md +6 -0
- package/corpus/templates/design/package.json +2 -0
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +311 -0
- package/corpus/templates/design/shared/canvas-math.ts +612 -206
- package/corpus/templates/design/shared/pen-path.ts +37 -0
- package/corpus/templates/design/vitest.config.ts +7 -1
- package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/dispatch/actions/list-workspace-connections.ts +34 -3
- package/corpus/templates/dispatch/app/routes/integrations.tsx +55 -21
- package/corpus/templates/dispatch/app/routes.ts +3 -1
- package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/factory/.env.example +2 -7
- package/corpus/templates/factory/AGENTS.md +3 -0
- package/corpus/templates/factory/README.md +5 -3
- package/corpus/templates/factory/actions/create-factory.ts +16 -3
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +2 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +2 -0
- package/corpus/templates/factory/actions/list-factory-audit.ts +116 -36
- package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
- package/corpus/templates/factory/actions/list-triage-items.ts +22 -19
- package/corpus/templates/factory/actions/run-factory-automation.ts +7 -3
- package/corpus/templates/factory/actions/save-factory-automation.ts +5 -2
- package/corpus/templates/factory/actions/save-triage-config.ts +2 -8
- package/corpus/templates/factory/actions/start-builder-for-item.ts +21 -0
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +229 -297
- package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +397 -247
- package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +33 -0
- package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +202 -162
- package/corpus/templates/factory/app/i18n/en-US.ts +32 -4
- package/corpus/templates/factory/app/routes/factory.tsx +84 -11
- package/corpus/templates/factory/app/routes.ts +3 -1
- package/corpus/templates/factory/changelog/2026-08-21-activity-runs-use-automation-display-names.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-create-and-settings-source-cards.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-keep-automations-visible-while-running.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-nested-factory-automations-can-poll.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-settings-sticky-unsaved-bar.md +6 -0
- package/corpus/templates/factory/server/connectors/credentials.ts +10 -5
- package/corpus/templates/factory/server/lib/factory-audit-report.ts +412 -0
- package/corpus/templates/factory/server/lib/factory-config-reconcile.ts +321 -0
- package/corpus/templates/factory/server/lib/factory-scope.ts +25 -2
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +13 -4
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +148 -4
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +4 -6
- package/corpus/templates/factory/vitest.config.ts +17 -2
- package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/forms/app/routes/_app.settings.tsx +4 -1
- package/corpus/templates/forms/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +11 -1
- package/corpus/templates/forms/vitest.config.ts +1 -0
- package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/macros/app/routes.ts +3 -1
- package/corpus/templates/macros/vitest.config.ts +6 -1
- package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/mail/actions/manage-gmail-filters.ts +10 -2
- package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -37
- package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +14 -2
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +66 -36
- package/corpus/templates/mail/app/hooks/use-emails.ts +13 -3
- package/corpus/templates/mail/app/hooks/use-google-auth.ts +2 -0
- package/corpus/templates/mail/app/lib/google-oauth-setup.ts +17 -0
- package/corpus/templates/mail/app/pages/InboxPage.tsx +69 -9
- package/corpus/templates/mail/app/routes/$.tsx +9 -0
- package/corpus/templates/mail/app/routes/$view.$threadId.tsx +23 -1
- package/corpus/templates/mail/app/routes/$view.tsx +47 -1
- package/corpus/templates/mail/app/routes.ts +3 -1
- package/corpus/templates/mail/changelog/2026-08-22-gmail-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-22-gmail-filters-now-shows-the-real-error.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-22-unknown-mail-urls-now-show-the-404-page.md +6 -0
- package/corpus/templates/mail/server/handlers/google-auth.ts +11 -2
- package/corpus/templates/mail/server/lib/google-auth.ts +92 -12
- package/corpus/templates/mail/server/onboarding.ts +66 -18
- package/corpus/templates/mail/vitest.config.ts +6 -1
- package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/plan/app/routes/settings.tsx +4 -1
- package/corpus/templates/plan/app/routes.ts +3 -1
- package/corpus/templates/plan/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/plan/netlify.toml +1 -1
- package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/slides/actions/patch-deck.ts +79 -10
- package/corpus/templates/slides/actions/update-slide.ts +11 -1
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +14 -4
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +10 -52
- package/corpus/templates/slides/app/components/editor/GoogleDocImportHint.tsx +8 -53
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +9 -75
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +8 -60
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +10 -2
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +19 -7
- package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +49 -36
- package/corpus/templates/slides/app/routes/access-request.approve.tsx +16 -9
- package/corpus/templates/slides/app/routes.ts +3 -1
- package/corpus/templates/slides/changelog/2026-08-22-already-uploaded-chat-images-are-no-longer-dropped.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-google-drive-and-slides-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-multi-slide-repairs-now-report-slides-that-still-overflow.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-update-slide-now-reports-which-batched-edit-was-skipped.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +52 -1
- package/corpus/templates/slides/server/lib/chat-attachments.ts +29 -3
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +66 -16
- package/corpus/templates/slides/server/lib/slide-content-patch.ts +13 -2
- package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -2
- package/corpus/templates/slides/tsconfig.json +5 -0
- package/corpus/templates/slides/vitest.config.ts +6 -1
- package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/tasks/app/routes/settings.tsx +4 -1
- package/corpus/templates/tasks/app/routes.ts +3 -1
- package/corpus/templates/tasks/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/tasks/vitest.config.ts +7 -1
- package/dist/action.d.ts +91 -0
- package/dist/action.js +50 -0
- package/dist/agent/abort-reasons.d.ts +38 -0
- package/dist/agent/abort-reasons.js +49 -0
- package/dist/agent/engine/ai-sdk-engine.js +8 -5
- package/dist/agent/engine/anthropic-engine.js +7 -5
- package/dist/agent/engine/credential-errors.d.ts +1 -1
- package/dist/agent/engine/credential-errors.js +2 -2
- package/dist/agent/engine/first-event-timeout.d.ts +42 -17
- package/dist/agent/engine/first-event-timeout.js +67 -25
- package/dist/agent/production-agent.d.ts +23 -0
- package/dist/agent/production-agent.js +107 -102
- package/dist/agent/run-loop-with-resume.d.ts +2 -28
- package/dist/agent/run-loop-with-resume.js +25 -40
- package/dist/agent/run-manager.js +5 -4
- package/dist/agent/run-store.d.ts +55 -0
- package/dist/agent/run-store.js +124 -1
- package/dist/agent/tool-search.js +2 -1
- package/dist/agent/types.d.ts +9 -4
- package/dist/app-config/configuration-error.d.ts +11 -0
- package/dist/app-config/configuration-error.js +14 -0
- package/dist/app-config/index.d.ts +1 -0
- package/dist/app-config/index.js +1 -0
- package/dist/app-config/integrations.d.ts +1 -0
- package/dist/app-config/integrations.js +10 -0
- package/dist/app-config/plugins.d.ts +34 -0
- package/dist/app-config/plugins.js +39 -0
- package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
- package/dist/app-config/run-lifecycle-invariants.js +18 -25
- package/dist/app-config/schema.d.ts +16 -0
- package/dist/app-config/schema.js +2 -0
- package/dist/chat-threads/schema-migrations.js +20 -0
- package/dist/chat-threads/store.js +21 -4
- package/dist/cli/native-dependencies.d.ts +4 -0
- package/dist/cli/native-dependencies.js +15 -0
- package/dist/client/AssistantChat.js +47 -15
- package/dist/client/ConnectBuilderCard.d.ts +3 -1
- package/dist/client/ConnectBuilderCard.js +6 -3
- package/dist/client/EnvironmentBadge.d.ts +1 -1
- package/dist/client/EnvironmentBadge.js +40 -5
- package/dist/client/MultiTabAssistantChat.d.ts +1 -1
- package/dist/client/MultiTabAssistantChat.js +35 -14
- package/dist/client/agent-chat/index.d.ts +1 -1
- package/dist/client/agent-chat/index.js +1 -1
- package/dist/client/agent-page/use-jobs.d.ts +2 -1
- package/dist/client/agent-page/use-jobs.js +3 -5
- package/dist/client/agent-sidebar-state.js +3 -1
- package/dist/client/blocks/library/code-tabs.js +5 -0
- package/dist/client/blocks/library/code.js +1 -0
- package/dist/client/chat/message-components.d.ts +7 -0
- package/dist/client/chat/message-components.js +1 -1
- package/dist/client/chat/run-recovery.js +5 -2
- package/dist/client/chat/tool-call-display.js +9 -3
- package/dist/client/chat-first/apps-rail.js +2 -2
- package/dist/client/chat-model-groups.d.ts +12 -0
- package/dist/client/chat-model-groups.js +3 -2
- package/dist/client/error-format.js +12 -0
- package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
- package/dist/client/integrations/GoogleProductLogo.js +45 -0
- package/dist/client/integrations/index.d.ts +2 -0
- package/dist/client/integrations/index.js +2 -0
- package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
- package/dist/client/integrations/workspace-provider-oauth.js +13 -0
- package/dist/client/navigation/index.d.ts +1 -0
- package/dist/client/navigation/index.js +1 -0
- package/dist/client/resources/mcp-integration-catalog.js +0 -29
- package/dist/client/route-state.js +6 -0
- package/dist/client/settings/SettingsTabsPage.js +10 -6
- package/dist/client/sharing/ShareButton.js +11 -2
- package/dist/client/use-chat-models.d.ts +6 -0
- package/dist/client/use-chat-models.js +10 -0
- package/dist/client/use-db-sync.js +27 -9
- package/dist/client/workspace-app-navigation.d.ts +10 -0
- package/dist/client/workspace-app-navigation.js +38 -0
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +111 -9
- package/dist/connections/catalog.js +86 -30
- package/dist/db/create-get-db.js +18 -0
- package/dist/db/ddl-guard.d.ts +0 -4
- package/dist/db/ddl-guard.js +46 -0
- package/dist/deploy/build.d.ts +32 -0
- package/dist/deploy/build.js +241 -16
- package/dist/deploy/function-bundle.d.ts +45 -0
- package/dist/deploy/function-bundle.js +337 -0
- package/dist/deploy/workspace-deploy.js +19 -1
- package/dist/eject/workspace-connections.js +4 -0
- package/dist/email-catalog/registry.d.ts +4 -0
- package/dist/email-catalog/registry.js +79 -14
- package/dist/extensions/content-patch.js +14 -2
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/plugin.d.ts +10 -0
- package/dist/integrations/plugin.js +40 -6
- package/dist/jobs/actions/run-automation-now.d.ts +2 -1
- package/dist/jobs/actions/run-automation-now.js +11 -5
- package/dist/jobs/frontmatter.js +53 -2
- package/dist/jobs/run-now.d.ts +11 -1
- package/dist/jobs/run-now.js +42 -7
- package/dist/jobs/scheduler.d.ts +1 -0
- package/dist/jobs/scheduler.js +2 -1
- package/dist/localization/core-messages/ar-SA.js +4 -1
- package/dist/localization/core-messages/de-DE.js +4 -1
- package/dist/localization/core-messages/en-US.d.ts +4 -1
- package/dist/localization/core-messages/en-US.js +4 -1
- package/dist/localization/core-messages/es-ES.js +4 -1
- package/dist/localization/core-messages/fr-FR.js +4 -1
- package/dist/localization/core-messages/hi-IN.js +4 -1
- package/dist/localization/core-messages/ja-JP.js +4 -1
- package/dist/localization/core-messages/ko-KR.js +4 -1
- package/dist/localization/core-messages/pt-BR.js +4 -1
- package/dist/localization/core-messages/zh-CN.js +4 -1
- package/dist/localization/core-messages/zh-TW.js +4 -1
- package/dist/localization/core-messages.d.ts +4 -1
- package/dist/localization/default-messages.d.ts +2 -5
- package/dist/localization/default-messages.js +2 -5
- package/dist/mcp/build-server.d.ts +9 -0
- package/dist/mcp/build-server.js +37 -8
- package/dist/mcp-client/oauth-client.d.ts +7 -0
- package/dist/mcp-client/oauth-client.js +12 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/oauth-tokens/index.d.ts +1 -1
- package/dist/oauth-tokens/index.js +1 -1
- package/dist/oauth-tokens/lifecycle.d.ts +11 -0
- package/dist/oauth-tokens/lifecycle.js +17 -0
- package/dist/oauth-tokens/store.js +7 -0
- package/dist/observability/posthog-ai.d.ts +15 -1
- package/dist/observability/posthog-ai.js +24 -12
- package/dist/observability/traces.js +158 -28
- package/dist/onboarding/app-profile.js +2 -2
- package/dist/onboarding/plugin.js +10 -2
- package/dist/onboarding/types.d.ts +2 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.js +2 -0
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.js +13 -4
- package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
- package/dist/scripts/db/check-scoping.js +9 -6
- package/dist/secrets/register-framework-secrets.js +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
- package/dist/server/agent-chat/action-filters-a2a.js +48 -9
- package/dist/server/agent-chat-plugin.js +36 -9
- package/dist/server/agent-discovery.js +43 -20
- package/dist/server/auth.js +18 -16
- package/dist/server/beta-opt-out-html.js +45 -4
- package/dist/server/better-auth-instance.d.ts +2 -1
- package/dist/server/better-auth-instance.js +23 -7
- package/dist/server/builder-browser.d.ts +4 -0
- package/dist/server/builder-browser.js +23 -1
- package/dist/server/builder-design-systems.d.ts +4 -1
- package/dist/server/builder-design-systems.js +87 -6
- package/dist/server/builder-oauth.d.ts +1 -7
- package/dist/server/builder-oauth.js +80 -163
- package/dist/server/core-routes-plugin.d.ts +29 -0
- package/dist/server/core-routes-plugin.js +113 -21
- package/dist/server/default-plugins.d.ts +18 -0
- package/dist/server/default-plugins.js +22 -0
- package/dist/server/edge.d.ts +1 -0
- package/dist/server/edge.js +1 -0
- package/dist/server/framework-request-handler.js +31 -3
- package/dist/server/google-oauth.d.ts +3 -0
- package/dist/server/google-oauth.js +3 -0
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.js +3 -3
- package/dist/server/onboarding-html.js +37 -3
- package/dist/server/workspace-provider-oauth.d.ts +6 -1
- package/dist/server/workspace-provider-oauth.js +72 -20
- package/dist/shared/agent-sidebar-url.d.ts +1 -0
- package/dist/shared/agent-sidebar-url.js +1 -0
- package/dist/shared/environment-lanes.d.ts +2 -0
- package/dist/shared/environment-lanes.js +3 -1
- package/dist/shared/index.d.ts +3 -1
- package/dist/shared/index.js +3 -1
- package/dist/shared/surface-visibility.d.ts +31 -0
- package/dist/shared/surface-visibility.js +57 -0
- package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/chat/app/routes.ts +3 -1
- package/dist/templates/chat/vitest.config.ts +8 -0
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/default/app/routes.ts +3 -1
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/tracking/registry.d.ts +11 -0
- package/dist/tracking/registry.js +5 -2
- package/dist/triggers/actions.js +10 -3
- package/dist/usage/store.js +23 -3
- package/dist/user-profile/actions/get-auth-methods.js +18 -5
- package/dist/vite/client.js +24 -5
- package/docs/content/actions-access-control.mdx +43 -4
- package/docs/content/actions-defining.mdx +16 -0
- package/docs/content/template-clips-capture-everywhere.mdx +29 -30
- package/docs/content/template-clips-developers.mdx +4 -4
- package/docs/content/template-clips.mdx +3 -1
- package/package.json +3 -3
- package/src/eject/workspace-connections.ts +4 -0
- package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/chat/app/routes.ts +3 -1
- package/src/templates/chat/vitest.config.ts +8 -0
- package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/default/app/routes.ts +3 -1
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
- /package/corpus/templates/dispatch/app/routes/{apps.$appId.tsx → apps.$appId.$.tsx} +0 -0
|
@@ -121,6 +121,8 @@ function getPollAbortMs(interval) {
|
|
|
121
121
|
return Math.max(POLL_ABORT_MIN_MS, interval * 4);
|
|
122
122
|
}
|
|
123
123
|
const ACTIVE_RUN_CLEAR_TIMEOUT_MS = 5_000;
|
|
124
|
+
const ACTIVE_RUN_CLEAR_STABLE_POLLS = 2;
|
|
125
|
+
const ACTIVE_RUN_CLEAR_RETRY_DELAY_MS = 1_000;
|
|
124
126
|
const ACTIVE_RUN_STUCK_THRESHOLD_MS = 90_000;
|
|
125
127
|
const BACKGROUND_ACTIVE_RUN_STUCK_THRESHOLD_MS = 13 * 60_000;
|
|
126
128
|
const ACTIVE_RUN_POLL_INTERVAL_MS = 150;
|
|
@@ -303,6 +305,7 @@ export async function waitForThreadRunToClear(apiUrl, threadId) {
|
|
|
303
305
|
return true;
|
|
304
306
|
const deadline = Date.now() + ACTIVE_RUN_CLEAR_TIMEOUT_MS;
|
|
305
307
|
let activeRunToResume = null;
|
|
308
|
+
let consecutiveClearPolls = 0;
|
|
306
309
|
const resumeActiveRun = (info) => {
|
|
307
310
|
if (!info.runId)
|
|
308
311
|
return;
|
|
@@ -323,11 +326,22 @@ export async function waitForThreadRunToClear(apiUrl, threadId) {
|
|
|
323
326
|
const res = await fetch(`${apiUrl}/runs/active?threadId=${encodeURIComponent(threadId)}`);
|
|
324
327
|
if (res.ok) {
|
|
325
328
|
const info = (await res.json());
|
|
326
|
-
|
|
329
|
+
const runLooksClear = !info?.active ||
|
|
327
330
|
info?.status !== "running" ||
|
|
328
|
-
activeRunLooksStale(info)
|
|
329
|
-
|
|
330
|
-
|
|
331
|
+
activeRunLooksStale(info);
|
|
332
|
+
if (runLooksClear) {
|
|
333
|
+
consecutiveClearPolls += 1;
|
|
334
|
+
// A terminal/no-active snapshot can briefly appear between a
|
|
335
|
+
// foreground run and its server-owned continuation. Require two
|
|
336
|
+
// consecutive clear polls before releasing a queued follow-up.
|
|
337
|
+
if (consecutiveClearPolls >= ACTIVE_RUN_CLEAR_STABLE_POLLS) {
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
consecutiveClearPolls = 0;
|
|
343
|
+
}
|
|
344
|
+
if (!runLooksClear && info.runId) {
|
|
331
345
|
activeRunToResume = info;
|
|
332
346
|
if (info.awaitingRedispatch === true) {
|
|
333
347
|
// This is not the brief terminal-write lag the 5s waiter was built
|
|
@@ -340,8 +354,12 @@ export async function waitForThreadRunToClear(apiUrl, threadId) {
|
|
|
340
354
|
}
|
|
341
355
|
}
|
|
342
356
|
}
|
|
357
|
+
else {
|
|
358
|
+
consecutiveClearPolls = 0;
|
|
359
|
+
}
|
|
343
360
|
}
|
|
344
361
|
catch {
|
|
362
|
+
consecutiveClearPolls = 0;
|
|
345
363
|
// Transient poll failure — try again until the short grace period ends.
|
|
346
364
|
}
|
|
347
365
|
await new Promise((resolve) => window.setTimeout(resolve, ACTIVE_RUN_POLL_INTERVAL_MS));
|
|
@@ -1730,6 +1748,15 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1730
1748
|
tabId,
|
|
1731
1749
|
onActiveRunChange: setHasActiveServerRun,
|
|
1732
1750
|
});
|
|
1751
|
+
// Server truth must participate in submit gating, not only in the missing
|
|
1752
|
+
// final-response warning. The local lifecycle can clear during a transport
|
|
1753
|
+
// handoff while the server still owns the turn.
|
|
1754
|
+
const serverRunState = useRunStuckDetection({
|
|
1755
|
+
threadId: threadId ?? null,
|
|
1756
|
+
enabled: isActiveComposer,
|
|
1757
|
+
apiUrl,
|
|
1758
|
+
});
|
|
1759
|
+
const serverRunActive = serverRunState.runId != null && serverRunState.status === "running";
|
|
1733
1760
|
// Real running state drives submission/queue gating; UI running also covers
|
|
1734
1761
|
// short auto-continuation gaps so the latest assistant message does not flash
|
|
1735
1762
|
// into a done state while the agent is still working.
|
|
@@ -1739,19 +1766,10 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1739
1766
|
isReconnecting,
|
|
1740
1767
|
optimisticRunning,
|
|
1741
1768
|
isAutoResuming,
|
|
1742
|
-
hasActiveServerRun,
|
|
1769
|
+
hasActiveServerRun: hasActiveServerRun || serverRunActive,
|
|
1743
1770
|
hasTerminalRunError: runErrorInfo !== null,
|
|
1744
1771
|
});
|
|
1745
1772
|
const textStreaming = showRunningInUI || externalStreaming;
|
|
1746
|
-
// Server truth about this thread's run, used to suppress the "agent stopped
|
|
1747
|
-
// without sending a final message" notice while the server still has the
|
|
1748
|
-
// turn in flight. The poll backs itself off to 15s while nothing is running.
|
|
1749
|
-
const serverRunState = useRunStuckDetection({
|
|
1750
|
-
threadId: threadId ?? null,
|
|
1751
|
-
enabled: isActiveComposer,
|
|
1752
|
-
apiUrl,
|
|
1753
|
-
});
|
|
1754
|
-
const serverRunActive = serverRunState.runId != null && serverRunState.status === "running";
|
|
1755
1773
|
const storedActiveRun = getActiveRun();
|
|
1756
1774
|
const activeChatRunId = (serverRunState.status === "running" ? serverRunState.runId : null) ??
|
|
1757
1775
|
(activeRunMatchesThread(storedActiveRun, threadId)
|
|
@@ -3318,6 +3336,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3318
3336
|
dequeueInFlightRef.current = true;
|
|
3319
3337
|
let cancelled = false;
|
|
3320
3338
|
let started = false;
|
|
3339
|
+
let retryTimer = null;
|
|
3321
3340
|
const timer = window.setTimeout(() => {
|
|
3322
3341
|
started = true;
|
|
3323
3342
|
void (async () => {
|
|
@@ -3329,8 +3348,19 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3329
3348
|
// complete. Starting the queued turn during that window can reconnect
|
|
3330
3349
|
// to the old run and replay the old answer under the new prompt.
|
|
3331
3350
|
const runCleared = await waitForThreadRunToClear(apiUrl, threadId);
|
|
3332
|
-
if (cancelled
|
|
3351
|
+
if (cancelled)
|
|
3333
3352
|
return;
|
|
3353
|
+
if (!runCleared) {
|
|
3354
|
+
// The server still owns this turn (including a deferred durable
|
|
3355
|
+
// successor). Keep the queued message visible and retry after a
|
|
3356
|
+
// short delay so one transient idle snapshot cannot strand it.
|
|
3357
|
+
retryTimer = window.setTimeout(() => {
|
|
3358
|
+
if (!cancelled) {
|
|
3359
|
+
setQueueWakeVersion((version) => version + 1);
|
|
3360
|
+
}
|
|
3361
|
+
}, ACTIVE_RUN_CLEAR_RETRY_DELAY_MS);
|
|
3362
|
+
return;
|
|
3363
|
+
}
|
|
3334
3364
|
if (queueStopVersionRef.current !== stopVersion ||
|
|
3335
3365
|
queuedMessagesRef.current[0]?.id !== next.id) {
|
|
3336
3366
|
return;
|
|
@@ -3391,6 +3421,8 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3391
3421
|
return () => {
|
|
3392
3422
|
cancelled = true;
|
|
3393
3423
|
window.clearTimeout(timer);
|
|
3424
|
+
if (retryTimer !== null)
|
|
3425
|
+
window.clearTimeout(retryTimer);
|
|
3394
3426
|
if (!started) {
|
|
3395
3427
|
dequeueInFlightRef.current = false;
|
|
3396
3428
|
}
|
|
@@ -12,10 +12,12 @@ export interface ConnectBuilderCardProps {
|
|
|
12
12
|
/** The user's feature/change request, forwarded to the selected coding
|
|
13
13
|
* agent when they click Send. Empty for generic "connect Builder" prompts. */
|
|
14
14
|
prompt?: string;
|
|
15
|
+
/** Formatted staged chat context forwarded with the Builder request. */
|
|
16
|
+
context?: string;
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* Rich inline card rendered for the `connect-builder` tool call. Shows the
|
|
18
20
|
* Builder handoff when available, or routes local development requests to the
|
|
19
21
|
* external coding agent.
|
|
20
22
|
*/
|
|
21
|
-
export declare function ConnectBuilderCard({ configured: initialConfigured, builderEnabled: initialBuilderEnabled, connectUrl: initialConnectUrl, orgName: initialOrgName, prompt, }: ConnectBuilderCardProps): React.JSX.Element;
|
|
23
|
+
export declare function ConnectBuilderCard({ configured: initialConfigured, builderEnabled: initialBuilderEnabled, connectUrl: initialConnectUrl, orgName: initialOrgName, prompt, context, }: ConnectBuilderCardProps): React.JSX.Element;
|
|
@@ -30,7 +30,7 @@ function hasElectronShellBridge() {
|
|
|
30
30
|
* Builder handoff when available, or routes local development requests to the
|
|
31
31
|
* external coding agent.
|
|
32
32
|
*/
|
|
33
|
-
export function ConnectBuilderCard({ configured: initialConfigured, builderEnabled: initialBuilderEnabled = true, connectUrl: initialConnectUrl, orgName: initialOrgName, prompt = "", }) {
|
|
33
|
+
export function ConnectBuilderCard({ configured: initialConfigured, builderEnabled: initialBuilderEnabled = true, connectUrl: initialConnectUrl, orgName: initialOrgName, prompt = "", context = "", }) {
|
|
34
34
|
// The connect-poll state machine is shared — the tool-call result is
|
|
35
35
|
// frozen at render time, so the hook's mount-time fetch + focus refresh
|
|
36
36
|
// is what catches a flow the user completed in another tab.
|
|
@@ -89,7 +89,10 @@ export function ConnectBuilderCard({ configured: initialConfigured, builderEnabl
|
|
|
89
89
|
const res = await fetch(new URL(agentNativePath("/_agent-native/builder/run"), origin).href, {
|
|
90
90
|
method: "POST",
|
|
91
91
|
headers: { "Content-Type": "application/json" },
|
|
92
|
-
body: JSON.stringify({
|
|
92
|
+
body: JSON.stringify({
|
|
93
|
+
prompt,
|
|
94
|
+
...(context.trim() ? { context } : {}),
|
|
95
|
+
}),
|
|
93
96
|
});
|
|
94
97
|
const data = await res.json().catch(() => ({}));
|
|
95
98
|
if (!res.ok) {
|
|
@@ -108,7 +111,7 @@ export function ConnectBuilderCard({ configured: initialConfigured, builderEnabl
|
|
|
108
111
|
setSendErr(e instanceof Error ? e.message : "Send failed");
|
|
109
112
|
setSending(false);
|
|
110
113
|
}
|
|
111
|
-
}, [prompt]);
|
|
114
|
+
}, [context, prompt]);
|
|
112
115
|
const handleJoinWaitlist = useCallback(async () => {
|
|
113
116
|
setJoiningWaitlist(true);
|
|
114
117
|
setWaitlistErr(null);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentNativeDeploymentEnvironment, AgentNativeConfig } from "../config.js";
|
|
2
|
-
export { BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, type EnvironmentBadgeTargets, } from "../shared/environment-lanes.js";
|
|
2
|
+
export { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, type EnvironmentBadgeTargets, } from "../shared/environment-lanes.js";
|
|
3
3
|
export declare function isBuilderIoEmployee(email: string | null | undefined): boolean;
|
|
4
4
|
export declare function isAgentNativeDesktopUserAgent(userAgent: string | undefined): boolean;
|
|
5
5
|
export declare function resolveEnvironmentChannel(config: AgentNativeConfig, hostname: string | undefined): Extract<AgentNativeDeploymentEnvironment, "local" | "beta" | "production"> | null;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Button } from "@agent-native/toolkit/ui/button";
|
|
3
3
|
import { Popover, PopoverContent, PopoverTrigger, } from "@agent-native/toolkit/ui/popover";
|
|
4
|
-
import { useEffect, useMemo, useRef } from "react";
|
|
5
|
-
import { BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
|
|
4
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
|
|
6
6
|
import { trackEvent } from "./analytics.js";
|
|
7
7
|
import { injectedAgentNativeConfig } from "./app-config.js";
|
|
8
8
|
import { useSession } from "./use-session.js";
|
|
9
9
|
import { cn } from "./utils.js";
|
|
10
|
-
export { BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
|
|
10
|
+
export { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
|
|
11
11
|
export function isBuilderIoEmployee(email) {
|
|
12
12
|
return email?.trim().toLowerCase().endsWith("@builder.io") ?? false;
|
|
13
13
|
}
|
|
@@ -50,6 +50,29 @@ function readBetaOptOutUntil(now = Date.now()) {
|
|
|
50
50
|
}
|
|
51
51
|
return null;
|
|
52
52
|
}
|
|
53
|
+
function rememberForcedProductionSession(sourceHref) {
|
|
54
|
+
let forcedByQuery = false;
|
|
55
|
+
try {
|
|
56
|
+
forcedByQuery =
|
|
57
|
+
new URL(sourceHref).searchParams.get(BETA_FORCE_QUERY_PARAM) === "true";
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// coercion-ok: the browser supplied an invalid location.
|
|
61
|
+
}
|
|
62
|
+
if (typeof window === "undefined")
|
|
63
|
+
return forcedByQuery;
|
|
64
|
+
try {
|
|
65
|
+
if (forcedByQuery) {
|
|
66
|
+
window.sessionStorage.setItem(BETA_FORCE_SESSION_STORAGE_KEY, "1");
|
|
67
|
+
}
|
|
68
|
+
return (forcedByQuery ||
|
|
69
|
+
window.sessionStorage.getItem(BETA_FORCE_SESSION_STORAGE_KEY) === "1");
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// coercion-ok: session storage is optional; the current URL remains authoritative.
|
|
73
|
+
return forcedByQuery;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
53
76
|
function consumeBetaOptOutQueryParam(sourceHref, now = Date.now()) {
|
|
54
77
|
let target;
|
|
55
78
|
try {
|
|
@@ -81,8 +104,11 @@ function EnvironmentLink({ label, href }) {
|
|
|
81
104
|
return (_jsx(Button, { asChild: true, className: "w-full justify-center", size: "sm", variant: "outline", children: _jsx("a", { href: href, children: label }) }));
|
|
82
105
|
}
|
|
83
106
|
function EnvironmentBadgeContent({ environment, targets, }) {
|
|
107
|
+
const [isHidden, setIsHidden] = useState(false);
|
|
84
108
|
if (typeof window === "undefined")
|
|
85
109
|
return null;
|
|
110
|
+
if (isHidden)
|
|
111
|
+
return null;
|
|
86
112
|
const currentHref = window.location.href;
|
|
87
113
|
const betaHref = buildEnvironmentUrl(currentHref, targets.betaHost);
|
|
88
114
|
const productionHref = buildEnvironmentOptOutUrl(currentHref, targets.productionHost);
|
|
@@ -94,7 +120,7 @@ function EnvironmentBadgeContent({ environment, targets, }) {
|
|
|
94
120
|
: "You're on Agent Native Production";
|
|
95
121
|
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { "aria-label": `Open ${title.toLowerCase()} switcher`, className: cn(environmentBadgePlacementClasses, environment === "beta"
|
|
96
122
|
? "border-primary/80"
|
|
97
|
-
: "border-border/80 bg-background/95 text-foreground"), size: "sm", variant: environment === "beta" ? "default" : "outline", children: label }) }), _jsxs(PopoverContent, { align: "start", className: "w-[280px] p-5", side: "top", sideOffset: 8, children: [_jsx("div", { className: "mb-1 text-sm font-semibold leading-5", children: title }), _jsx("div", { className: "mb-4 text-sm text-muted-foreground", children: "Choose where you want to continue." }),
|
|
123
|
+
: "border-border/80 bg-background/95 text-foreground"), size: "sm", variant: environment === "beta" ? "default" : "outline", children: label }) }), _jsxs(PopoverContent, { align: "start", className: "w-[280px] p-5", side: "top", sideOffset: 8, children: [_jsx("div", { className: "mb-1 text-sm font-semibold leading-5", children: title }), _jsx("div", { className: "mb-4 text-sm text-muted-foreground", children: "Choose where you want to continue." }), _jsxs("div", { className: "grid gap-2", children: [environment === "beta" ? (_jsx(EnvironmentLink, { href: productionHref, label: "Switch to production" })) : (_jsx(EnvironmentLink, { href: betaHref, label: "Go to beta" })), _jsx(Button, { className: "mt-2 -mb-2 w-full justify-center text-muted-foreground", onClick: () => setIsHidden(true), size: "sm", type: "button", variant: "ghost", children: "Hide badge" })] })] })] }));
|
|
98
124
|
}
|
|
99
125
|
function LocalEnvironmentBadge() {
|
|
100
126
|
return (_jsx("div", { "aria-label": "Local development environment", className: cn(environmentBadgePlacementClasses, "inline-flex items-center justify-center border border-border/80 bg-background/95 text-foreground"), role: "status", children: "dev" }));
|
|
@@ -107,6 +133,10 @@ function ProductionEnvironmentBadge({ targets, }) {
|
|
|
107
133
|
isBuilderIoEmployee(session?.email);
|
|
108
134
|
const didAutoRedirect = useRef(false);
|
|
109
135
|
useEffect(() => {
|
|
136
|
+
if (typeof window === "undefined")
|
|
137
|
+
return;
|
|
138
|
+
if (rememberForcedProductionSession(window.location.href))
|
|
139
|
+
return;
|
|
110
140
|
if (!isEligible || didAutoRedirect.current) {
|
|
111
141
|
return;
|
|
112
142
|
}
|
|
@@ -140,11 +170,16 @@ function ProductionEnvironmentBadge({ targets, }) {
|
|
|
140
170
|
* lane for authenticated staff.
|
|
141
171
|
*/
|
|
142
172
|
export function EnvironmentBadge({ showProduction = true, } = {}) {
|
|
173
|
+
const [hydrated, setHydrated] = useState(false);
|
|
143
174
|
const config = useMemo(injectedAgentNativeConfig, []);
|
|
144
175
|
const hostname = typeof window === "undefined" ? undefined : window.location.hostname;
|
|
145
176
|
const environment = resolveEnvironmentChannel(config, hostname);
|
|
146
177
|
const targets = resolveEnvironmentTargets(hostname);
|
|
147
|
-
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
setHydrated(true);
|
|
180
|
+
}, []);
|
|
181
|
+
if (!hydrated ||
|
|
182
|
+
typeof window === "undefined" ||
|
|
148
183
|
window.parent !== window ||
|
|
149
184
|
!environment) {
|
|
150
185
|
return null;
|
|
@@ -71,4 +71,4 @@ export type MultiTabAssistantChatProps = Omit<AssistantChatProps, "tabId" | "thr
|
|
|
71
71
|
/** Cadence for hydrating agent-team sub-agent tab status. Default: 3000. */
|
|
72
72
|
agentTeamPollMs?: number;
|
|
73
73
|
};
|
|
74
|
-
export declare function MultiTabAssistantChat({ showTabBar, renderHeader, renderOverlay, contentHidden, apiUrl, storageKey, restoreActiveThread, browserTabId, threadUrlSync, scope, isolateHistoryByScope, agentTeamPollMs, ...props }: MultiTabAssistantChatProps): React.JSX.Element;
|
|
74
|
+
export declare function MultiTabAssistantChat({ showTabBar, renderHeader, renderOverlay, contentHidden, apiUrl, storageKey, restoreActiveThread, browserTabId, threadUrlSync, scope, isolateHistoryByScope, agentTeamPollMs, availableModels: hostAvailableModels, modelListLoading: hostModelListLoading, onModelChange: hostOnModelChange, ...props }: MultiTabAssistantChatProps): React.JSX.Element;
|
|
@@ -17,7 +17,7 @@ import { DEFAULT_LOCALE, useOptionalLocale, useT } from "./i18n.js";
|
|
|
17
17
|
import { RunStuckBanner } from "./RunStuckBanner.js";
|
|
18
18
|
import { callAction } from "./use-action.js";
|
|
19
19
|
import { useChangeVersion } from "./use-change-version.js";
|
|
20
|
-
import { CHAT_MODEL_SELECTION_CHANGED_EVENT } from "./use-chat-models.js";
|
|
20
|
+
import { CHAT_MODEL_SELECTION_CHANGED_EVENT, chatModelSelectionStorageKey, } from "./use-chat-models.js";
|
|
21
21
|
import { useChatThreads, } from "./use-chat-threads.js";
|
|
22
22
|
import { usePollLoop } from "./use-poll-loop.js";
|
|
23
23
|
import { cn } from "./utils.js";
|
|
@@ -43,7 +43,6 @@ function deliverPendingSend(ref, send) {
|
|
|
43
43
|
ref.sendMessage(send.message, send.images);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
const MODEL_SELECTION_STORAGE_KEY = "agent-native:chat-models:selection";
|
|
47
46
|
function readStoredModelSelection(key) {
|
|
48
47
|
if (typeof window === "undefined")
|
|
49
48
|
return undefined;
|
|
@@ -402,7 +401,7 @@ function runToAgentTeamTabInfo(run) {
|
|
|
402
401
|
status: run.status ?? "unknown",
|
|
403
402
|
};
|
|
404
403
|
}
|
|
405
|
-
export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderOverlay, contentHidden = false, apiUrl = agentNativePath("/_agent-native/agent-chat"), storageKey, restoreActiveThread = true, browserTabId, threadUrlSync = false, scope = null, isolateHistoryByScope = false, agentTeamPollMs = DEFAULT_AGENT_TEAM_POLL_MS, ...props }) {
|
|
404
|
+
export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderOverlay, contentHidden = false, apiUrl = agentNativePath("/_agent-native/agent-chat"), storageKey, restoreActiveThread = true, browserTabId, threadUrlSync = false, scope = null, isolateHistoryByScope = false, agentTeamPollMs = DEFAULT_AGENT_TEAM_POLL_MS, availableModels: hostAvailableModels, modelListLoading: hostModelListLoading, onModelChange: hostOnModelChange, ...props }) {
|
|
406
405
|
const translate = useT();
|
|
407
406
|
const contextNamespace = scope
|
|
408
407
|
? scope.contextKey?.trim() || `scope:${scope.type}:${scope.id}`
|
|
@@ -528,7 +527,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
528
527
|
}, [switchThreadState, writeThreadUrl]);
|
|
529
528
|
// Namespace all localStorage keys by storageKey when provided (for per-app isolation in frame)
|
|
530
529
|
const keyPrefix = storageKey ? `:${storageKey}` : "";
|
|
531
|
-
const modelSelectionKey =
|
|
530
|
+
const modelSelectionKey = chatModelSelectionStorageKey(storageKey);
|
|
532
531
|
// Track which tabs have been focused at least once (lazy mount for sub-agent tabs)
|
|
533
532
|
const mountedTabsRef = useRef(new Set());
|
|
534
533
|
const activeThreadIdRef = useRef(activeThreadId);
|
|
@@ -557,8 +556,16 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
557
556
|
setPageOverlayScrolled(target.scrollTop > 1);
|
|
558
557
|
}, [renderOverlay]);
|
|
559
558
|
// ─── Model state ─────────────────────────────────────────────────────────
|
|
560
|
-
|
|
561
|
-
|
|
559
|
+
// A host that supplies its own catalog owns the whole picker: the server
|
|
560
|
+
// catalog must not be discovered or merged, or a host with no engine of its
|
|
561
|
+
// own silently gets this app's models instead.
|
|
562
|
+
const hostManagedModels = hostAvailableModels !== undefined;
|
|
563
|
+
const [discoveredModels, setDiscoveredModels] = useState([]);
|
|
564
|
+
const availableModels = hostAvailableModels ?? discoveredModels;
|
|
565
|
+
const [discoveredModelsLoading, setModelListLoading] = useState(true);
|
|
566
|
+
const modelListLoading = hostManagedModels
|
|
567
|
+
? (hostModelListLoading ?? false)
|
|
568
|
+
: discoveredModelsLoading;
|
|
562
569
|
const [defaultModel, setDefaultModel] = useState(DEFAULT_MODEL);
|
|
563
570
|
const threadModelRef = useRef(new Map());
|
|
564
571
|
const [persistedModelSelection, setPersistedModelSelection] = useState(() => readStoredModelSelection(modelSelectionKey));
|
|
@@ -666,6 +673,14 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
666
673
|
persistModelSelection,
|
|
667
674
|
props.selectedAgent,
|
|
668
675
|
]);
|
|
676
|
+
// A host that owns the model list still needs the internal selection updated:
|
|
677
|
+
// `selectedModel`/`selectedEngine` render from it and submitted turns read it,
|
|
678
|
+
// so routing a pick only to the host snaps the picker back to the previous
|
|
679
|
+
// model and sends that one.
|
|
680
|
+
const handleModelChangeWithHost = useCallback((model, engine) => {
|
|
681
|
+
handleModelChange(model, engine);
|
|
682
|
+
hostOnModelChange?.(model, engine);
|
|
683
|
+
}, [handleModelChange, hostOnModelChange]);
|
|
669
684
|
const handleEffortChange = useCallback((effort) => {
|
|
670
685
|
const threadId = activeThreadIdRef.current;
|
|
671
686
|
if (!threadId)
|
|
@@ -689,15 +704,19 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
689
704
|
resolveThreadModelSelection,
|
|
690
705
|
]);
|
|
691
706
|
useEffect(() => {
|
|
692
|
-
const preferredAgentModel = props.selectedAgent
|
|
693
|
-
? resolvePreferredAgentModel(props.selectedAgent, availableModels)
|
|
694
|
-
: undefined;
|
|
695
|
-
if (!preferredAgentModel)
|
|
696
|
-
return;
|
|
697
707
|
const threadId = activeThreadIdRef.current;
|
|
698
708
|
const current = threadId
|
|
699
709
|
? resolveThreadModelSelection(threadId)
|
|
700
710
|
: persistedModelSelection;
|
|
711
|
+
// Only correct a selection the agent cannot run. This effect re-runs on
|
|
712
|
+
// every selection change, so an unconditional rewrite pins the picker and
|
|
713
|
+
// each later user pick snaps straight back.
|
|
714
|
+
const preferredAgentModel = isClaudeCodeAgentId(props.selectedAgent) &&
|
|
715
|
+
isLunaModel(current?.model ?? "")
|
|
716
|
+
? resolvePreferredAgentModel(props.selectedAgent, availableModels)
|
|
717
|
+
: undefined;
|
|
718
|
+
if (!preferredAgentModel)
|
|
719
|
+
return;
|
|
701
720
|
if (current?.model === preferredAgentModel.model &&
|
|
702
721
|
current.engine === preferredAgentModel.engine) {
|
|
703
722
|
return;
|
|
@@ -721,6 +740,8 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
721
740
|
resolveThreadModelSelection,
|
|
722
741
|
]);
|
|
723
742
|
const refreshEngines = useCallback(() => {
|
|
743
|
+
if (hostManagedModels)
|
|
744
|
+
return;
|
|
724
745
|
setModelListLoading(true);
|
|
725
746
|
Promise.all([
|
|
726
747
|
callAction("manage-agent-engine", { action: "list" }).catch(() => null),
|
|
@@ -751,12 +772,12 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
751
772
|
currentEngineName,
|
|
752
773
|
currentModel,
|
|
753
774
|
});
|
|
754
|
-
|
|
775
|
+
setDiscoveredModels(groups);
|
|
755
776
|
setDefaultModel(currentModel ?? DEFAULT_MODEL);
|
|
756
777
|
})
|
|
757
778
|
.catch(() => { })
|
|
758
779
|
.finally(() => setModelListLoading(false));
|
|
759
|
-
}, []);
|
|
780
|
+
}, [hostManagedModels]);
|
|
760
781
|
useEffect(() => {
|
|
761
782
|
refreshEngines();
|
|
762
783
|
window.addEventListener("agent-engine:configured-changed", refreshEngines);
|
|
@@ -1976,7 +1997,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
1976
1997
|
? clearActiveTab
|
|
1977
1998
|
: undefined, isThreadStateLoading: isLoading, onMessageCountChange: (count) => setMessageCounts((prev) => prev[tabId] === count
|
|
1978
1999
|
? prev
|
|
1979
|
-
: { ...prev, [tabId]: count }), onSaveThread: handleSaveThread, onGenerateTitle: handleGenerateTitle, onSlashCommand: handleSlashCommand, selectedModel: modelSelection?.model, selectedEngine: modelSelection?.engine, selectedEffort: modelSelection?.effort ?? DEFAULT_REASONING_EFFORT, composerSlot: props.composerSlot, defaultModel: defaultModel, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange:
|
|
2000
|
+
: { ...prev, [tabId]: count }), onSaveThread: handleSaveThread, onGenerateTitle: handleGenerateTitle, onSlashCommand: handleSlashCommand, selectedModel: modelSelection?.model, selectedEngine: modelSelection?.engine, selectedEffort: modelSelection?.effort ?? DEFAULT_REASONING_EFFORT, composerSlot: props.composerSlot, defaultModel: defaultModel, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange: handleModelChangeWithHost, onEffortChange: handleEffortChange, onForkChat: () => handleForkChat(tabId),
|
|
1980
2001
|
// Sub-agent tabs are read-only: sending a new message from the
|
|
1981
2002
|
// sub-agent tab would start a fresh run on that thread and kill
|
|
1982
2003
|
// the in-flight team chunk. Disable the composer and show a
|
|
@@ -11,7 +11,7 @@ export { buildRepositoryFromCodeAgentTranscript, type BuildRepositoryFromCodeAge
|
|
|
11
11
|
export { compareCodeAgentTranscriptEvents, getCodeAgentTranscriptSeq, isCodeAgentRunActive, mergeCodeAgentTranscriptEvents, type CodeAgentRunStateLike, type CodeAgentTranscriptOrderEvent, } from "../../code-agents/transcript-order.js";
|
|
12
12
|
export { CREDENTIAL_GAP_SIGNAL, isCredentialGapCodeAgentEvent, } from "../../code-agents/transcript-normalizer.js";
|
|
13
13
|
export { useSendToAgentChat } from "../use-send-to-agent-chat.js";
|
|
14
|
-
export { useChatModels, type UseChatModelsResult, type EngineModelGroup, } from "../use-chat-models.js";
|
|
14
|
+
export { chatModelSelectionStorageKey, useChatModels, type UseChatModelsResult, type EngineModelGroup, } from "../use-chat-models.js";
|
|
15
15
|
export { CodeRequiredDialog, type CodeRequiredDialogProps, } from "../components/CodeRequiredDialog.js";
|
|
16
16
|
export { ChatFirstAgentActivityPanel, type ChatFirstAgentActivityPanelProps, } from "../chat-first-agent-activity.js";
|
|
17
17
|
export { ChatFirstSurfacePanelToggle } from "../chat-first-surface-panel-toggle.js";
|
|
@@ -11,7 +11,7 @@ export { buildRepositoryFromCodeAgentTranscript, } from "../../agent/thread-data
|
|
|
11
11
|
export { compareCodeAgentTranscriptEvents, getCodeAgentTranscriptSeq, isCodeAgentRunActive, mergeCodeAgentTranscriptEvents, } from "../../code-agents/transcript-order.js";
|
|
12
12
|
export { CREDENTIAL_GAP_SIGNAL, isCredentialGapCodeAgentEvent, } from "../../code-agents/transcript-normalizer.js";
|
|
13
13
|
export { useSendToAgentChat } from "../use-send-to-agent-chat.js";
|
|
14
|
-
export { useChatModels, } from "../use-chat-models.js";
|
|
14
|
+
export { chatModelSelectionStorageKey, useChatModels, } from "../use-chat-models.js";
|
|
15
15
|
export { CodeRequiredDialog, } from "../components/CodeRequiredDialog.js";
|
|
16
16
|
export { ChatFirstAgentActivityPanel, } from "../chat-first-agent-activity.js";
|
|
17
17
|
export { ChatFirstSurfacePanelToggle } from "../chat-first-surface-panel-toggle.js";
|
|
@@ -57,7 +57,8 @@ export type ManageJobInput = {
|
|
|
57
57
|
};
|
|
58
58
|
export type ManageAutomationInput = ManageJobInput;
|
|
59
59
|
export interface RunAutomationNowInput {
|
|
60
|
-
name
|
|
60
|
+
name?: string;
|
|
61
|
+
path?: string;
|
|
61
62
|
scope: "personal" | "organization";
|
|
62
63
|
}
|
|
63
64
|
export interface RunAutomationNowResult {
|
|
@@ -87,12 +87,10 @@ export function useRunAutomationNow() {
|
|
|
87
87
|
return useActionMutation("run-automation-now", {
|
|
88
88
|
onSuccess: (_result, variables) => {
|
|
89
89
|
const scope = variables.scope === "organization" ? "organization" : "personal";
|
|
90
|
+
const name = variables.name ??
|
|
91
|
+
variables.path?.replace(/^jobs\//, "").replace(/\.md$/, "");
|
|
90
92
|
queryClient.invalidateQueries({
|
|
91
|
-
queryKey: [
|
|
92
|
-
"action",
|
|
93
|
-
"list-automation-runs",
|
|
94
|
-
{ scope, name: variables.name },
|
|
95
|
-
],
|
|
93
|
+
queryKey: ["action", "list-automation-runs", { scope, name }],
|
|
96
94
|
});
|
|
97
95
|
queryClient.invalidateQueries({
|
|
98
96
|
queryKey: ["action", "list-automations", { scope }],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, } from "../shared/agent-sidebar-url.js";
|
|
1
|
+
import { AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, AGENT_SIDEBAR_QUERY_VALUE_OPEN, } from "../shared/agent-sidebar-url.js";
|
|
2
2
|
import { hasChatThreadDeepLink } from "./chat-thread-url.js";
|
|
3
3
|
export { hasChatThreadDeepLink } from "./chat-thread-url.js";
|
|
4
4
|
export const SIDEBAR_OPEN_KEY = "agent-native-sidebar-open";
|
|
@@ -62,6 +62,8 @@ export function getAgentSidebarUrlOpenOverride() {
|
|
|
62
62
|
const value = url.searchParams.get(AGENT_SIDEBAR_QUERY_PARAM);
|
|
63
63
|
if (value === AGENT_SIDEBAR_QUERY_VALUE_CLOSED)
|
|
64
64
|
return false;
|
|
65
|
+
if (value === AGENT_SIDEBAR_QUERY_VALUE_OPEN)
|
|
66
|
+
return true;
|
|
65
67
|
}
|
|
66
68
|
catch { }
|
|
67
69
|
return null;
|
|
@@ -273,4 +273,9 @@ export const codeTabsBlock = defineBlock({
|
|
|
273
273
|
label: "Code tabs",
|
|
274
274
|
icon: IconCode,
|
|
275
275
|
description: "A vertical file tab rail of syntax-highlighted code snippets, one tab per file with an optional language and caption.",
|
|
276
|
+
// `tabs` has schema min(1), so a fresh insert needs one starter tab — same
|
|
277
|
+
// shape `addTab` mints for a second tab.
|
|
278
|
+
empty: () => ({
|
|
279
|
+
tabs: [{ id: newCodeTabId(), label: "file-1.ts", code: "" }],
|
|
280
|
+
}),
|
|
276
281
|
});
|
|
@@ -131,4 +131,5 @@ export const codeBlock = defineBlock({
|
|
|
131
131
|
label: "Code",
|
|
132
132
|
icon: IconCode,
|
|
133
133
|
description: "A single syntax-highlighted code snippet, Notion-style: one border, a hover language switcher + copy, and collapse-to-N lines. Put several in a `tabs` block for a file rail.",
|
|
134
|
+
empty: () => ({ code: "" }),
|
|
134
135
|
});
|
|
@@ -115,6 +115,13 @@ export declare function shouldShowMissingFinalResponse({ isCurrentTurnRunning, s
|
|
|
115
115
|
hasActiveTool?: boolean;
|
|
116
116
|
userStoppedRun?: boolean;
|
|
117
117
|
}): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* "The agent stopped" is derived from local client state, which dips to
|
|
120
|
+
* not-running at every chunk boundary and transport re-attach while the turn is
|
|
121
|
+
* still alive server-side. Requiring the shape to hold for a beat keeps the
|
|
122
|
+
* notice off the screen for those gaps without hiding a real stop for long.
|
|
123
|
+
*/
|
|
124
|
+
export declare const MISSING_FINAL_RESPONSE_SETTLE_MS = 3000;
|
|
118
125
|
export declare function useSettledFlag(active: boolean, delayMs: number): boolean;
|
|
119
126
|
export declare function shouldShowAssistantWorkSummary({ isLast, isComplete, hasCollapsibleWork, hasUnresolvedTool, hasActiveTool, chatRunning, }: {
|
|
120
127
|
isLast: boolean;
|
|
@@ -728,7 +728,7 @@ export function shouldShowMissingFinalResponse({ isCurrentTurnRunning, serverRun
|
|
|
728
728
|
* still alive server-side. Requiring the shape to hold for a beat keeps the
|
|
729
729
|
* notice off the screen for those gaps without hiding a real stop for long.
|
|
730
730
|
*/
|
|
731
|
-
const MISSING_FINAL_RESPONSE_SETTLE_MS =
|
|
731
|
+
export const MISSING_FINAL_RESPONSE_SETTLE_MS = 3_000;
|
|
732
732
|
export function useSettledFlag(active, delayMs) {
|
|
733
733
|
const [settled, setSettled] = useState(false);
|
|
734
734
|
useEffect(() => {
|
|
@@ -120,6 +120,9 @@ function isMissingLlmProviderRunError(info) {
|
|
|
120
120
|
((code === "missing_credentials" || code === "missing_api_key") &&
|
|
121
121
|
!text.trim()));
|
|
122
122
|
}
|
|
123
|
+
function isDesktopChatRelayRunError(info) {
|
|
124
|
+
return [info.message, info.details].some((value) => typeof value === "string" && /desktop app chat relay failed/i.test(value));
|
|
125
|
+
}
|
|
123
126
|
// ─── BuilderConnectCta ────────────────────────────────────────────────────────
|
|
124
127
|
// Renders a single row with left-aligned copy and a right-aligned action.
|
|
125
128
|
// Click opens the Builder OAuth popup via the shared
|
|
@@ -210,7 +213,7 @@ export function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDism
|
|
|
210
213
|
});
|
|
211
214
|
const canRecover = info.recoverable === true;
|
|
212
215
|
const shouldShowBuilderReconnect = isBuilderReconnectRunError(info);
|
|
213
|
-
const
|
|
216
|
+
const shouldShowProviderSetup = isMissingLlmProviderRunError(info) || isDesktopChatRelayRunError(info);
|
|
214
217
|
const isProviderAuthError = isProviderAuthenticationError([info.message, info.details].filter(Boolean).join("\n"), info.errorCode);
|
|
215
218
|
// Blocked on something the reader goes and fixes elsewhere, then comes back
|
|
216
219
|
// to. Recoverable runs and email verification keep a retry path; rejected
|
|
@@ -292,7 +295,7 @@ export function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDism
|
|
|
292
295
|
onDismiss();
|
|
293
296
|
}
|
|
294
297
|
}, [builderReconnectResolved, onDismiss]);
|
|
295
|
-
if (
|
|
298
|
+
if (shouldShowProviderSetup) {
|
|
296
299
|
return (_jsxs("div", { className: "w-full", children: [_jsx(BuilderSetupCard, { fullWidth: true, layout: "sidebar", onConnected: handleMissingProviderConnected }), providerConnected ? (_jsx("div", { className: "flex justify-center px-3 pt-1", children: _jsxs("button", { type: "button", onClick: handleMissingProviderRetry, disabled: retryRequested, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90 disabled:cursor-wait disabled:opacity-60", children: [_jsx(IconRefresh, { size: 13 }), t("agentChat.common.retry")] }) })) : null] }));
|
|
297
300
|
}
|
|
298
301
|
return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] p-3 text-sm", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-700 dark:text-amber-300", children: _jsx(IconAlertTriangle, { size: 14 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-foreground", children: runErrorHeadline(info, {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { IconLoader2, IconAlertTriangle, IconCircleX, IconCheck, IconChevronRight, IconCopy, IconCode, IconBrandSlack, IconTerminal2, IconDatabase, IconSearch, IconFileCode, IconShieldCheck, IconX, } from "@tabler/icons-react";
|
|
3
3
|
import React, { useState, useEffect, useCallback, useLayoutEffect, useRef, } from "react";
|
|
4
|
+
import { formatAgentChatContextItemsForPrompt } from "../agent-chat.js";
|
|
4
5
|
import { AgentTaskCard } from "../AgentTaskCard.js";
|
|
5
6
|
import { writeClipboardText } from "../clipboard.js";
|
|
6
7
|
import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
|
|
@@ -12,6 +13,7 @@ import { findMcpIntegrationForToolName } from "../resources/mcp-integration-cata
|
|
|
12
13
|
import { McpIntegrationLogo } from "../resources/McpIntegrationLogo.js";
|
|
13
14
|
import { BashCell, EditCell, WriteCell, FilesChangedSummary, } from "../tool-cells/index.js";
|
|
14
15
|
import { humanizeToolName, isCallAgentToolCallShadowed, isToolCallActive, } from "../tool-display.js";
|
|
16
|
+
import { useAgentChatContext } from "../use-agent-chat-context.js";
|
|
15
17
|
import { cn } from "../utils.js";
|
|
16
18
|
import { ActionChatUiSurface } from "./action-chat-ui-surface.js";
|
|
17
19
|
import { SmoothMarkdownText, HighlightedCodeBlock, } from "./markdown-renderer.js";
|
|
@@ -280,6 +282,10 @@ function ApprovalAffordance({ toolName, toolCallId, approval, }) {
|
|
|
280
282
|
}
|
|
281
283
|
// ─── ToolCallDisplay ──────────────────────────────────────────────────────────
|
|
282
284
|
export function ToolCallDisplay({ toolName, toolCallId, argsText, args, result, mcpApp, chatUI, isRunning, outcome, structuredMeta, activity, approval, repeatCount, isLatestRunning = isRunning, isActiveTail, }) {
|
|
285
|
+
const { items: agentChatContextItems } = useAgentChatContext(toolName === "connect-builder");
|
|
286
|
+
const builderContext = toolName === "connect-builder"
|
|
287
|
+
? formatAgentChatContextItemsForPrompt(agentChatContextItems)
|
|
288
|
+
: "";
|
|
283
289
|
const isDelegatedAgentCall = toolName === "call-agent" || toolName.startsWith("agent:");
|
|
284
290
|
const effectiveIsRunning = isRunning ||
|
|
285
291
|
(isDelegatedAgentCall &&
|
|
@@ -306,9 +312,9 @@ export function ToolCallDisplay({ toolName, toolCallId, argsText, args, result,
|
|
|
306
312
|
if (toolKind === "write") {
|
|
307
313
|
return wrapToolDisplay(_jsx(WriteCell, { meta: structuredMeta, isRunning: effectiveIsRunning }));
|
|
308
314
|
}
|
|
309
|
-
return wrapToolDisplay(_jsx(ToolCallDisplayGeneric, { toolName: toolName, toolCallId: toolCallId, argsText: argsText, args: args, result: result, mcpApp: mcpApp, chatUI: chatUI, isRunning: effectiveIsRunning, outcome: outcome, isActiveTail: showActiveTail, structuredMeta: structuredMeta, approval: approval, repeatCount: repeatCount }));
|
|
315
|
+
return wrapToolDisplay(_jsx(ToolCallDisplayGeneric, { toolName: toolName, toolCallId: toolCallId, argsText: argsText, args: args, result: result, mcpApp: mcpApp, chatUI: chatUI, isRunning: effectiveIsRunning, outcome: outcome, isActiveTail: showActiveTail, structuredMeta: structuredMeta, approval: approval, repeatCount: repeatCount, context: builderContext }));
|
|
310
316
|
}
|
|
311
|
-
function ToolCallDisplayGeneric({ toolName, toolCallId, argsText, args, result, mcpApp, chatUI, isRunning, outcome, isActiveTail, structuredMeta, approval, repeatCount, }) {
|
|
317
|
+
function ToolCallDisplayGeneric({ toolName, toolCallId, argsText, args, result, mcpApp, chatUI, isRunning, outcome, isActiveTail, structuredMeta, approval, repeatCount, context, }) {
|
|
312
318
|
const t = useT();
|
|
313
319
|
const suppressInlineOpenApp = React.useContext(SuppressInlineOpenAppContext);
|
|
314
320
|
const isRawCallAgent = toolName === "call-agent";
|
|
@@ -339,7 +345,7 @@ function ToolCallDisplayGeneric({ toolName, toolCallId, argsText, args, result,
|
|
|
339
345
|
return (_jsx(ConnectBuilderCard, { configured: !!parsed.configured, builderEnabled: parsed.builderEnabled !== false,
|
|
340
346
|
// Ignore obsolete direct-auth URLs from older tool results. The
|
|
341
347
|
// card fetches a fresh app-local connect URL on mount and click.
|
|
342
|
-
connectUrl: parsed.connectUrl || "", orgName: parsed.orgName ?? null, prompt: typeof parsed.prompt === "string" ? parsed.prompt : "" }));
|
|
348
|
+
connectUrl: parsed.connectUrl || "", orgName: parsed.orgName ?? null, prompt: typeof parsed.prompt === "string" ? parsed.prompt : "", context: context }));
|
|
343
349
|
}
|
|
344
350
|
}
|
|
345
351
|
catch {
|