@agent-native/core 0.141.7 → 0.144.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 +9 -0
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/AGENTS.md +35 -38
- package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
- package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
- package/corpus/templates/analytics/actions/navigate.ts +4 -5
- package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +44 -11
- package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
- package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
- package/corpus/templates/analytics/app/i18n-data.ts +680 -0
- package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
- package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
- package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
- package/corpus/templates/analytics/netlify.toml +7 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
- package/corpus/templates/analytics/server/db/index.ts +27 -0
- package/corpus/templates/analytics/server/db/schema.ts +10 -0
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +133 -44
- package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
- package/corpus/templates/analytics/server/plugins/db.ts +52 -18
- package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +28 -2
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
- package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
- package/corpus/templates/brain/app/routes/sources.tsx +15 -7
- package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
- package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/AGENTS.md +11 -32
- package/corpus/templates/calendar/actions/update-event.ts +107 -1
- package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
- package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
- package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
- package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
- package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
- package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +48 -20
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
- package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
- package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
- package/corpus/templates/clips/server/plugins/db.ts +214 -26
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
- package/corpus/templates/crm/server/plugins/db.ts +11 -8
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/design/actions/import-from-url.ts +1 -1
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
- package/corpus/templates/design/app/pages/Index.tsx +6 -2
- package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
- package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +37 -1
- package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/slides/AGENTS.md +7 -9
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/actions/export-pptx.ts +402 -36
- package/corpus/templates/slides/actions/import-file.ts +46 -85
- package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
- package/corpus/templates/slides/actions/import-pptx.ts +85 -60
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
- package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +173 -0
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
- package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
- package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +4 -0
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +1 -1
- package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
- package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
- package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
- package/corpus/templates/slides/app/pages/Index.tsx +91 -1
- package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
- package/corpus/templates/slides/server/handlers/import/html-converter.ts +236 -13
- package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
- package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
- package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
- package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -3
- package/corpus/templates/slides/server/lib/emails.ts +7 -2
- package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
- package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
- package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
- package/corpus/templates/slides/shared/upload-types.ts +3 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/agent/production-agent.d.ts +17 -0
- package/dist/agent/production-agent.js +72 -1
- package/dist/cli/agent-plugin.d.ts +112 -0
- package/dist/cli/agent-plugin.js +1081 -0
- package/dist/cli/app-skill.js +39 -1
- package/dist/cli/code-agent-executor.d.ts +3 -0
- package/dist/cli/code-agent-executor.js +51 -13
- package/dist/cli/index.js +13 -0
- package/dist/cli/templates-meta.js +1 -1
- package/dist/client/AgentPanel.d.ts +3 -1
- package/dist/client/AgentPanel.js +9 -2
- package/dist/client/AssistantChat.d.ts +8 -0
- package/dist/client/AssistantChat.js +23 -8
- package/dist/client/NewWorkspaceAppFlow.js +1 -0
- package/dist/client/agent-chat-adapter.js +123 -4
- package/dist/client/assistant-ui-recovery.d.ts +2 -1
- package/dist/client/assistant-ui-recovery.js +7 -3
- package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
- package/dist/client/org/TeamPage.js +1 -1
- package/dist/client/require-session.js +1 -1
- package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
- package/dist/client/resources/McpConnectionSuggestion.js +27 -10
- package/dist/client/resources/McpIntegrationDialog.js +77 -45
- package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
- package/dist/client/resources/mcp-integration-catalog.js +255 -2
- package/dist/client/resources/mcp-integration-logos.js +18 -2
- package/dist/client/settings/AccountSettingsCard.js +2 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts +9 -0
- package/dist/db/client.js +51 -16
- package/dist/db/create-get-db.js +2 -2
- package/dist/db/ddl-guard.d.ts +11 -10
- package/dist/db/ddl-guard.js +40 -12
- package/dist/deploy/build.d.ts +2 -0
- package/dist/deploy/build.js +97 -4
- package/dist/deploy/workspace-deploy.js +0 -2
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/guards/no-env-credentials.js +9 -0
- package/dist/ingestion/index.d.ts +1 -1
- package/dist/ingestion/pptx.d.ts +68 -0
- package/dist/ingestion/pptx.js +660 -213
- package/dist/integrations/plugin.js +9 -6
- package/dist/localization/default-messages.d.ts +54 -0
- package/dist/localization/default-messages.js +57 -2
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp-client/oauth-routes.d.ts +2 -0
- package/dist/mcp-client/oauth-routes.js +73 -6
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.js +11 -0
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.js +15 -1
- package/dist/scripts/call-agent.js +34 -4
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +36 -1
- package/dist/server/agent-chat-plugin.js +29 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.js +47 -11
- package/dist/server/better-auth-instance.js +5 -3
- package/dist/server/core-routes-plugin.d.ts +8 -1
- package/dist/server/core-routes-plugin.js +28 -3
- package/dist/server/credential-provider.d.ts +3 -3
- package/dist/server/credential-provider.js +90 -4
- package/dist/server/onboarding-html.d.ts +2 -0
- package/dist/server/onboarding-html.js +115 -29
- package/dist/server/self-dispatch.d.ts +5 -4
- package/dist/server/self-dispatch.js +25 -14
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.js +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/cache-control.d.ts +26 -2
- package/dist/shared/cache-control.js +43 -2
- package/dist/shared/password-policy.d.ts +3 -0
- package/dist/shared/password-policy.js +3 -0
- package/dist/sharing/actions/set-resource-visibility.js +16 -4
- package/dist/sharing/registry.d.ts +14 -0
- package/dist/styles/agent-native.css +6 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-root/AGENTS.md +7 -0
- package/dist/user-profile/actions/change-password.js +8 -3
- package/dist/user-profile/actions/set-password.js +5 -1
- package/dist/vite/action-types-plugin.js +59 -0
- package/docs/content/skills-guide.mdx +13 -0
- package/package.json +6 -2
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-root/AGENTS.md +7 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
+
import { IconCalendarTime } from "@tabler/icons-react";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Select,
|
|
7
|
+
SelectContent,
|
|
8
|
+
SelectGroup,
|
|
9
|
+
SelectItem,
|
|
10
|
+
SelectTrigger,
|
|
11
|
+
SelectValue,
|
|
12
|
+
} from "@/components/ui/select";
|
|
13
|
+
import { useGoogleAuthStatus } from "@/hooks/use-google-auth";
|
|
14
|
+
import { useViewPreferences } from "@/hooks/use-view-preferences";
|
|
15
|
+
import { defaultColorForAccount } from "@/lib/calendar-view-preferences";
|
|
16
|
+
import { shouldShowEventAccountSelector } from "@/lib/event-account-selection";
|
|
17
|
+
|
|
18
|
+
const EMPTY_CONNECTED_ACCOUNTS: Array<{ email: string }> = [];
|
|
19
|
+
|
|
20
|
+
export function EventCalendarSelect({
|
|
21
|
+
accountEmail,
|
|
22
|
+
onAccountChange,
|
|
23
|
+
disabled = false,
|
|
24
|
+
}: {
|
|
25
|
+
accountEmail?: string;
|
|
26
|
+
onAccountChange: (accountEmail: string) => void;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
}) {
|
|
29
|
+
const t = useT();
|
|
30
|
+
const googleStatus = useGoogleAuthStatus();
|
|
31
|
+
const connectedAccounts =
|
|
32
|
+
googleStatus.data?.accounts ?? EMPTY_CONNECTED_ACCOUNTS;
|
|
33
|
+
const connectedAccountEmails = useMemo(
|
|
34
|
+
() => connectedAccounts.map((account) => account.email),
|
|
35
|
+
[connectedAccounts],
|
|
36
|
+
);
|
|
37
|
+
const { prefs: viewPrefs } = useViewPreferences();
|
|
38
|
+
|
|
39
|
+
if (!shouldShowEventAccountSelector(connectedAccounts) || !accountEmail) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<div className="flex items-center gap-3 py-1.5">
|
|
45
|
+
<IconCalendarTime className="h-4 w-4 shrink-0 text-muted-foreground" />
|
|
46
|
+
<Select
|
|
47
|
+
value={accountEmail}
|
|
48
|
+
onValueChange={onAccountChange}
|
|
49
|
+
disabled={disabled}
|
|
50
|
+
>
|
|
51
|
+
<SelectTrigger
|
|
52
|
+
aria-label={t("navigation.calendar")}
|
|
53
|
+
className="h-8 flex-1 text-sm"
|
|
54
|
+
>
|
|
55
|
+
<SelectValue />
|
|
56
|
+
</SelectTrigger>
|
|
57
|
+
<SelectContent>
|
|
58
|
+
<SelectGroup>
|
|
59
|
+
{connectedAccounts.map((account) => (
|
|
60
|
+
<SelectItem key={account.email} value={account.email}>
|
|
61
|
+
<span className="flex min-w-0 items-center gap-2">
|
|
62
|
+
<span
|
|
63
|
+
className="size-2.5 shrink-0 rounded-full"
|
|
64
|
+
style={{
|
|
65
|
+
backgroundColor:
|
|
66
|
+
viewPrefs.accountColors[account.email] ??
|
|
67
|
+
viewPrefs.singleColor ??
|
|
68
|
+
defaultColorForAccount(
|
|
69
|
+
account.email,
|
|
70
|
+
connectedAccountEmails,
|
|
71
|
+
),
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
<span className="truncate">{account.email}</span>
|
|
75
|
+
</span>
|
|
76
|
+
</SelectItem>
|
|
77
|
+
))}
|
|
78
|
+
</SelectGroup>
|
|
79
|
+
</SelectContent>
|
|
80
|
+
</Select>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
@@ -18,6 +18,7 @@ import { toast } from "sonner";
|
|
|
18
18
|
|
|
19
19
|
import { ResearchMeetingButton } from "@/components/calendar/ApolloPanel";
|
|
20
20
|
import { EventAttendeesSection } from "@/components/calendar/EventAttendeesSection";
|
|
21
|
+
import { EventCalendarSelect } from "@/components/calendar/EventCalendarSelect";
|
|
21
22
|
import {
|
|
22
23
|
RenderedDescription,
|
|
23
24
|
AutoGrowTextarea,
|
|
@@ -133,6 +134,9 @@ export function EventDetailPanel({
|
|
|
133
134
|
);
|
|
134
135
|
const titleInputRef = useRef<HTMLInputElement>(null);
|
|
135
136
|
const updateEvent = useUpdateEvent();
|
|
137
|
+
const [selectedAccountEmail, setSelectedAccountEmail] = useState(
|
|
138
|
+
event?.accountEmail,
|
|
139
|
+
);
|
|
136
140
|
const { promptGuestNotification, guestNotificationDialog } =
|
|
137
141
|
useGuestNotificationPrompt();
|
|
138
142
|
const isOverlay = !!event?.overlayEmail;
|
|
@@ -157,6 +161,10 @@ export function EventDetailPanel({
|
|
|
157
161
|
lastSavedDescriptionRef.current = event?.description || "";
|
|
158
162
|
}, [event?.id]);
|
|
159
163
|
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
setSelectedAccountEmail(event?.accountEmail);
|
|
166
|
+
}, [event?.id, event?.accountEmail]);
|
|
167
|
+
|
|
160
168
|
useEffect(() => {
|
|
161
169
|
if (isEditingTitle) {
|
|
162
170
|
requestAnimationFrame(() => titleInputRef.current?.focus());
|
|
@@ -203,6 +211,47 @@ export function EventDetailPanel({
|
|
|
203
211
|
onClose();
|
|
204
212
|
};
|
|
205
213
|
|
|
214
|
+
const handleAccountChange = useCallback(
|
|
215
|
+
(targetAccountEmail: string) => {
|
|
216
|
+
if (
|
|
217
|
+
!event ||
|
|
218
|
+
!event.accountEmail ||
|
|
219
|
+
targetAccountEmail === event.accountEmail ||
|
|
220
|
+
updateEvent.isPending
|
|
221
|
+
) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
setSelectedAccountEmail(targetAccountEmail);
|
|
226
|
+
void (async () => {
|
|
227
|
+
const guestNotification = await promptGuestNotification({
|
|
228
|
+
event,
|
|
229
|
+
action: "update",
|
|
230
|
+
});
|
|
231
|
+
if (!guestNotification) {
|
|
232
|
+
setSelectedAccountEmail(event.accountEmail);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
updateEvent.mutate(
|
|
236
|
+
{
|
|
237
|
+
id: event.id,
|
|
238
|
+
accountEmail: event.accountEmail,
|
|
239
|
+
targetAccountEmail,
|
|
240
|
+
...guestNotification,
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
onSuccess: () => toast.success(t("eventForm.eventUpdated")),
|
|
244
|
+
onError: () => {
|
|
245
|
+
setSelectedAccountEmail(event.accountEmail);
|
|
246
|
+
toast.error(t("eventForm.updateFailed"));
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
);
|
|
250
|
+
})();
|
|
251
|
+
},
|
|
252
|
+
[event, promptGuestNotification, t, updateEvent],
|
|
253
|
+
);
|
|
254
|
+
|
|
206
255
|
const handleAddGoogleMeet = useCallback(() => {
|
|
207
256
|
if (!event || updateEvent.isPending) return;
|
|
208
257
|
void (async () => {
|
|
@@ -378,6 +427,14 @@ export function EventDetailPanel({
|
|
|
378
427
|
</h2>
|
|
379
428
|
)}
|
|
380
429
|
|
|
430
|
+
{!isOverlay && event.source === "google" && (
|
|
431
|
+
<EventCalendarSelect
|
|
432
|
+
accountEmail={selectedAccountEmail}
|
|
433
|
+
onAccountChange={handleAccountChange}
|
|
434
|
+
disabled={updateEvent.isPending}
|
|
435
|
+
/>
|
|
436
|
+
)}
|
|
437
|
+
|
|
381
438
|
{/* Time */}
|
|
382
439
|
<div className="flex items-start gap-2.5 text-sm text-muted-foreground">
|
|
383
440
|
<IconClock className="mt-0.5 h-4 w-4 shrink-0" />
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
type AttendeeRecipient,
|
|
32
32
|
} from "@/components/calendar/AttendeeAutocomplete";
|
|
33
33
|
import { EventAttendeesSection } from "@/components/calendar/EventAttendeesSection";
|
|
34
|
+
import { EventCalendarSelect } from "@/components/calendar/EventCalendarSelect";
|
|
34
35
|
import {
|
|
35
36
|
RenderedDescription,
|
|
36
37
|
AutoGrowTextarea,
|
|
@@ -58,7 +59,6 @@ import {
|
|
|
58
59
|
import {
|
|
59
60
|
Select,
|
|
60
61
|
SelectContent,
|
|
61
|
-
SelectGroup,
|
|
62
62
|
SelectItem,
|
|
63
63
|
SelectTrigger,
|
|
64
64
|
SelectValue,
|
|
@@ -71,12 +71,8 @@ import {
|
|
|
71
71
|
TooltipProvider,
|
|
72
72
|
} from "@/components/ui/tooltip";
|
|
73
73
|
import { useEvent, useUpdateEvent } from "@/hooks/use-events";
|
|
74
|
-
import { useGoogleAuthStatus } from "@/hooks/use-google-auth";
|
|
75
74
|
import { useIsMobile } from "@/hooks/use-mobile";
|
|
76
|
-
import { useViewPreferences } from "@/hooks/use-view-preferences";
|
|
77
75
|
import { useConnectZoom, useZoomStatus } from "@/hooks/use-zoom-auth";
|
|
78
|
-
import { defaultColorForAccount } from "@/lib/calendar-view-preferences";
|
|
79
|
-
import { shouldShowEventAccountSelector } from "@/lib/event-account-selection";
|
|
80
76
|
import {
|
|
81
77
|
attachmentsToDrafts,
|
|
82
78
|
buildRecurrenceRules,
|
|
@@ -113,7 +109,6 @@ import {
|
|
|
113
109
|
|
|
114
110
|
const ZOOM_AFTER_CONNECT_EVENT_ID_KEY = "calendar.zoomAfterConnectEventId";
|
|
115
111
|
const ZOOM_AFTER_CONNECT_MAX_AGE_MS = 10 * 60 * 1000;
|
|
116
|
-
const EMPTY_CONNECTED_ACCOUNTS: Array<{ email: string }> = [];
|
|
117
112
|
|
|
118
113
|
function buildEventDetailSlotContext(event: CalendarEvent) {
|
|
119
114
|
return {
|
|
@@ -306,6 +301,7 @@ type EventUpdatePatch = Partial<CalendarEvent> & {
|
|
|
306
301
|
addGoogleMeet?: boolean;
|
|
307
302
|
addZoom?: boolean;
|
|
308
303
|
addAttendees?: CalendarEvent["attendees"];
|
|
304
|
+
targetAccountEmail?: string;
|
|
309
305
|
scope?: UpdateEventScope;
|
|
310
306
|
workingLocationType?: "homeOffice" | "officeLocation" | "customLocation";
|
|
311
307
|
workingLocationLabel?: string;
|
|
@@ -425,68 +421,6 @@ function formatEventDateRange(start: string, end: string, allDay?: boolean) {
|
|
|
425
421
|
return startLabel === endLabel ? startLabel : `${startLabel} - ${endLabel}`;
|
|
426
422
|
}
|
|
427
423
|
|
|
428
|
-
function DraftEventAccountSelect({
|
|
429
|
-
event,
|
|
430
|
-
onAccountChange,
|
|
431
|
-
}: {
|
|
432
|
-
event: CalendarEvent;
|
|
433
|
-
onAccountChange: (accountEmail: string) => void;
|
|
434
|
-
}) {
|
|
435
|
-
const t = useT();
|
|
436
|
-
const googleStatus = useGoogleAuthStatus();
|
|
437
|
-
const connectedAccounts =
|
|
438
|
-
googleStatus.data?.accounts ?? EMPTY_CONNECTED_ACCOUNTS;
|
|
439
|
-
const connectedAccountEmails = useMemo(
|
|
440
|
-
() => connectedAccounts.map((account) => account.email),
|
|
441
|
-
[connectedAccounts],
|
|
442
|
-
);
|
|
443
|
-
const { prefs: viewPrefs } = useViewPreferences();
|
|
444
|
-
|
|
445
|
-
if (
|
|
446
|
-
!shouldShowEventAccountSelector(connectedAccounts) ||
|
|
447
|
-
!event.accountEmail
|
|
448
|
-
) {
|
|
449
|
-
return null;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
return (
|
|
453
|
-
<div className="flex items-center gap-3 py-1.5">
|
|
454
|
-
<IconCalendarTime className="h-4 w-4 shrink-0 text-muted-foreground" />
|
|
455
|
-
<Select value={event.accountEmail} onValueChange={onAccountChange}>
|
|
456
|
-
<SelectTrigger
|
|
457
|
-
aria-label={t("navigation.calendar")}
|
|
458
|
-
className="h-8 flex-1 text-sm"
|
|
459
|
-
>
|
|
460
|
-
<SelectValue />
|
|
461
|
-
</SelectTrigger>
|
|
462
|
-
<SelectContent>
|
|
463
|
-
<SelectGroup>
|
|
464
|
-
{connectedAccounts.map((account) => (
|
|
465
|
-
<SelectItem key={account.email} value={account.email}>
|
|
466
|
-
<span className="flex min-w-0 items-center gap-2">
|
|
467
|
-
<span
|
|
468
|
-
className="size-2.5 shrink-0 rounded-full"
|
|
469
|
-
style={{
|
|
470
|
-
backgroundColor:
|
|
471
|
-
viewPrefs.accountColors[account.email] ??
|
|
472
|
-
viewPrefs.singleColor ??
|
|
473
|
-
defaultColorForAccount(
|
|
474
|
-
account.email,
|
|
475
|
-
connectedAccountEmails,
|
|
476
|
-
),
|
|
477
|
-
}}
|
|
478
|
-
/>
|
|
479
|
-
<span className="truncate">{account.email}</span>
|
|
480
|
-
</span>
|
|
481
|
-
</SelectItem>
|
|
482
|
-
))}
|
|
483
|
-
</SelectGroup>
|
|
484
|
-
</SelectContent>
|
|
485
|
-
</Select>
|
|
486
|
-
</div>
|
|
487
|
-
);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
424
|
interface EventDetailPopoverProps {
|
|
491
425
|
event: CalendarEvent;
|
|
492
426
|
children: React.ReactNode;
|
|
@@ -590,6 +524,9 @@ export function EventDetailPopover({
|
|
|
590
524
|
() => attachmentsToDrafts(event.attachments),
|
|
591
525
|
);
|
|
592
526
|
const [editMeetingLink, setEditMeetingLink] = useState("");
|
|
527
|
+
const [selectedAccountEmail, setSelectedAccountEmail] = useState(
|
|
528
|
+
event.accountEmail,
|
|
529
|
+
);
|
|
593
530
|
const [editTimeScope, setEditTimeScope] =
|
|
594
531
|
useState<UpdateEventScope>("single");
|
|
595
532
|
const [pendingVideoProvider, setPendingVideoProvider] = useState<
|
|
@@ -620,6 +557,54 @@ export function EventDetailPopover({
|
|
|
620
557
|
const locationRef = useRef<HTMLInputElement>(null);
|
|
621
558
|
const meetingLinkRef = useRef<HTMLInputElement>(null);
|
|
622
559
|
|
|
560
|
+
useEffect(() => {
|
|
561
|
+
setSelectedAccountEmail(event.accountEmail);
|
|
562
|
+
}, [event.id, event.accountEmail]);
|
|
563
|
+
|
|
564
|
+
const handleAccountChange = useCallback(
|
|
565
|
+
(targetAccountEmail: string) => {
|
|
566
|
+
if (isDraft) {
|
|
567
|
+
onDraftUpdate?.(event.id, { accountEmail: targetAccountEmail });
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
if (
|
|
571
|
+
!event.accountEmail ||
|
|
572
|
+
targetAccountEmail === event.accountEmail ||
|
|
573
|
+
updateEvent.isPending
|
|
574
|
+
) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
setSelectedAccountEmail(targetAccountEmail);
|
|
579
|
+
void (async () => {
|
|
580
|
+
const guestNotification = await promptGuestNotification({
|
|
581
|
+
event,
|
|
582
|
+
action: "update",
|
|
583
|
+
});
|
|
584
|
+
if (!guestNotification) {
|
|
585
|
+
setSelectedAccountEmail(event.accountEmail);
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
updateEvent.mutate(
|
|
589
|
+
{
|
|
590
|
+
id: event.id,
|
|
591
|
+
accountEmail: event.accountEmail,
|
|
592
|
+
targetAccountEmail,
|
|
593
|
+
...guestNotification,
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
onSuccess: () => toast.success(t("eventForm.eventUpdated")),
|
|
597
|
+
onError: () => {
|
|
598
|
+
setSelectedAccountEmail(event.accountEmail);
|
|
599
|
+
toast.error(t("eventForm.updateFailed"));
|
|
600
|
+
},
|
|
601
|
+
},
|
|
602
|
+
);
|
|
603
|
+
})();
|
|
604
|
+
},
|
|
605
|
+
[event, isDraft, onDraftUpdate, promptGuestNotification, t, updateEvent],
|
|
606
|
+
);
|
|
607
|
+
|
|
623
608
|
// Sync editing state when the event changes (incl. live agent/other-user
|
|
624
609
|
// edits picked up by polling). Skip the field the user is actively editing so
|
|
625
610
|
// an incoming update never yanks text out from under in-progress typing —
|
|
@@ -1587,12 +1572,13 @@ export function EventDetailPopover({
|
|
|
1587
1572
|
</div>
|
|
1588
1573
|
|
|
1589
1574
|
<div className="px-4 space-y-1">
|
|
1590
|
-
{isDraft && (
|
|
1591
|
-
<
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
onDraftUpdate?.(event.id, { accountEmail })
|
|
1575
|
+
{(isDraft || (!isOverlay && event.source === "google")) && (
|
|
1576
|
+
<EventCalendarSelect
|
|
1577
|
+
accountEmail={
|
|
1578
|
+
isDraft ? event.accountEmail : selectedAccountEmail
|
|
1595
1579
|
}
|
|
1580
|
+
onAccountChange={handleAccountChange}
|
|
1581
|
+
disabled={updateEvent.isPending}
|
|
1596
1582
|
/>
|
|
1597
1583
|
)}
|
|
1598
1584
|
|
|
@@ -45,6 +45,7 @@ type CreateEventInput = Omit<
|
|
|
45
45
|
|
|
46
46
|
type UpdateEventInput = Partial<CalendarEvent> & {
|
|
47
47
|
id: string;
|
|
48
|
+
targetAccountEmail?: string;
|
|
48
49
|
addGoogleMeet?: boolean;
|
|
49
50
|
addZoom?: boolean;
|
|
50
51
|
addAttendees?: CalendarEvent["attendees"];
|
|
@@ -379,6 +380,7 @@ export function useUpdateEvent() {
|
|
|
379
380
|
addGoogleMeet,
|
|
380
381
|
addZoom,
|
|
381
382
|
addAttendees,
|
|
383
|
+
targetAccountEmail,
|
|
382
384
|
sendUpdates,
|
|
383
385
|
notificationMessage,
|
|
384
386
|
scope,
|
|
@@ -386,6 +388,7 @@ export function useUpdateEvent() {
|
|
|
386
388
|
workingLocationLabel,
|
|
387
389
|
...optimisticData
|
|
388
390
|
} = newData;
|
|
391
|
+
const optimisticPatch = targetAccountEmail ? {} : optimisticData;
|
|
389
392
|
const hasWorkingLocationUpdate =
|
|
390
393
|
workingLocationType !== undefined ||
|
|
391
394
|
workingLocationLabel !== undefined;
|
|
@@ -413,7 +416,7 @@ export function useUpdateEvent() {
|
|
|
413
416
|
workingLocationLabel ?? getWorkingLocationEditableLabel(e);
|
|
414
417
|
return {
|
|
415
418
|
...e,
|
|
416
|
-
...
|
|
419
|
+
...optimisticPatch,
|
|
417
420
|
...(hasWorkingLocationUpdate
|
|
418
421
|
? {
|
|
419
422
|
workingLocationProperties: buildWorkingLocationProperties(
|
|
@@ -762,6 +762,8 @@ const enUS = {
|
|
|
762
762
|
end: "End",
|
|
763
763
|
endDate: "End date",
|
|
764
764
|
event: "Event",
|
|
765
|
+
eventUpdated: "Event updated",
|
|
766
|
+
updateFailed: "Failed to update event",
|
|
765
767
|
eventAlerts: "Event alerts",
|
|
766
768
|
eventOptions: "Event options",
|
|
767
769
|
autoDecline: "Automatically decline",
|
|
@@ -8110,6 +8112,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8110
8112
|
},
|
|
8111
8113
|
eventForm: {
|
|
8112
8114
|
addCalendar: "添加日历",
|
|
8115
|
+
eventUpdated: "事件已更新",
|
|
8116
|
+
updateFailed: "更新事件失败",
|
|
8113
8117
|
addCalendarFailed: "添加日历失败",
|
|
8114
8118
|
addCalendarFromUrl: "从 URL 添加日历",
|
|
8115
8119
|
added: "已添加",
|
|
@@ -8281,6 +8285,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8281
8285
|
},
|
|
8282
8286
|
eventForm: {
|
|
8283
8287
|
addCalendar: "Añadir calendario",
|
|
8288
|
+
eventUpdated: "Evento actualizado",
|
|
8289
|
+
updateFailed: "No se pudo actualizar el evento",
|
|
8284
8290
|
addCalendarFailed: "No se pudo añadir el calendario",
|
|
8285
8291
|
addCalendarFromUrl: "Añadir calendario desde URL",
|
|
8286
8292
|
added: "Añadido",
|
|
@@ -8454,6 +8460,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8454
8460
|
},
|
|
8455
8461
|
eventForm: {
|
|
8456
8462
|
addCalendar: "Ajouter un calendrier",
|
|
8463
|
+
eventUpdated: "Événement mis à jour",
|
|
8464
|
+
updateFailed: "Échec de la mise à jour de l'événement",
|
|
8457
8465
|
addCalendarFailed: "Échec de l’ajout du calendrier",
|
|
8458
8466
|
addCalendarFromUrl: "Ajouter un calendrier depuis une URL",
|
|
8459
8467
|
added: "Ajouté",
|
|
@@ -8633,6 +8641,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8633
8641
|
},
|
|
8634
8642
|
eventForm: {
|
|
8635
8643
|
addCalendar: "Kalender hinzufügen",
|
|
8644
|
+
eventUpdated: "Ereignis aktualisiert",
|
|
8645
|
+
updateFailed: "Ereignis konnte nicht aktualisiert werden",
|
|
8636
8646
|
addCalendarFailed: "Kalender konnte nicht hinzugefügt werden",
|
|
8637
8647
|
addCalendarFromUrl: "Kalender per URL hinzufügen",
|
|
8638
8648
|
added: "Hinzugefügt",
|
|
@@ -8808,6 +8818,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8808
8818
|
},
|
|
8809
8819
|
eventForm: {
|
|
8810
8820
|
addCalendar: "カレンダーを追加",
|
|
8821
|
+
eventUpdated: "予定を更新しました",
|
|
8822
|
+
updateFailed: "予定を更新できませんでした",
|
|
8811
8823
|
addCalendarFailed: "カレンダーを追加できませんでした",
|
|
8812
8824
|
addCalendarFromUrl: "URL からカレンダーを追加",
|
|
8813
8825
|
added: "追加済み",
|
|
@@ -8978,6 +8990,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8978
8990
|
},
|
|
8979
8991
|
eventForm: {
|
|
8980
8992
|
addCalendar: "캘린더 추가",
|
|
8993
|
+
eventUpdated: "이벤트가 업데이트되었습니다",
|
|
8994
|
+
updateFailed: "이벤트를 업데이트하지 못했습니다",
|
|
8981
8995
|
addCalendarFailed: "캘린더를 추가하지 못했습니다",
|
|
8982
8996
|
addCalendarFromUrl: "URL에서 캘린더 추가",
|
|
8983
8997
|
added: "추가됨",
|
|
@@ -9151,6 +9165,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
9151
9165
|
},
|
|
9152
9166
|
eventForm: {
|
|
9153
9167
|
addCalendar: "Adicionar calendário",
|
|
9168
|
+
eventUpdated: "Evento atualizado",
|
|
9169
|
+
updateFailed: "Falha ao atualizar evento",
|
|
9154
9170
|
addCalendarFailed: "Falha ao adicionar calendário",
|
|
9155
9171
|
addCalendarFromUrl: "Adicionar calendário por URL",
|
|
9156
9172
|
added: "Adicionado",
|
|
@@ -9323,6 +9339,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
9323
9339
|
},
|
|
9324
9340
|
eventForm: {
|
|
9325
9341
|
addCalendar: "कैलेंडर जोड़ें",
|
|
9342
|
+
eventUpdated: "इवेंट अपडेट हो गया",
|
|
9343
|
+
updateFailed: "इवेंट अपडेट नहीं हो सका",
|
|
9326
9344
|
addCalendarFailed: "कैलेंडर जोड़ने में विफल",
|
|
9327
9345
|
addCalendarFromUrl: "URL से कैलेंडर जोड़ें",
|
|
9328
9346
|
added: "जोड़ा गया",
|
|
@@ -9494,6 +9512,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
9494
9512
|
},
|
|
9495
9513
|
eventForm: {
|
|
9496
9514
|
addCalendar: "إضافة تقويم",
|
|
9515
|
+
eventUpdated: "تم تحديث الحدث",
|
|
9516
|
+
updateFailed: "فشل تحديث الحدث",
|
|
9497
9517
|
addCalendarFailed: "فشلت إضافة التقويم",
|
|
9498
9518
|
addCalendarFromUrl: "إضافة تقويم من URL",
|
|
9499
9519
|
added: "تمت الإضافة",
|
|
@@ -154,6 +154,27 @@ const LIST_EVENT_TYPES = [
|
|
|
154
154
|
];
|
|
155
155
|
const GOOGLE_READ_CONCURRENCY = 4;
|
|
156
156
|
|
|
157
|
+
export class CalendarMoveRollbackError extends Error {
|
|
158
|
+
readonly code = "CALENDAR_MOVE_ROLLBACK_FAILED" as const;
|
|
159
|
+
readonly cause: unknown;
|
|
160
|
+
readonly replacementId: string;
|
|
161
|
+
readonly destinationAccountEmail: string;
|
|
162
|
+
|
|
163
|
+
constructor(
|
|
164
|
+
replacementId: string,
|
|
165
|
+
destinationAccountEmail: string,
|
|
166
|
+
cause: unknown,
|
|
167
|
+
) {
|
|
168
|
+
super(
|
|
169
|
+
`Calendar move cleanup failed after Google created destination event "${replacementId}" in calendar "${destinationAccountEmail}". The destination may still exist; inspect or delete it before retrying.`,
|
|
170
|
+
);
|
|
171
|
+
this.name = "CalendarMoveRollbackError";
|
|
172
|
+
this.cause = cause;
|
|
173
|
+
this.replacementId = replacementId;
|
|
174
|
+
this.destinationAccountEmail = destinationAccountEmail;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
157
178
|
async function mapWithConcurrency<T, R>(
|
|
158
179
|
values: T[],
|
|
159
180
|
map: (value: T) => Promise<R>,
|
|
@@ -1261,6 +1282,86 @@ export async function createEvent(
|
|
|
1261
1282
|
};
|
|
1262
1283
|
}
|
|
1263
1284
|
|
|
1285
|
+
export async function moveEvent(
|
|
1286
|
+
googleEventId: string,
|
|
1287
|
+
options: {
|
|
1288
|
+
sourceAccount: GoogleAccountSelection;
|
|
1289
|
+
destinationAccount: GoogleAccountSelection;
|
|
1290
|
+
sendUpdates?: "all" | "none";
|
|
1291
|
+
},
|
|
1292
|
+
): Promise<{
|
|
1293
|
+
id?: string;
|
|
1294
|
+
htmlLink?: string;
|
|
1295
|
+
meetLink?: string;
|
|
1296
|
+
conferenceData?: CalendarEvent["conferenceData"];
|
|
1297
|
+
}> {
|
|
1298
|
+
const sourceEvent = await getEvent(googleEventId, options.sourceAccount);
|
|
1299
|
+
if (sourceEvent.status === "cancelled") {
|
|
1300
|
+
throw new Error("Cancelled events cannot be moved.");
|
|
1301
|
+
}
|
|
1302
|
+
if (
|
|
1303
|
+
sourceEvent.eventType &&
|
|
1304
|
+
!["default", "outOfOffice", "focusTime", "workingLocation"].includes(
|
|
1305
|
+
sourceEvent.eventType,
|
|
1306
|
+
)
|
|
1307
|
+
) {
|
|
1308
|
+
throw new Error("This Google Calendar event type cannot be moved.");
|
|
1309
|
+
}
|
|
1310
|
+
if (sourceEvent.recurrence?.length && !sourceEvent.recurringEventId) {
|
|
1311
|
+
throw new Error(
|
|
1312
|
+
"Recurring series masters cannot be moved; move a single occurrence instead.",
|
|
1313
|
+
);
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
const replacement = await createEvent(
|
|
1317
|
+
{
|
|
1318
|
+
...sourceEvent,
|
|
1319
|
+
id: "",
|
|
1320
|
+
googleEventId: undefined,
|
|
1321
|
+
recurringEventId: undefined,
|
|
1322
|
+
accountEmail: options.destinationAccount.accountEmail,
|
|
1323
|
+
attendees: sourceEvent.attendees?.filter((attendee) => !attendee.self),
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
account: options.destinationAccount,
|
|
1327
|
+
addGoogleMeet: Boolean(
|
|
1328
|
+
sourceEvent.hangoutLink ||
|
|
1329
|
+
sourceEvent.conferenceData?.entryPoints?.some(
|
|
1330
|
+
(entry) => entry.entryPointType === "video",
|
|
1331
|
+
),
|
|
1332
|
+
),
|
|
1333
|
+
sendUpdates: options.sendUpdates,
|
|
1334
|
+
},
|
|
1335
|
+
);
|
|
1336
|
+
|
|
1337
|
+
if (!replacement.id) {
|
|
1338
|
+
throw new Error("Google did not return an id for the moved event.");
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
try {
|
|
1342
|
+
await deleteEvent(googleEventId, options.sourceAccount, {
|
|
1343
|
+
scope: "single",
|
|
1344
|
+
sendUpdates: options.sendUpdates,
|
|
1345
|
+
});
|
|
1346
|
+
} catch (error) {
|
|
1347
|
+
try {
|
|
1348
|
+
await deleteEvent(replacement.id, options.destinationAccount, {
|
|
1349
|
+
scope: "single",
|
|
1350
|
+
sendUpdates: options.sendUpdates === "all" ? "all" : "none",
|
|
1351
|
+
});
|
|
1352
|
+
} catch (cleanupError) {
|
|
1353
|
+
throw new CalendarMoveRollbackError(
|
|
1354
|
+
replacement.id,
|
|
1355
|
+
options.destinationAccount.accountEmail,
|
|
1356
|
+
cleanupError,
|
|
1357
|
+
);
|
|
1358
|
+
}
|
|
1359
|
+
throw error;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
return replacement;
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1264
1365
|
export async function updateEvent(
|
|
1265
1366
|
googleEventId: string,
|
|
1266
1367
|
event: Partial<CalendarEvent>,
|
|
@@ -83,6 +83,12 @@ const INITIAL_TOOL_NAMES = [
|
|
|
83
83
|
|
|
84
84
|
export default createAgentChatPlugin({
|
|
85
85
|
appId: "calendar",
|
|
86
|
+
// A delegated (A2A) turn served from the foreground gets the 40s
|
|
87
|
+
// serverless wall, and "I ran out of time before finishing this step"
|
|
88
|
+
// was 39% of this fleet's failed inbound A2A tasks — clustered at
|
|
89
|
+
// 35-46s, the wall to the second. Opting in routes the task to the
|
|
90
|
+
// background worker, as content, slides and analytics already do.
|
|
91
|
+
durableBackgroundRuns: true,
|
|
86
92
|
initialToolNames: INITIAL_TOOL_NAMES,
|
|
87
93
|
connectorCatalog: [...CALENDAR_CONNECTOR_CATALOG],
|
|
88
94
|
// Enable sandboxed JavaScript execution so Calendar agents can fetch,
|
|
@@ -109,7 +115,7 @@ Provider-specific Calendar actions are shortcuts, not limits. If a first-class a
|
|
|
109
115
|
- \`pnpm action search-events --query "term" --from YYYY-MM-DD --to YYYY-MM-DD\` — Convenience bounded search by title, attendees, organizer, location, or description. For relationship history, all-calendar discovery, exact attendee/domain search, or custom pagination, prefer provider-api-request with provider=google_calendar.
|
|
110
116
|
- \`pnpm action provider-api-catalog\` / \`provider-api-docs\` / \`provider-api-request\` — Inspect and call the real Google Calendar, Apollo, Gong, HubSpot, and Pylon APIs directly. For Google Calendar events.list pagination use provider=google_calendar, path=/calendars/primary/events, query={...}, fetchAllPages={cursorPath:"nextPageToken",cursorParam:"pageToken",itemsPath:"items"}. For large relationship-history scans, pass stageAs and pagination={nextCursorPath:"nextPageToken",cursorParam:"pageToken",maxPages:N} with itemsPath="items", then use query-staged-dataset.
|
|
111
117
|
- \`pnpm action create-event --title "..." --start "ISO" --end "ISO"\` — Create a new event. Use \`--eventType outOfOffice\` for OOO, \`--eventType focusTime\` for focus time, \`--eventType workingLocation\` for working location, \`--transparency transparent\` to show as Free, \`--visibility private\` for private events, \`--startTimeZone America/Los_Angeles\` for timezone anchoring, \`--colorId 9\` for Google event color, \`--reminders '[{"method":"popup","minutes":10}]'\` for alerts, and \`--attachments '[{"fileUrl":"https://...","title":"Agenda"}]'\` for Drive/HTTPS file links.
|
|
112
|
-
- \`pnpm action update-event --id "google-..." --transparency opaque|transparent --visibility default|public|private --reminderMinutes 10 --addAttendees "alice@example.com" --scope single|all\` — Update event availability, visibility, reminders, timezone, color, attachments, recurrence, guests,
|
|
118
|
+
- \`pnpm action update-event --id "google-..." --transparency opaque|transparent --visibility default|public|private --reminderMinutes 10 --addAttendees "alice@example.com" --scope single|all\` — Update event availability, visibility, reminders, timezone, color, attachments, recurrence, guests, generated video links, or move an existing event between connected account calendars with \`--accountEmail <current> --targetAccountEmail <destination>\`. A move recreates the event on the destination and removes the source; do not combine it with other event field changes. Use \`addAttendees\` when inviting more people so existing RSVP metadata is preserved. Pass attendee objects with \`optional:true\` to mark optional guests. Use \`--scope all\` to update an entire recurring series from one occurrence, but use \`scope: single\` when moving an event.
|
|
113
119
|
- \`pnpm action navigate --view=calendar --calendarViewMode=day\` — Navigate the UI (day/week/month views, dates)
|
|
114
120
|
- \`pnpm action navigate --view=calendar --date=YYYY-MM-DD\` — Navigate to a specific date
|
|
115
121
|
- \`pnpm action navigate --view=availability\` — Show availability settings
|