@agent-native/core 0.169.1 → 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/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/app/i18n-data.ts +28 -0
- package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
- 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-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/slack.ts +4 -2
- 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/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/view-screen.ts +8 -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 +1383 -88
- 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/MultiScreenCanvas.tsx +284 -136
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2057 -141
- 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 -1
- 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 +11 -4
- package/corpus/templates/design/app/i18n-data.ts +1 -0
- 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 +77 -35
- package/corpus/templates/design/app/pages/DesignSystems.tsx +136 -42
- package/corpus/templates/design/app/pages/Index.tsx +2 -0
- 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/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-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/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/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-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/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/resources/mcp-integration-catalog.js +0 -29
- 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/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 +19 -0
- package/dist/deploy/build.js +190 -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 +3 -0
- package/dist/localization/core-messages/de-DE.js +3 -0
- package/dist/localization/core-messages/en-US.d.ts +3 -0
- package/dist/localization/core-messages/en-US.js +3 -0
- package/dist/localization/core-messages/es-ES.js +3 -0
- package/dist/localization/core-messages/fr-FR.js +3 -0
- package/dist/localization/core-messages/hi-IN.js +3 -0
- package/dist/localization/core-messages/ja-JP.js +3 -0
- package/dist/localization/core-messages/ko-KR.js +3 -0
- package/dist/localization/core-messages/pt-BR.js +3 -0
- package/dist/localization/core-messages/zh-CN.js +3 -0
- package/dist/localization/core-messages/zh-TW.js +3 -0
- package/dist/localization/core-messages.d.ts +3 -0
- 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/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/routes.d.ts +3 -3
- 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 +1 -1
- package/dist/provider-api/actions/provider-api.d.ts +2 -2
- package/dist/provider-api/index.js +2 -0
- package/dist/resources/store.js +13 -4
- package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
- package/dist/secrets/register-framework-secrets.js +1 -1
- 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-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 +100 -20
- 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/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- 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 +2 -2
- 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
|
@@ -13,7 +13,12 @@ import { decodeOAuthState, encodeOAuthState, getAppUrl, resolveOAuthRedirectUri,
|
|
|
13
13
|
import { runWithRequestContext } from "./request-context.js";
|
|
14
14
|
const SUPPORTED_PROVIDERS = new Set([
|
|
15
15
|
"figma",
|
|
16
|
+
"gmail",
|
|
17
|
+
"google_calendar",
|
|
18
|
+
"google_docs",
|
|
16
19
|
"google_drive",
|
|
20
|
+
"google_sheets",
|
|
21
|
+
"google_slides",
|
|
17
22
|
"github",
|
|
18
23
|
"hubspot",
|
|
19
24
|
"salesforce",
|
|
@@ -26,7 +31,22 @@ const PROVIDER_REQUEST_TIMEOUT_MS = 10_000;
|
|
|
26
31
|
const PROVIDER_RESPONSE_MAX_BYTES = 256 * 1024;
|
|
27
32
|
const SALESFORCE_PRODUCTION_LOGIN_URL = "https://login.salesforce.com";
|
|
28
33
|
const SALESFORCE_SANDBOX_LOGIN_URL = "https://test.salesforce.com";
|
|
29
|
-
const WORKSPACE_OAUTH_ADMIN_ERROR = "
|
|
34
|
+
const WORKSPACE_OAUTH_ADMIN_ERROR = "This shared connection requires organization or app-admin access. Personal connections can be connected by any workspace member.";
|
|
35
|
+
export function isWorkspaceProviderOAuthScope(value) {
|
|
36
|
+
return value === "user" || value === "organization" || value === "app";
|
|
37
|
+
}
|
|
38
|
+
export function isGoogleWorkspaceOAuthProvider(provider) {
|
|
39
|
+
return (provider === "gmail" ||
|
|
40
|
+
provider === "google_calendar" ||
|
|
41
|
+
provider === "google_docs" ||
|
|
42
|
+
provider === "google_drive" ||
|
|
43
|
+
provider === "google_sheets" ||
|
|
44
|
+
provider === "google_slides");
|
|
45
|
+
}
|
|
46
|
+
export async function hasWorkspaceProviderOAuthCredentials(provider) {
|
|
47
|
+
const [clientId, clientSecret] = await resolveProviderClientCredentials(provider);
|
|
48
|
+
return Boolean(clientId && clientSecret);
|
|
49
|
+
}
|
|
30
50
|
export function workspaceProviderOAuthPath(provider, phase) {
|
|
31
51
|
return `/_agent-native/connections/oauth/${provider}/${phase}`;
|
|
32
52
|
}
|
|
@@ -46,7 +66,14 @@ export async function handleWorkspaceProviderOAuthStart(event, providerId) {
|
|
|
46
66
|
return unauthorized(event);
|
|
47
67
|
const query = getQuery(event);
|
|
48
68
|
const appId = normalizeAppId(text(query.appId) ?? getAppConfig().app.workspaceId ?? "creative-context");
|
|
49
|
-
const
|
|
69
|
+
const requestedScope = parseWorkspaceProviderOAuthScope(text(query.scope));
|
|
70
|
+
if (!requestedScope) {
|
|
71
|
+
setResponseStatus(event, 400);
|
|
72
|
+
return {
|
|
73
|
+
error: "OAuth connection scope must be user, organization, or app.",
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const orgContext = await requireWorkspaceProviderOAuthAccess(event, appId, requestedScope);
|
|
50
77
|
if (!orgContext) {
|
|
51
78
|
return { error: WORKSPACE_OAUTH_ADMIN_ERROR };
|
|
52
79
|
}
|
|
@@ -91,6 +118,7 @@ export async function handleWorkspaceProviderOAuthStart(event, providerId) {
|
|
|
91
118
|
owner: session.email,
|
|
92
119
|
orgId,
|
|
93
120
|
app: appId,
|
|
121
|
+
scope: orgContext.oauthScope,
|
|
94
122
|
returnUrl,
|
|
95
123
|
flowId,
|
|
96
124
|
});
|
|
@@ -102,6 +130,7 @@ export async function handleWorkspaceProviderOAuthStart(event, providerId) {
|
|
|
102
130
|
owner: session.email,
|
|
103
131
|
orgId,
|
|
104
132
|
appId,
|
|
133
|
+
scope: orgContext.oauthScope,
|
|
105
134
|
...(salesforceLoginUrl ? { salesforceLoginUrl } : {}),
|
|
106
135
|
expiresAt: Date.now() + FLOW_TTL_SECONDS * 1_000,
|
|
107
136
|
};
|
|
@@ -134,7 +163,11 @@ export async function handleWorkspaceProviderOAuthCallback(event, providerId) {
|
|
|
134
163
|
if (!session?.email)
|
|
135
164
|
return unauthorized(event);
|
|
136
165
|
const flow = readStoredFlow(event, providerId);
|
|
137
|
-
|
|
166
|
+
if (!flow || !isWorkspaceProviderOAuthScope(flow.scope)) {
|
|
167
|
+
setResponseStatus(event, 400);
|
|
168
|
+
return { error: "OAuth state is invalid or expired." };
|
|
169
|
+
}
|
|
170
|
+
const orgContext = await requireWorkspaceProviderOAuthAccess(event, flow.appId, flow.scope);
|
|
138
171
|
if (!orgContext) {
|
|
139
172
|
return { error: WORKSPACE_OAUTH_ADMIN_ERROR };
|
|
140
173
|
}
|
|
@@ -204,8 +237,12 @@ export async function handleWorkspaceProviderOAuthCallback(event, providerId) {
|
|
|
204
237
|
await saveOAuthTokens(provider.oauth.provider, accountId, tokens, session.email);
|
|
205
238
|
await setOAuthDisplayName(provider.oauth.provider, accountId, identity.label);
|
|
206
239
|
const existing = existingConnections.find((connection) => connection.accountId === accountId &&
|
|
207
|
-
(
|
|
208
|
-
connection.
|
|
240
|
+
(flow.scope === "user"
|
|
241
|
+
? connection.allowedUsers.some((allowedUser) => allowedUser.toLowerCase() === session.email.toLowerCase())
|
|
242
|
+
: flow.scope === "organization"
|
|
243
|
+
? connection.allowedUsers.length === 0 &&
|
|
244
|
+
(connection.allowedUserGroups?.length ?? 0) === 0
|
|
245
|
+
: connection.allowedApps.some((allowedApp) => allowedApp.toLowerCase() === flow.appId.toLowerCase())));
|
|
209
246
|
const scopes = mergeWorkspaceOAuthValues(existing?.scopes ?? [], identity.scopes ?? tokenScopes(tokens, provider.oauth.scopes));
|
|
210
247
|
const connectionConfig = {
|
|
211
248
|
credentialMode: "oauth",
|
|
@@ -229,8 +266,10 @@ export async function handleWorkspaceProviderOAuthCallback(event, providerId) {
|
|
|
229
266
|
accountLabel: identity.label,
|
|
230
267
|
status: "connected",
|
|
231
268
|
scopes,
|
|
232
|
-
allowedApps: existing?.allowedApps ??
|
|
233
|
-
|
|
269
|
+
allowedApps: existing?.allowedApps ?? (flow.scope === "app" ? [flow.appId] : []),
|
|
270
|
+
allowedUsers: flow.scope === "user"
|
|
271
|
+
? [session.email]
|
|
272
|
+
: (existing?.allowedUsers ?? []),
|
|
234
273
|
config: connectionConfig,
|
|
235
274
|
lastCheckedAt: new Date(),
|
|
236
275
|
lastError: null,
|
|
@@ -267,7 +306,7 @@ export function buildWorkspaceProviderAuthorizationUrl(input) {
|
|
|
267
306
|
url.searchParams.set("audience", "api.atlassian.com");
|
|
268
307
|
url.searchParams.set("prompt", "consent");
|
|
269
308
|
}
|
|
270
|
-
if (input.provider.id
|
|
309
|
+
if (isGoogleWorkspaceOAuthProvider(input.provider.id)) {
|
|
271
310
|
url.searchParams.set("access_type", "offline");
|
|
272
311
|
url.searchParams.set("include_granted_scopes", "true");
|
|
273
312
|
url.searchParams.set("prompt", "consent");
|
|
@@ -393,7 +432,7 @@ export async function exchangeWorkspaceProviderOAuthCode(input) {
|
|
|
393
432
|
...(input.providerId === "sentry"
|
|
394
433
|
? { client_id: input.clientId, client_secret: input.clientSecret }
|
|
395
434
|
: {}),
|
|
396
|
-
...(input.providerId
|
|
435
|
+
...(isGoogleWorkspaceOAuthProvider(input.providerId)
|
|
397
436
|
? { client_id: input.clientId, client_secret: input.clientSecret }
|
|
398
437
|
: {}),
|
|
399
438
|
};
|
|
@@ -566,19 +605,16 @@ async function resolveWorkspaceProviderIdentitySingle(providerId, tokens) {
|
|
|
566
605
|
label: text(user?.email) ?? text(user?.name) ?? "Sentry account",
|
|
567
606
|
};
|
|
568
607
|
}
|
|
569
|
-
if (providerId
|
|
608
|
+
if (isGoogleWorkspaceOAuthProvider(providerId)) {
|
|
570
609
|
const accessToken = text(tokens.access_token);
|
|
571
|
-
const { response, body } = await fetchBoundedProviderJson("https://
|
|
572
|
-
const
|
|
573
|
-
const accountId = text(user?.permissionId) ?? text(user?.emailAddress);
|
|
610
|
+
const { response, body } = await fetchBoundedProviderJson("https://openidconnect.googleapis.com/v1/userinfo", { headers: { Authorization: `Bearer ${accessToken}` } }, "Google Workspace");
|
|
611
|
+
const accountId = text(body.email) ?? text(body.sub);
|
|
574
612
|
if (!response.ok || !accountId) {
|
|
575
|
-
throw new Error("Google
|
|
613
|
+
throw new Error("Google OAuth response did not identify the connected account.");
|
|
576
614
|
}
|
|
577
615
|
return {
|
|
578
616
|
accountId,
|
|
579
|
-
label: text(
|
|
580
|
-
text(user?.displayName) ??
|
|
581
|
-
"Google Drive account",
|
|
617
|
+
label: text(body.email) ?? text(body.name) ?? "Google account",
|
|
582
618
|
};
|
|
583
619
|
}
|
|
584
620
|
const accessToken = text(tokens.access_token);
|
|
@@ -615,6 +651,7 @@ export function isWorkspaceProviderOAuthFlowValid(input) {
|
|
|
615
651
|
input.state.flowId === input.flow.flowId &&
|
|
616
652
|
input.state.redirectUri === input.flow.redirectUri &&
|
|
617
653
|
input.state.owner === input.flow.owner &&
|
|
654
|
+
input.state.scope === input.flow.scope &&
|
|
618
655
|
input.sessionEmail === input.flow.owner &&
|
|
619
656
|
input.state.orgId === input.flow.orgId &&
|
|
620
657
|
input.sessionOrgId === input.flow.orgId &&
|
|
@@ -697,7 +734,9 @@ export function mergeWorkspaceOAuthValues(existing, incoming) {
|
|
|
697
734
|
return [...new Set([...existing, ...incoming])];
|
|
698
735
|
}
|
|
699
736
|
function clientCredentialKeys(provider, field) {
|
|
700
|
-
const prefix = provider
|
|
737
|
+
const prefix = isGoogleWorkspaceOAuthProvider(provider)
|
|
738
|
+
? "GOOGLE"
|
|
739
|
+
: provider.toUpperCase();
|
|
701
740
|
const suffix = field === "id" ? "ID" : "SECRET";
|
|
702
741
|
if (provider === "github") {
|
|
703
742
|
const integrationPrefix = `GITHUB_INTEGRATION_CLIENT_${suffix}`;
|
|
@@ -799,6 +838,11 @@ function normalizeAppId(value) {
|
|
|
799
838
|
function text(value) {
|
|
800
839
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
801
840
|
}
|
|
841
|
+
function parseWorkspaceProviderOAuthScope(value) {
|
|
842
|
+
if (value === undefined)
|
|
843
|
+
return "organization";
|
|
844
|
+
return isWorkspaceProviderOAuthScope(value) ? value : null;
|
|
845
|
+
}
|
|
802
846
|
function scalarText(value) {
|
|
803
847
|
if (typeof value === "number" && Number.isFinite(value))
|
|
804
848
|
return String(value);
|
|
@@ -817,15 +861,23 @@ function unauthorized(event) {
|
|
|
817
861
|
setResponseStatus(event, 401);
|
|
818
862
|
return { error: "Authentication required" };
|
|
819
863
|
}
|
|
820
|
-
async function
|
|
864
|
+
async function requireWorkspaceProviderOAuthAccess(event, appId, requestedScope = "organization") {
|
|
821
865
|
const context = await getOrgContext(event).catch(() => null);
|
|
822
866
|
if (!context || !context.orgId) {
|
|
823
867
|
setResponseStatus(event, 403);
|
|
824
868
|
return null;
|
|
825
869
|
}
|
|
826
|
-
if (
|
|
870
|
+
if (requestedScope === "user") {
|
|
871
|
+
return { ...context, oauthScope: "user" };
|
|
872
|
+
}
|
|
873
|
+
if (requestedScope === "organization" &&
|
|
874
|
+
canConnectWorkspaceProviderOAuth(context.orgId, context.role)) {
|
|
827
875
|
return { ...context, oauthScope: "organization" };
|
|
828
876
|
}
|
|
877
|
+
if (requestedScope === "app" &&
|
|
878
|
+
canConnectWorkspaceProviderOAuth(context.orgId, context.role)) {
|
|
879
|
+
return { ...context, oauthScope: "app" };
|
|
880
|
+
}
|
|
829
881
|
if (appId) {
|
|
830
882
|
const descriptor = getRegisteredAppRoles(appId);
|
|
831
883
|
if (descriptor?.roles.some((role) => role === "admin")) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const AGENT_NATIVE_OPEN_PATH = "/_agent-native/open";
|
|
2
2
|
export declare const AGENT_SIDEBAR_QUERY_PARAM = "agentSidebar";
|
|
3
3
|
export declare const AGENT_SIDEBAR_QUERY_VALUE_CLOSED = "closed";
|
|
4
|
+
export declare const AGENT_SIDEBAR_QUERY_VALUE_OPEN = "open";
|
|
4
5
|
export declare function isAgentNativeOpenDeepLink(urlOrPath: string): boolean;
|
|
5
6
|
export declare function withCollapsedAgentSidebarParam(urlOrPath: string): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const AGENT_NATIVE_OPEN_PATH = "/_agent-native/open";
|
|
2
2
|
export const AGENT_SIDEBAR_QUERY_PARAM = "agentSidebar";
|
|
3
3
|
export const AGENT_SIDEBAR_QUERY_VALUE_CLOSED = "closed";
|
|
4
|
+
export const AGENT_SIDEBAR_QUERY_VALUE_OPEN = "open";
|
|
4
5
|
const RELATIVE_URL_BASE = "http://agent-native.invalid";
|
|
5
6
|
function hasUrlScheme(urlOrPath) {
|
|
6
7
|
return /^[a-z][a-z0-9+.-]*:/i.test(urlOrPath);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
|
|
2
2
|
export declare const BETA_OPT_OUT_DURATION_MS: number;
|
|
3
3
|
export declare const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
|
|
4
|
+
export declare const BETA_FORCE_QUERY_PARAM = "force";
|
|
5
|
+
export declare const BETA_FORCE_SESSION_STORAGE_KEY = "agent-native:force-production";
|
|
4
6
|
export declare const ENVIRONMENT_BETA_HOSTS: {
|
|
5
7
|
readonly "agent-workspace.builder.io": "beta.agent-workspace.builder.io";
|
|
6
8
|
readonly "analytics.agent-native.com": "beta.analytics.agent-native.com";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
|
|
2
|
-
export const BETA_OPT_OUT_DURATION_MS =
|
|
2
|
+
export const BETA_OPT_OUT_DURATION_MS = 8 * 60 * 60 * 1000;
|
|
3
3
|
export const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
|
|
4
|
+
export const BETA_FORCE_QUERY_PARAM = "force";
|
|
5
|
+
export const BETA_FORCE_SESSION_STORAGE_KEY = "agent-native:force-production";
|
|
4
6
|
export const ENVIRONMENT_BETA_HOSTS = {
|
|
5
7
|
"agent-workspace.builder.io": "beta.agent-workspace.builder.io",
|
|
6
8
|
"analytics.agent-native.com": "beta.analytics.agent-native.com",
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -6,13 +6,15 @@ export { truncate } from "./truncate.js";
|
|
|
6
6
|
export { isHumanReadableDocumentTitle, normalizeDocumentTitle, } from "./document-title.js";
|
|
7
7
|
export { injectDocumentMarkup } from "./html-document.js";
|
|
8
8
|
export { withBuilderUtmTrackingParams } from "./builder-link-tracking.js";
|
|
9
|
+
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, ENVIRONMENT_BETA_HOSTS, resolveEnvironmentTargets, type EnvironmentBadgeTargets, } from "./environment-lanes.js";
|
|
9
10
|
export { SSR_HTML_CONTENT_TYPE, SSR_QUERY_CACHE_KEY_HEADER, type SsrHtmlContentTypeOptions, withSsrHtmlContentType, } from "./cache-control.js";
|
|
11
|
+
export { SURFACE_HIDDEN_FLAG, SURFACE_VISIBILITY_EVENT, addSurfaceVisibilityListener, buildSurfaceVisibilityScript, isHostSurfaceHidden, isSurfaceHidden, } from "./surface-visibility.js";
|
|
10
12
|
export { AGENT_NATIVE_DOCS_ORIGIN, docsUrl, type DocsUrlOptions, } from "./docs-url.js";
|
|
11
13
|
export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, type RuntimeConfigEnvironment, type RuntimeConfigIssue, type RuntimeConfigIssueCode, type RuntimeConfigIssueSeverity, type RuntimeConfigPhase, type RuntimeConfigReport, type RuntimeConfigRequirements, } from "./runtime-config.js";
|
|
12
14
|
export { llmConnectionTrackingProperties, normalizeLlmConnection, type LlmConnectionStatus, } from "./llm-connection.js";
|
|
13
15
|
export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, normalizeWorkspaceAppId, } from "./workspace-app-id.js";
|
|
14
16
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, type WorkspaceAppRouteAccess, type WorkspaceAppRouteAccessFromConfig, type WorkspaceAppAudience, } from "./workspace-app-audience.js";
|
|
15
|
-
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
17
|
+
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, AGENT_SIDEBAR_QUERY_VALUE_OPEN, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
16
18
|
export { buildChatFirstAppCreationPrompt, titleFromChatFirstAppPrompt, type ChatFirstAppCreationPromptInput, type ChatFirstAppCreationResource, type ChatFirstAppCreationVaultAccessMode, } from "./chat-first-app-creation.js";
|
|
17
19
|
export { NATIVE_AUTH_COPY, resolveNativeAuthCopy, type NativeAuthCopy, } from "./auth-copy.js";
|
|
18
20
|
export { createPollEngine, type PollEngineOptions, type PollEngineHandle, } from "./poll-engine.js";
|
package/dist/shared/index.js
CHANGED
|
@@ -6,13 +6,15 @@ export { truncate } from "./truncate.js";
|
|
|
6
6
|
export { isHumanReadableDocumentTitle, normalizeDocumentTitle, } from "./document-title.js";
|
|
7
7
|
export { injectDocumentMarkup } from "./html-document.js";
|
|
8
8
|
export { withBuilderUtmTrackingParams } from "./builder-link-tracking.js";
|
|
9
|
+
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, ENVIRONMENT_BETA_HOSTS, resolveEnvironmentTargets, } from "./environment-lanes.js";
|
|
9
10
|
export { SSR_HTML_CONTENT_TYPE, SSR_QUERY_CACHE_KEY_HEADER, withSsrHtmlContentType, } from "./cache-control.js";
|
|
11
|
+
export { SURFACE_HIDDEN_FLAG, SURFACE_VISIBILITY_EVENT, addSurfaceVisibilityListener, buildSurfaceVisibilityScript, isHostSurfaceHidden, isSurfaceHidden, } from "./surface-visibility.js";
|
|
10
12
|
export { AGENT_NATIVE_DOCS_ORIGIN, docsUrl, } from "./docs-url.js";
|
|
11
13
|
export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, } from "./runtime-config.js";
|
|
12
14
|
export { llmConnectionTrackingProperties, normalizeLlmConnection, } from "./llm-connection.js";
|
|
13
15
|
export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, normalizeWorkspaceAppId, } from "./workspace-app-id.js";
|
|
14
16
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, } from "./workspace-app-audience.js";
|
|
15
|
-
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
17
|
+
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, AGENT_SIDEBAR_QUERY_VALUE_OPEN, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
16
18
|
export { buildChatFirstAppCreationPrompt, titleFromChatFirstAppPrompt, } from "./chat-first-app-creation.js";
|
|
17
19
|
export { NATIVE_AUTH_COPY, resolveNativeAuthCopy, } from "./auth-copy.js";
|
|
18
20
|
export { createPollEngine, } from "./poll-engine.js";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-declared surface visibility.
|
|
3
|
+
*
|
|
4
|
+
* An Electron `<webview>` guest never reports itself hidden: hiding the element
|
|
5
|
+
* or any ancestor leaves `document.visibilityState === "visible"` and never
|
|
6
|
+
* fires `visibilitychange`, so every visibility-based pause in this package is
|
|
7
|
+
* inert inside the desktop shell. A backgrounded app tab there keeps polling at
|
|
8
|
+
* its full foreground cadence and holds its event stream open for as long as
|
|
9
|
+
* the shell is running. The host therefore has to say so explicitly, and this
|
|
10
|
+
* flag is what background work must consult instead of the document alone.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SURFACE_HIDDEN_FLAG = "__agentNativeSurfaceHidden";
|
|
13
|
+
/** Dispatched on `window` whenever the host flips the flag. */
|
|
14
|
+
export declare const SURFACE_VISIBILITY_EVENT = "agentnative:surfacevisibilitychange";
|
|
15
|
+
/** Whether an embedding host has declared this surface off screen. */
|
|
16
|
+
export declare function isHostSurfaceHidden(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether this surface is off screen by either signal. A host that has stashed
|
|
19
|
+
* the surface entirely is a stronger statement than a backgrounded browser tab,
|
|
20
|
+
* so callers that keep working while merely backgrounded should still stop on
|
|
21
|
+
* `isHostSurfaceHidden()`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isSurfaceHidden(): boolean;
|
|
24
|
+
/** Subscribe to both visibility signals. Returns an unsubscribe function. */
|
|
25
|
+
export declare function addSurfaceVisibilityListener(handler: () => void): () => void;
|
|
26
|
+
/**
|
|
27
|
+
* Script a host embedder evaluates inside the guest to declare whether the
|
|
28
|
+
* surface it is hosting is on screen. Kept here so the flag name, the event
|
|
29
|
+
* name, and the write that sets them cannot drift apart across packages.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildSurfaceVisibilityScript(hidden: boolean): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-declared surface visibility.
|
|
3
|
+
*
|
|
4
|
+
* An Electron `<webview>` guest never reports itself hidden: hiding the element
|
|
5
|
+
* or any ancestor leaves `document.visibilityState === "visible"` and never
|
|
6
|
+
* fires `visibilitychange`, so every visibility-based pause in this package is
|
|
7
|
+
* inert inside the desktop shell. A backgrounded app tab there keeps polling at
|
|
8
|
+
* its full foreground cadence and holds its event stream open for as long as
|
|
9
|
+
* the shell is running. The host therefore has to say so explicitly, and this
|
|
10
|
+
* flag is what background work must consult instead of the document alone.
|
|
11
|
+
*/
|
|
12
|
+
export const SURFACE_HIDDEN_FLAG = "__agentNativeSurfaceHidden";
|
|
13
|
+
/** Dispatched on `window` whenever the host flips the flag. */
|
|
14
|
+
export const SURFACE_VISIBILITY_EVENT = "agentnative:surfacevisibilitychange";
|
|
15
|
+
/** Whether an embedding host has declared this surface off screen. */
|
|
16
|
+
export function isHostSurfaceHidden() {
|
|
17
|
+
if (typeof window === "undefined")
|
|
18
|
+
return false;
|
|
19
|
+
return (window[SURFACE_HIDDEN_FLAG] === true);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Whether this surface is off screen by either signal. A host that has stashed
|
|
23
|
+
* the surface entirely is a stronger statement than a backgrounded browser tab,
|
|
24
|
+
* so callers that keep working while merely backgrounded should still stop on
|
|
25
|
+
* `isHostSurfaceHidden()`.
|
|
26
|
+
*/
|
|
27
|
+
export function isSurfaceHidden() {
|
|
28
|
+
if (isHostSurfaceHidden())
|
|
29
|
+
return true;
|
|
30
|
+
return (typeof document !== "undefined" && document.visibilityState === "hidden");
|
|
31
|
+
}
|
|
32
|
+
/** Subscribe to both visibility signals. Returns an unsubscribe function. */
|
|
33
|
+
export function addSurfaceVisibilityListener(handler) {
|
|
34
|
+
if (typeof document === "undefined" || typeof window === "undefined") {
|
|
35
|
+
return () => { };
|
|
36
|
+
}
|
|
37
|
+
document.addEventListener("visibilitychange", handler);
|
|
38
|
+
window.addEventListener(SURFACE_VISIBILITY_EVENT, handler);
|
|
39
|
+
return () => {
|
|
40
|
+
document.removeEventListener("visibilitychange", handler);
|
|
41
|
+
window.removeEventListener(SURFACE_VISIBILITY_EVENT, handler);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Script a host embedder evaluates inside the guest to declare whether the
|
|
46
|
+
* surface it is hosting is on screen. Kept here so the flag name, the event
|
|
47
|
+
* name, and the write that sets them cannot drift apart across packages.
|
|
48
|
+
*/
|
|
49
|
+
export function buildSurfaceVisibilityScript(hidden) {
|
|
50
|
+
return `(() => {
|
|
51
|
+
const next = ${hidden ? "true" : "false"};
|
|
52
|
+
if (window[${JSON.stringify(SURFACE_HIDDEN_FLAG)}] === next) return next;
|
|
53
|
+
window[${JSON.stringify(SURFACE_HIDDEN_FLAG)}] = next;
|
|
54
|
+
window.dispatchEvent(new Event(${JSON.stringify(SURFACE_VISIBILITY_EVENT)}));
|
|
55
|
+
return next;
|
|
56
|
+
})()`;
|
|
57
|
+
}
|
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type RouteConfig } from "@react-router/dev/routes";
|
|
2
2
|
import { flatRoutes } from "@react-router/fs-routes";
|
|
3
3
|
|
|
4
|
-
export default flatRoutes(
|
|
4
|
+
export default flatRoutes({
|
|
5
|
+
ignoredRouteFiles: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
|
|
6
|
+
}) satisfies RouteConfig;
|
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type RouteConfig } from "@react-router/dev/routes";
|
|
2
2
|
import { flatRoutes } from "@react-router/fs-routes";
|
|
3
3
|
|
|
4
|
-
export default flatRoutes(
|
|
4
|
+
export default flatRoutes({
|
|
5
|
+
ignoredRouteFiles: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
|
|
6
|
+
}) satisfies RouteConfig;
|
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -8,6 +8,17 @@ export interface TrackingMeta {
|
|
|
8
8
|
anonymousId?: string;
|
|
9
9
|
/** Overrides the ambient request's browser session. */
|
|
10
10
|
sessionId?: string;
|
|
11
|
+
/**
|
|
12
|
+
* When the event actually happened, in epoch ms. Defaults to now.
|
|
13
|
+
*
|
|
14
|
+
* Needed by callers that buffer and flush a batch of events at the end of a
|
|
15
|
+
* unit of work — an agent run emits its trace, generation, and tool spans in
|
|
16
|
+
* one burst, and stamping all of them with the flush time collapses a
|
|
17
|
+
* multi-second waterfall into a single instant. PostHog orders an LLM trace
|
|
18
|
+
* tree by event timestamp, so without this the tree renders with a synthetic
|
|
19
|
+
* timeline.
|
|
20
|
+
*/
|
|
21
|
+
occurredAt?: number;
|
|
11
22
|
}
|
|
12
23
|
/**
|
|
13
24
|
* Who an event is attributed to. Pass an action's `ctx` straight through —
|
|
@@ -42,10 +42,11 @@ function resolveTrackingSource(source) {
|
|
|
42
42
|
userId: source.userId,
|
|
43
43
|
anonymousId: source.anonymousId,
|
|
44
44
|
sessionId: source.sessionId ?? ambientSessionId,
|
|
45
|
+
occurredAt: source.occurredAt,
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
export function track(name, properties, source) {
|
|
48
|
-
const { userId, anonymousId, sessionId } = resolveTrackingSource(source);
|
|
49
|
+
const { userId, anonymousId, sessionId, occurredAt } = resolveTrackingSource(source);
|
|
49
50
|
const clientPlatform = getRequestContext()?.clientPlatform;
|
|
50
51
|
const trackedProperties = {
|
|
51
52
|
...(properties ?? {}),
|
|
@@ -57,7 +58,9 @@ export function track(name, properties, source) {
|
|
|
57
58
|
const event = {
|
|
58
59
|
name,
|
|
59
60
|
properties: trackedProperties,
|
|
60
|
-
|
|
61
|
+
// A caller-supplied `occurredAt` of 0 is not a real event time, so `||`
|
|
62
|
+
// rather than `??` is deliberate here.
|
|
63
|
+
timestamp: new Date(occurredAt || Date.now()).toISOString(),
|
|
61
64
|
userId,
|
|
62
65
|
anonymousId,
|
|
63
66
|
sessionId,
|
package/dist/triggers/actions.js
CHANGED
|
@@ -301,12 +301,15 @@ async function handleRunNow(args, getCurrentUser, appId, context) {
|
|
|
301
301
|
return "Error: an automation cannot run another automation.";
|
|
302
302
|
}
|
|
303
303
|
try {
|
|
304
|
+
const path = typeof args.path === "string" ? args.path.trim() : "";
|
|
305
|
+
const name = typeof args.name === "string" ? args.name : "";
|
|
304
306
|
const result = await queueAutomationRunNow({
|
|
305
307
|
userEmail: getCurrentUser(),
|
|
306
308
|
orgId: getRequestOrgId(),
|
|
307
309
|
appId,
|
|
308
310
|
scope: automationScope(args.scope),
|
|
309
|
-
|
|
311
|
+
...(path ? { path } : { name }),
|
|
312
|
+
requestHeaders: context?.requestHeaders,
|
|
310
313
|
});
|
|
311
314
|
return JSON.stringify(result);
|
|
312
315
|
}
|
|
@@ -340,7 +343,7 @@ export function createAutomationToolEntries(getCurrentUser, appId) {
|
|
|
340
343
|
- **update**: Update an existing automation's settings without changing its creator (enabled, schedule, timezone, condition, body, policy, model, execution host, MCP allowlist). Required param: name. Use the same scope it was created in.
|
|
341
344
|
- **delete**: Delete an automation. Always confirm with the user first. Required param: name.
|
|
342
345
|
- **fire-test**: Fire a test event to validate automations. Emits a test.event.fired event. Optional param: data (JSON string).
|
|
343
|
-
- **run-now**: Run one automation immediately using its real actions and side effects. This is an explicit user-authorized run and returns a durable run id; it does not change the automation's next scheduled run. Required params: name; optional scope.`,
|
|
346
|
+
- **run-now**: Run one automation immediately using its real actions and side effects. This is an explicit user-authorized run and returns a durable run id; it does not change the automation's next scheduled run. Required params: name or path (not both); optional scope. Use path for automations nested under jobs/ (for example jobs/factories/<id>/factory-slack-feedback.md); those names contain a slash and cannot round-trip through name.`,
|
|
344
347
|
parameters: {
|
|
345
348
|
type: "object",
|
|
346
349
|
properties: {
|
|
@@ -351,7 +354,11 @@ export function createAutomationToolEntries(getCurrentUser, appId) {
|
|
|
351
354
|
},
|
|
352
355
|
name: {
|
|
353
356
|
type: "string",
|
|
354
|
-
description: "Slug name for the automation (lowercase, hyphens). Used by define, update, delete, and run-now.",
|
|
357
|
+
description: "Slug name for the automation (lowercase, hyphens). Used by define, update, delete, and run-now for flat automations. For nested automations, pass path to run-now instead.",
|
|
358
|
+
},
|
|
359
|
+
path: {
|
|
360
|
+
type: "string",
|
|
361
|
+
description: "Full jobs resource path (jobs/...md) for a nested automation. Use with run-now instead of name when the automation name contains a slash.",
|
|
355
362
|
},
|
|
356
363
|
scope: {
|
|
357
364
|
type: "string",
|
package/dist/usage/store.js
CHANGED
|
@@ -207,6 +207,17 @@ export async function ensureUsageTable() {
|
|
|
207
207
|
// Probe pg_indexes first (no lock) and skip the SHARE-locking CREATE
|
|
208
208
|
// INDEX when the index is already present.
|
|
209
209
|
await ensureIndexExists("idx_token_usage_owner_created", `CREATE INDEX IF NOT EXISTS idx_token_usage_owner_created ON token_usage (owner_email, created_at)`);
|
|
210
|
+
// `owner_email` is written as the caller supplied it, so the metrics
|
|
211
|
+
// queries scope with `LOWER(owner_email) IN (…)`. A plain btree cannot
|
|
212
|
+
// serve a function-wrapped predicate: without this expression index the
|
|
213
|
+
// usage panel scans the whole table, which is the highest-row-count one
|
|
214
|
+
// in the system (a row per LLM call, every app and org).
|
|
215
|
+
// NOT built CONCURRENTLY. This runs at release over the pooled Neon
|
|
216
|
+
// endpoint, and a transaction-pooled connection cannot carry
|
|
217
|
+
// `CREATE INDEX CONCURRENTLY` to completion — it returns without
|
|
218
|
+
// creating the index, which then fails the verifying probe and blocks
|
|
219
|
+
// the whole release. The SHARE lock is the cost of a build that lands.
|
|
220
|
+
await ensureIndexExists("idx_token_usage_lower_owner_created", `CREATE INDEX IF NOT EXISTS idx_token_usage_lower_owner_created ON token_usage (LOWER(owner_email), created_at)`);
|
|
210
221
|
return;
|
|
211
222
|
}
|
|
212
223
|
// SQLite (local dev): no lock problem — keep the original behaviour.
|
|
@@ -226,10 +237,19 @@ export async function ensureUsageTable() {
|
|
|
226
237
|
// the `Date.now()` written per run by recordUsage() overflows int4. Widen
|
|
227
238
|
// it in place (no-op once done / on fresh BIGINT databases).
|
|
228
239
|
await widenIntColumnsToBigInt("token_usage", ["created_at"]);
|
|
229
|
-
|
|
230
|
-
|
|
240
|
+
for (const ddl of [
|
|
241
|
+
`CREATE INDEX IF NOT EXISTS idx_token_usage_owner_created ON token_usage (owner_email, created_at)`,
|
|
242
|
+
`CREATE INDEX IF NOT EXISTS idx_token_usage_lower_owner_created ON token_usage (LOWER(owner_email), created_at)`,
|
|
243
|
+
]) {
|
|
244
|
+
try {
|
|
245
|
+
await client.execute(ddl);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
// coercion-ok: index already exists, or this dialect rejected the
|
|
249
|
+
// duplicate. Local-dev SQLite only — the hosted path creates these
|
|
250
|
+
// through the Postgres branch above, which probes before creating.
|
|
251
|
+
}
|
|
231
252
|
}
|
|
232
|
-
catch { }
|
|
233
253
|
})().catch((err) => {
|
|
234
254
|
// Retry init on the next call after a failed startup.
|
|
235
255
|
_initPromise = undefined;
|