@agent-native/core 0.151.2 → 0.152.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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/analytics/actions/bigquery-query.ts +21 -0
- package/corpus/templates/analytics/app/components/ConnectionTestStatus.tsx +65 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +3 -3
- package/corpus/templates/analytics/app/pages/DataSources.tsx +15 -37
- package/corpus/templates/analytics/app/root.tsx +0 -1
- package/corpus/templates/analytics/changelog/2026-08-11-analytics-custom-blocks-keep-loading-with-legacy-bigquery-action.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-11-analytics-routes-company-knowledge-and-slack-context-questio.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/analytics/public/manifest.json +0 -1
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +5 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/assets/app/root.tsx +0 -1
- package/corpus/templates/assets/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/assets/public/manifest.json +0 -1
- package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/brain/app/root.tsx +0 -1
- package/corpus/templates/brain/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/brain/public/manifest.json +0 -1
- package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +0 -53
- package/corpus/templates/calendar/app/i18n-data.ts +0 -80
- package/corpus/templates/calendar/app/root.tsx +0 -1
- package/corpus/templates/calendar/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-11-google-calendar-connection-buttons-now-open-the-sign-in-flow.md +6 -0
- package/corpus/templates/calendar/public/manifest.json +0 -1
- package/corpus/templates/calendar/server/plugins/auth.ts +0 -10
- package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/chat/app/root.tsx +0 -1
- package/corpus/templates/chat/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/chat/public/manifest.json +0 -1
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +1 -1
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +6 -0
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +20 -3
- package/corpus/templates/clips/app/i18n/en-US.ts +4 -4
- package/corpus/templates/clips/app/root.tsx +0 -1
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -3
- package/corpus/templates/clips/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-clips-desktop-settings-are-now-easier-to-scan-with-a-wider-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-google-calendar-connections-from-meetings-now-open-directly.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-recording-viewers-can-comment-and-react.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-system-audio-recording-now-lives-inside-the-microphone-menu-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-11-timestamped-comments-stay-on-the-video-for-three-seconds-wh.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +773 -1001
- package/corpus/templates/clips/desktop/src/components/MediaDeviceRow.tsx +15 -27
- package/corpus/templates/clips/desktop/src/styles.css +364 -5
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +1 -1
- package/corpus/templates/clips/public/manifest.json +0 -1
- package/corpus/templates/content/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/content/AGENTS.md +3 -0
- package/corpus/templates/content/actions/resolve-content-landing.ts +120 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +9 -0
- package/corpus/templates/content/app/i18n-data.ts +58 -0
- package/corpus/templates/content/app/lib/content-landing.ts +22 -0
- package/corpus/templates/content/app/root.tsx +0 -1
- package/corpus/templates/content/app/routes/_app._index.tsx +36 -26
- package/corpus/templates/content/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/content/changelog/2026-08-11-content-opens-your-last-page-on-return-and-gives-new-users-a.md +6 -0
- package/corpus/templates/content/docs/product/capabilities/content.workspace.session-restore.md +7 -1
- package/corpus/templates/content/parity/matrix.md +1 -0
- package/corpus/templates/content/parity/matrix.ts +22 -0
- package/corpus/templates/content/public/manifest.json +0 -1
- package/corpus/templates/content/shared/content-landing.ts +17 -0
- package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/crm/app/root.tsx +0 -1
- package/corpus/templates/crm/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/crm/public/manifest.json +0 -1
- package/corpus/templates/design/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/design/app/i18n/en-US.ts +5 -0
- package/corpus/templates/design/app/root.tsx +0 -1
- package/corpus/templates/design/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/design/changelog/2026-08-11-design-sharing-now-identifies-viewers-who-can-add-review-com.md +6 -0
- package/corpus/templates/design/public/manifest.json +0 -1
- package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/dispatch/AGENTS.md +9 -0
- package/corpus/templates/dispatch/actions/list-dispatch-usage-metrics.ts +5 -19
- package/corpus/templates/dispatch/actions/view-screen.ts +10 -3
- package/corpus/templates/dispatch/app/root.tsx +0 -1
- package/corpus/templates/dispatch/app/routes/settings.tsx +13 -1
- package/corpus/templates/dispatch/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-clicking-the-dispatch-logo-returns-to-the-overview-page.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-dispatch-no-longer-links-to-itself-from-the-app-switcher.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-dispatch-settings-now-link-directly-to-admin.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-dispatch-shows-usage-trends-recent-prompts-and-an-agent-revi.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-11-human-friendly-app-names.md +6 -0
- package/corpus/templates/dispatch/public/manifest.json +0 -1
- package/corpus/templates/dispatch/server/lib/identity-sso.ts +432 -158
- package/corpus/templates/dispatch/server/plugins/identity-sso.ts +204 -123
- package/corpus/templates/dispatch/server/plugins/setup-dispatch.ts +1 -0
- package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/factory/app/root.tsx +0 -1
- package/corpus/templates/factory/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/factory/public/manifest.json +0 -1
- package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/forms/app/root.tsx +0 -1
- package/corpus/templates/forms/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/forms/public/manifest.json +0 -1
- package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/mail/app/root.tsx +0 -1
- package/corpus/templates/mail/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-11-google-sign-in-now-opens-the-gmail-connection-flow-directly.md +6 -0
- package/corpus/templates/mail/public/manifest.json +0 -1
- package/corpus/templates/mail/server/plugins/auth.ts +0 -10
- package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/plan/app/i18n/en-US.ts +2 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +6 -0
- package/corpus/templates/plan/app/root.tsx +0 -1
- package/corpus/templates/plan/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/plan/changelog/2026-08-11-plan-sharing-now-identifies-viewers-who-can-add-comments.md +6 -0
- package/corpus/templates/plan/public/manifest.json +0 -1
- package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +6 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +2 -0
- package/corpus/templates/slides/app/root.tsx +0 -1
- package/corpus/templates/slides/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-share-dialog-uses-commenter-terminology.md +6 -0
- package/corpus/templates/slides/public/manifest.json +0 -1
- package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +1 -1
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/tasks/app/root.tsx +0 -1
- package/corpus/templates/tasks/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/corpus/templates/tasks/public/manifest.json +0 -1
- package/dist/agent/production-agent.js +1 -22
- package/dist/agent/run-manager.d.ts +7 -0
- package/dist/agent/run-manager.js +46 -3
- package/dist/agent/tool-approval-migrations.d.ts +40 -0
- package/dist/agent/tool-approval-migrations.js +51 -0
- package/dist/agent/tool-approval-store.js +5 -20
- package/dist/cli/templates-meta.js +2 -2
- package/dist/client/AgentPanel.js +10 -1
- package/dist/client/AssistantChat.d.ts +3 -0
- package/dist/client/AssistantChat.js +148 -140
- package/dist/client/agent-page/AgentTabsPage.js +2 -2
- package/dist/client/chat/attachment-adapters.js +8 -2
- package/dist/client/chat/tool-call-display.d.ts +1 -0
- package/dist/client/chat/tool-call-display.js +3 -1
- package/dist/client/chat-first.js +11 -5
- package/dist/client/hooks/index.d.ts +1 -1
- package/dist/client/hooks/index.js +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +3 -1
- package/dist/client/org/OrgSwitcher.js +22 -16
- package/dist/client/org/WorkspaceNotice.js +3 -1
- package/dist/client/resources/index.d.ts +1 -1
- package/dist/client/resources/index.js +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts +1 -0
- package/dist/client/resources/use-mcp-servers.js +14 -0
- package/dist/client/settings/AccountSettingsCard.js +8 -4
- package/dist/client/settings/SettingsPanel.js +46 -13
- package/dist/client/settings/SettingsTabsPage.js +8 -3
- package/dist/client/sharing/ShareButton.d.ts +7 -1
- package/dist/client/sharing/ShareButton.js +14 -7
- package/dist/client/sharing/ShareDialog.js +5 -1
- package/dist/client/sharing/useShareButtonController.d.ts +4 -0
- package/dist/client/sharing/useShareButtonController.js +15 -0
- package/dist/client/sharing/useShareDialogController.d.ts +7 -0
- package/dist/client/sharing/useShareDialogController.js +14 -0
- package/dist/client/sse-event-processor.js +37 -0
- package/dist/client/use-session.d.ts +2 -0
- package/dist/client/use-session.js +69 -5
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.js +1 -1
- package/dist/file-upload/pre-upload-attachments.d.ts +3 -4
- package/dist/file-upload/pre-upload-attachments.js +65 -17
- package/dist/ingestion/index.d.ts +1 -0
- package/dist/ingestion/index.js +1 -0
- package/dist/ingestion/office.d.ts +3 -3
- package/dist/ingestion/office.js +24 -2
- package/dist/ingestion/spreadsheet.d.ts +41 -0
- package/dist/ingestion/spreadsheet.js +172 -0
- package/dist/integrations/adapters/slack.js +7 -3
- package/dist/localization/default-messages.d.ts +3 -0
- package/dist/localization/default-messages.js +3 -0
- package/dist/mcp/embed-app.js +20 -9
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +6 -6
- package/dist/oauth-tokens/migrations.d.ts +8 -0
- package/dist/oauth-tokens/migrations.js +36 -0
- package/dist/org/workspace-url.d.ts +8 -0
- package/dist/org/workspace-url.js +26 -2
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/agent-chat-plugin.js +16 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.d.ts +0 -11
- package/dist/server/auth.js +37 -20
- package/dist/server/better-auth-migrations.js +23 -0
- package/dist/server/email-template.d.ts +5 -0
- package/dist/server/email-template.js +9 -0
- package/dist/server/embed-route.js +17 -5
- package/dist/server/identity-sso-store.d.ts +40 -66
- package/dist/server/identity-sso-store.js +187 -150
- package/dist/server/identity-sso.d.ts +17 -73
- package/dist/server/identity-sso.js +294 -297
- package/dist/server/onboarding-html.d.ts +0 -12
- package/dist/server/onboarding-html.js +46 -269
- package/dist/server/release-migrations.js +8 -0
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/workspace-app-id.d.ts +2 -0
- package/dist/shared/workspace-app-id.js +10 -0
- package/dist/sharing/actions/share-resource.d.ts +1 -0
- package/dist/sharing/actions/share-resource.js +20 -5
- package/dist/templates/chat/.agents/skills/sharing/SKILL.md +1 -1
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/dist/templates/chat/app/root.tsx +0 -1
- package/dist/templates/chat/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/dist/templates/chat/public/manifest.json +0 -1
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/dist/templates/default/app/root.tsx +0 -1
- package/dist/templates/default/public/manifest.json +0 -1
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +22 -11
- package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/docs/content/cross-app-sso.mdx +85 -27
- package/docs/content/template-mail.mdx +0 -6
- package/package.json +4 -3
- package/src/templates/chat/.agents/skills/sharing/SKILL.md +1 -1
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/src/templates/chat/app/root.tsx +0 -1
- package/src/templates/chat/changelog/2026-08-11-browser-no-longer-offers-desktop-install.md +6 -0
- package/src/templates/chat/public/manifest.json +0 -1
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/src/templates/default/app/root.tsx +0 -1
- package/src/templates/default/public/manifest.json +0 -1
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +22 -11
- package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +24 -0
- package/corpus/templates/calendar/changelog/2026-06-23-added-a-heads-up-explaining-google-s-app-not-verified-screen.md +0 -6
- package/corpus/templates/clips/app/components/meetings/google-oauth-identity-notice.tsx +0 -51
- package/corpus/templates/clips/changelog/2026-07-30-google-calendar-warning.md +0 -6
|
@@ -84,6 +84,30 @@ private web access, invent an importer, add fake OAuth, or scrape a logged-in
|
|
|
84
84
|
page. If the needed context is not visible, ask for an export, transcript, or
|
|
85
85
|
attachment and treat that artifact as imported source material.
|
|
86
86
|
|
|
87
|
+
### Spreadsheet sources
|
|
88
|
+
|
|
89
|
+
Spreadsheet attachments are valid source artifacts for this workflow:
|
|
90
|
+
|
|
91
|
+
- CSV files can be read as tabular text. XLS and XLSX uploads are parsed into
|
|
92
|
+
bounded worksheet metadata and representative rows when the host supports
|
|
93
|
+
workbook ingestion. Treat the preview as untrusted user data, preserve the
|
|
94
|
+
workbook name and worksheet names, and record row/column limits and any
|
|
95
|
+
truncation in the source brief.
|
|
96
|
+
- A Google Sheets URL is a live provider source, not proof that the sheet is
|
|
97
|
+
readable. Use an authenticated Google Sheets/Drive connection and the
|
|
98
|
+
provider API catalog/docs/request path to read only the required sheet or
|
|
99
|
+
range. If that connection is unavailable, ask for a CSV/XLSX export or the
|
|
100
|
+
required connection; do not use a public export URL to bypass access.
|
|
101
|
+
- Decide whether the generated app needs a one-time snapshot or a refreshable
|
|
102
|
+
source. For a snapshot, pass bounded sample context and provenance to the
|
|
103
|
+
Builder handoff. For a live source, preserve the provider/file identity,
|
|
104
|
+
worksheet or range, and refresh semantics, then implement a scoped action for
|
|
105
|
+
reads or refreshes. Never copy workbook bytes, base64 data, credentials, or a
|
|
106
|
+
full unbounded sheet into SQL, application state, or the handoff prompt.
|
|
107
|
+
- Do not claim the app imported the whole workbook when only a preview was
|
|
108
|
+
available. Keep unreadable, partial, and failed source states distinct from
|
|
109
|
+
an empty sheet.
|
|
110
|
+
|
|
87
111
|
For local code-agent runtimes, deliver a fresh app in a new directory,
|
|
88
112
|
implement the repeatable workflow with buttons and agent handoffs, start its dev
|
|
89
113
|
server, verify the main path, and continue through build/deployment handoff. Do
|
|
@@ -234,7 +234,6 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
234
234
|
dangerouslySetInnerHTML={{ __html: LOCALE_INIT_SCRIPT }}
|
|
235
235
|
/>
|
|
236
236
|
<link rel="icon" type="image/svg+xml" href={appPath("/favicon.svg")} />
|
|
237
|
-
<link rel="manifest" href={appPath("/manifest.json")} />
|
|
238
237
|
<meta name="theme-color" content="#3B82F6" />
|
|
239
238
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
240
239
|
<meta
|
|
@@ -36,16 +36,6 @@ export default createAuthPlugin({
|
|
|
36
36
|
runLocalCommand:
|
|
37
37
|
"npx @agent-native/core@latest create my-mail-app --template mail",
|
|
38
38
|
},
|
|
39
|
-
googleSignInNotice: {
|
|
40
|
-
host: "mail.agent-native.com",
|
|
41
|
-
title: "Google may show a warning",
|
|
42
|
-
body: [
|
|
43
|
-
"You'll see this screen because this demo uses Agent-Native's Google app, not a Google-reviewed public app.",
|
|
44
|
-
"It's safe to continue: click Advanced, then “Go to … (unsafe)” to finish signing in.",
|
|
45
|
-
],
|
|
46
|
-
continueLabel: "Continue to Google",
|
|
47
|
-
cancelLabel: "Run locally",
|
|
48
|
-
},
|
|
49
39
|
// Gmail Pub/Sub push notifications POST here from Google's servers — no
|
|
50
40
|
// user session. The handler itself verifies the OIDC token when
|
|
51
41
|
// GMAIL_PUSH_AUDIENCE is configured.
|
|
@@ -189,7 +189,7 @@ The framework auto-mounts these actions in every template — no per-template bo
|
|
|
189
189
|
|
|
190
190
|
| Action | Args | Purpose |
|
|
191
191
|
| -------------------------- | ------------------------------------------------------------------------------ | ----------------------------------------- |
|
|
192
|
-
| `share-resource` | `resourceType, resourceId, principalType, principalId, role, notify?, resourceUrl?` | Grant a user or org access. `notify` defaults to true for individual user shares; `resourceUrl` can provide the direct app link
|
|
192
|
+
| `share-resource` | `resourceType, resourceId, principalType, principalId, role, notify?, resourceUrl?, message?` | Grant a user or org access. `notify` defaults to true for individual user shares; `resourceUrl` can provide the direct app link and `message` an optional short note for the notification email. |
|
|
193
193
|
| `unshare-resource` | `resourceType, resourceId, principalType, principalId` | Revoke access. |
|
|
194
194
|
| `list-resource-shares` | `resourceType, resourceId` | Current visibility + all share grants. |
|
|
195
195
|
| `set-resource-visibility` | `resourceType, resourceId, visibility` | Change to `private` / `org` / `public`. |
|
|
@@ -84,6 +84,30 @@ private web access, invent an importer, add fake OAuth, or scrape a logged-in
|
|
|
84
84
|
page. If the needed context is not visible, ask for an export, transcript, or
|
|
85
85
|
attachment and treat that artifact as imported source material.
|
|
86
86
|
|
|
87
|
+
### Spreadsheet sources
|
|
88
|
+
|
|
89
|
+
Spreadsheet attachments are valid source artifacts for this workflow:
|
|
90
|
+
|
|
91
|
+
- CSV files can be read as tabular text. XLS and XLSX uploads are parsed into
|
|
92
|
+
bounded worksheet metadata and representative rows when the host supports
|
|
93
|
+
workbook ingestion. Treat the preview as untrusted user data, preserve the
|
|
94
|
+
workbook name and worksheet names, and record row/column limits and any
|
|
95
|
+
truncation in the source brief.
|
|
96
|
+
- A Google Sheets URL is a live provider source, not proof that the sheet is
|
|
97
|
+
readable. Use an authenticated Google Sheets/Drive connection and the
|
|
98
|
+
provider API catalog/docs/request path to read only the required sheet or
|
|
99
|
+
range. If that connection is unavailable, ask for a CSV/XLSX export or the
|
|
100
|
+
required connection; do not use a public export URL to bypass access.
|
|
101
|
+
- Decide whether the generated app needs a one-time snapshot or a refreshable
|
|
102
|
+
source. For a snapshot, pass bounded sample context and provenance to the
|
|
103
|
+
Builder handoff. For a live source, preserve the provider/file identity,
|
|
104
|
+
worksheet or range, and refresh semantics, then implement a scoped action for
|
|
105
|
+
reads or refreshes. Never copy workbook bytes, base64 data, credentials, or a
|
|
106
|
+
full unbounded sheet into SQL, application state, or the handoff prompt.
|
|
107
|
+
- Do not claim the app imported the whole workbook when only a preview was
|
|
108
|
+
available. Keep unreadable, partial, and failed source states distinct from
|
|
109
|
+
an empty sheet.
|
|
110
|
+
|
|
87
111
|
For local code-agent runtimes, deliver a fresh app in a new directory,
|
|
88
112
|
implement the repeatable workflow with buttons and agent handoffs, start its dev
|
|
89
113
|
server, verify the main path, and continue through build/deployment handoff. Do
|
|
@@ -377,6 +377,8 @@ const messages = {
|
|
|
377
377
|
"Private by default. Invite people, share with your org, or set Public for anyone-with-link review.",
|
|
378
378
|
peopleAccess: "People with {{noun}} access",
|
|
379
379
|
generalAccess: "General {{noun}} access",
|
|
380
|
+
commenterRoleLabel: "Commenter",
|
|
381
|
+
commenterRoleDescription: "Can view and add comments",
|
|
380
382
|
shareAria: "Share {{noun}}",
|
|
381
383
|
share: "Share {{noun}}",
|
|
382
384
|
shareThis: "Share this {{noun}}",
|
|
@@ -6218,6 +6218,12 @@ function PlanShareControl({
|
|
|
6218
6218
|
shareUrlPlacement="top"
|
|
6219
6219
|
peopleAccessLabel={t("plansPage.share.peopleAccess", { noun })}
|
|
6220
6220
|
generalAccessLabel={t("plansPage.share.generalAccess", { noun })}
|
|
6221
|
+
roleCopy={{
|
|
6222
|
+
viewer: {
|
|
6223
|
+
label: t("plansPage.share.commenterRoleLabel"),
|
|
6224
|
+
description: t("plansPage.share.commenterRoleDescription"),
|
|
6225
|
+
},
|
|
6226
|
+
}}
|
|
6221
6227
|
accessNote={buildShareAccessNote(t, noun)}
|
|
6222
6228
|
visibilityCopy={buildShareVisibilityCopy(t, noun)}
|
|
6223
6229
|
trigger="icon"
|
|
@@ -111,7 +111,6 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
111
111
|
suppressHydrationWarning
|
|
112
112
|
dangerouslySetInnerHTML={{ __html: LOCALE_INIT_SCRIPT }}
|
|
113
113
|
/>
|
|
114
|
-
<link rel="manifest" href={appPath("/manifest.json")} />
|
|
115
114
|
<meta name="theme-color" content="#71717A" />
|
|
116
115
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
117
116
|
<meta
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
"short_name": "Plan",
|
|
4
4
|
"description": "Generate and review coding-agent plans with diagrams, wireframes, prototypes, annotations, sharing, and feedback.",
|
|
5
5
|
"start_url": ".",
|
|
6
|
-
"display": "standalone",
|
|
7
6
|
"background_color": "#111111",
|
|
8
7
|
"theme_color": "#71717A",
|
|
9
8
|
"icons": [
|
|
@@ -189,7 +189,7 @@ The framework auto-mounts these actions in every template — no per-template bo
|
|
|
189
189
|
|
|
190
190
|
| Action | Args | Purpose |
|
|
191
191
|
| -------------------------- | ------------------------------------------------------------------------------ | ----------------------------------------- |
|
|
192
|
-
| `share-resource` | `resourceType, resourceId, principalType, principalId, role, notify?, resourceUrl?` | Grant a user or org access. `notify` defaults to true for individual user shares; `resourceUrl` can provide the direct app link
|
|
192
|
+
| `share-resource` | `resourceType, resourceId, principalType, principalId, role, notify?, resourceUrl?, message?` | Grant a user or org access. `notify` defaults to true for individual user shares; `resourceUrl` can provide the direct app link and `message` an optional short note for the notification email. |
|
|
193
193
|
| `unshare-resource` | `resourceType, resourceId, principalType, principalId` | Revoke access. |
|
|
194
194
|
| `list-resource-shares` | `resourceType, resourceId` | Current visibility + all share grants. |
|
|
195
195
|
| `set-resource-visibility` | `resourceType, resourceId, visibility` | Change to `private` / `org` / `public`. |
|
|
@@ -84,6 +84,30 @@ private web access, invent an importer, add fake OAuth, or scrape a logged-in
|
|
|
84
84
|
page. If the needed context is not visible, ask for an export, transcript, or
|
|
85
85
|
attachment and treat that artifact as imported source material.
|
|
86
86
|
|
|
87
|
+
### Spreadsheet sources
|
|
88
|
+
|
|
89
|
+
Spreadsheet attachments are valid source artifacts for this workflow:
|
|
90
|
+
|
|
91
|
+
- CSV files can be read as tabular text. XLS and XLSX uploads are parsed into
|
|
92
|
+
bounded worksheet metadata and representative rows when the host supports
|
|
93
|
+
workbook ingestion. Treat the preview as untrusted user data, preserve the
|
|
94
|
+
workbook name and worksheet names, and record row/column limits and any
|
|
95
|
+
truncation in the source brief.
|
|
96
|
+
- A Google Sheets URL is a live provider source, not proof that the sheet is
|
|
97
|
+
readable. Use an authenticated Google Sheets/Drive connection and the
|
|
98
|
+
provider API catalog/docs/request path to read only the required sheet or
|
|
99
|
+
range. If that connection is unavailable, ask for a CSV/XLSX export or the
|
|
100
|
+
required connection; do not use a public export URL to bypass access.
|
|
101
|
+
- Decide whether the generated app needs a one-time snapshot or a refreshable
|
|
102
|
+
source. For a snapshot, pass bounded sample context and provenance to the
|
|
103
|
+
Builder handoff. For a live source, preserve the provider/file identity,
|
|
104
|
+
worksheet or range, and refresh semantics, then implement a scoped action for
|
|
105
|
+
reads or refreshes. Never copy workbook bytes, base64 data, credentials, or a
|
|
106
|
+
full unbounded sheet into SQL, application state, or the handoff prompt.
|
|
107
|
+
- Do not claim the app imported the whole workbook when only a preview was
|
|
108
|
+
available. Keep unreadable, partial, and failed source states distinct from
|
|
109
|
+
an empty sheet.
|
|
110
|
+
|
|
87
111
|
For local code-agent runtimes, deliver a fresh app in a new directory,
|
|
88
112
|
implement the repeatable workflow with buttons and agent handoffs, start its dev
|
|
89
113
|
server, verify the main path, and continue through build/deployment handoff. Do
|
|
@@ -824,6 +824,12 @@ export default function EditorToolbar({
|
|
|
824
824
|
resourceType="deck"
|
|
825
825
|
resourceId={deckId}
|
|
826
826
|
resourceTitle={deckTitle}
|
|
827
|
+
roleCopy={{
|
|
828
|
+
viewer: {
|
|
829
|
+
label: t("editorToolbar.commenterRoleLabel"),
|
|
830
|
+
description: t("editorToolbar.commenterRoleDescription"),
|
|
831
|
+
},
|
|
832
|
+
}}
|
|
827
833
|
shareUrl={primaryShareLink.url}
|
|
828
834
|
shareUrlLabel={primaryShareLink.label}
|
|
829
835
|
shareUrlDescription={primaryShareLink.description}
|
|
@@ -205,6 +205,8 @@ const messages = {
|
|
|
205
205
|
usingDesignSystem: "Using {{title}}",
|
|
206
206
|
usingLinkedDesignSystem: "Using a linked design system",
|
|
207
207
|
viewOnly: "View only",
|
|
208
|
+
commenterRoleLabel: "Commenter",
|
|
209
|
+
commenterRoleDescription: "Can view and add comments",
|
|
208
210
|
slideSettings: "Slide settings",
|
|
209
211
|
layout: "Layout",
|
|
210
212
|
background: "Background",
|
|
@@ -163,7 +163,6 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
163
163
|
dangerouslySetInnerHTML={{ __html: LOCALE_INIT_SCRIPT }}
|
|
164
164
|
/>
|
|
165
165
|
<link rel="icon" type="image/svg+xml" href={appPath("/favicon.svg")} />
|
|
166
|
-
<link rel="manifest" href={appPath("/manifest.json")} />
|
|
167
166
|
<meta name="theme-color" content="#EC4899" />
|
|
168
167
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
169
168
|
<meta
|
|
@@ -189,7 +189,7 @@ The framework auto-mounts these actions in every template — no per-template bo
|
|
|
189
189
|
|
|
190
190
|
| Action | Args | Purpose |
|
|
191
191
|
| -------------------------- | ------------------------------------------------------------------------------ | ----------------------------------------- |
|
|
192
|
-
| `share-resource` | `resourceType, resourceId, principalType, principalId, role, notify?, resourceUrl?` | Grant a user or org access. `notify` defaults to true for individual user shares; `resourceUrl` can provide the direct app link
|
|
192
|
+
| `share-resource` | `resourceType, resourceId, principalType, principalId, role, notify?, resourceUrl?, message?` | Grant a user or org access. `notify` defaults to true for individual user shares; `resourceUrl` can provide the direct app link and `message` an optional short note for the notification email. |
|
|
193
193
|
| `unshare-resource` | `resourceType, resourceId, principalType, principalId` | Revoke access. |
|
|
194
194
|
| `list-resource-shares` | `resourceType, resourceId` | Current visibility + all share grants. |
|
|
195
195
|
| `set-resource-visibility` | `resourceType, resourceId, visibility` | Change to `private` / `org` / `public`. |
|
|
@@ -84,6 +84,30 @@ private web access, invent an importer, add fake OAuth, or scrape a logged-in
|
|
|
84
84
|
page. If the needed context is not visible, ask for an export, transcript, or
|
|
85
85
|
attachment and treat that artifact as imported source material.
|
|
86
86
|
|
|
87
|
+
### Spreadsheet sources
|
|
88
|
+
|
|
89
|
+
Spreadsheet attachments are valid source artifacts for this workflow:
|
|
90
|
+
|
|
91
|
+
- CSV files can be read as tabular text. XLS and XLSX uploads are parsed into
|
|
92
|
+
bounded worksheet metadata and representative rows when the host supports
|
|
93
|
+
workbook ingestion. Treat the preview as untrusted user data, preserve the
|
|
94
|
+
workbook name and worksheet names, and record row/column limits and any
|
|
95
|
+
truncation in the source brief.
|
|
96
|
+
- A Google Sheets URL is a live provider source, not proof that the sheet is
|
|
97
|
+
readable. Use an authenticated Google Sheets/Drive connection and the
|
|
98
|
+
provider API catalog/docs/request path to read only the required sheet or
|
|
99
|
+
range. If that connection is unavailable, ask for a CSV/XLSX export or the
|
|
100
|
+
required connection; do not use a public export URL to bypass access.
|
|
101
|
+
- Decide whether the generated app needs a one-time snapshot or a refreshable
|
|
102
|
+
source. For a snapshot, pass bounded sample context and provenance to the
|
|
103
|
+
Builder handoff. For a live source, preserve the provider/file identity,
|
|
104
|
+
worksheet or range, and refresh semantics, then implement a scoped action for
|
|
105
|
+
reads or refreshes. Never copy workbook bytes, base64 data, credentials, or a
|
|
106
|
+
full unbounded sheet into SQL, application state, or the handoff prompt.
|
|
107
|
+
- Do not claim the app imported the whole workbook when only a preview was
|
|
108
|
+
available. Keep unreadable, partial, and failed source states distinct from
|
|
109
|
+
an empty sheet.
|
|
110
|
+
|
|
87
111
|
For local code-agent runtimes, deliver a fresh app in a new directory,
|
|
88
112
|
implement the repeatable workflow with buttons and agent handoffs, start its dev
|
|
89
113
|
server, verify the main path, and continue through build/deployment handoff. Do
|
|
@@ -85,7 +85,6 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
85
85
|
suppressHydrationWarning
|
|
86
86
|
dangerouslySetInnerHTML={{ __html: LOCALE_INIT_SCRIPT }}
|
|
87
87
|
/>
|
|
88
|
-
<link rel="manifest" href={appPath("/manifest.json")} />
|
|
89
88
|
<meta name="theme-color" content="#18181B" />
|
|
90
89
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
91
90
|
<meta
|
|
@@ -36,7 +36,7 @@ import { EngineError } from "./engine/types.js";
|
|
|
36
36
|
import { getDefaultMaxIterations, getDefaultMaxRunInputTokens, MAX_AGENT_MAX_ITERATIONS, MIN_AGENT_MAX_ITERATIONS, normalizeMaxIterations, normalizeMaxRunInputTokens, readAgentLoopSettings, } from "./loop-settings.js";
|
|
37
37
|
import { maybeCompactThread, buildObservationalContext, hasObservationalMemory, serializeObservationalMemoryBlock, } from "./observational-memory/index.js";
|
|
38
38
|
import { ProcessorChain, TripWire, toolCallsFromContent, } from "./processors.js";
|
|
39
|
-
import { startRun, subscribeToRun, getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortTurnDurably, tryClaimRunSlot, isHostedRuntime, resolveRunSoftTimeoutMs, resolveRunToolTimeoutCeilingMs, } from "./run-manager.js";
|
|
39
|
+
import { startRun, subscribeToRun, getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortTurnDurably, tryClaimRunSlot, isHostedRuntime, resolveRunSoftTimeoutMs, resolveRunToolTimeoutCeilingMs, endsAfterCompletedToolWithoutAssistantFinal, } from "./run-manager.js";
|
|
40
40
|
import { writeLedgerEntry, readLedgerEntry, clearLedgerForThread, insertRun, insertRunEvent, isTurnAborted, markRunAborted, updateRunHeartbeat, updateRunStatusIfRunning, setRunError, setRunTerminalReason, claimBackgroundRun, readBackgroundRunClaim, recordRunDiagnostic, countRunsForTurn, RUN_DIAG_STAGE, UNCLAIMED_BACKGROUND_RUN_GRACE_MS, } from "./run-store.js";
|
|
41
41
|
import { buildCurrentTimeUserContext } from "./runtime-context.js";
|
|
42
42
|
import { consumeAgentToolApproval, createAgentToolApproval, } from "./tool-approval-store.js";
|
|
@@ -4970,27 +4970,6 @@ export function lastUnfinishedPreparingActionToolFromEvents(events) {
|
|
|
4970
4970
|
}
|
|
4971
4971
|
return latest?.tool;
|
|
4972
4972
|
}
|
|
4973
|
-
function endsAfterCompletedToolWithoutAssistantFinal(run) {
|
|
4974
|
-
let completedToolAfterLastAssistantText = false;
|
|
4975
|
-
for (const { event } of run.events) {
|
|
4976
|
-
if (event.type === "text" && event.text.trim().length > 0) {
|
|
4977
|
-
completedToolAfterLastAssistantText = false;
|
|
4978
|
-
continue;
|
|
4979
|
-
}
|
|
4980
|
-
if (event.type === "tool_done" && event.isError !== true) {
|
|
4981
|
-
completedToolAfterLastAssistantText = true;
|
|
4982
|
-
continue;
|
|
4983
|
-
}
|
|
4984
|
-
if (event.type === "clear" ||
|
|
4985
|
-
event.type === "error" ||
|
|
4986
|
-
event.type === "missing_api_key" ||
|
|
4987
|
-
event.type === "auto_continue" ||
|
|
4988
|
-
event.type === "loop_limit") {
|
|
4989
|
-
completedToolAfterLastAssistantText = false;
|
|
4990
|
-
}
|
|
4991
|
-
}
|
|
4992
|
-
return completedToolAfterLastAssistantText;
|
|
4993
|
-
}
|
|
4994
4973
|
function lastUnfinishedPreparingActionTool(run) {
|
|
4995
4974
|
return lastUnfinishedPreparingActionToolFromEvents(run.events.map(({ event }) => event));
|
|
4996
4975
|
}
|
|
@@ -317,6 +317,13 @@ export declare function isHostedRuntime(): boolean;
|
|
|
317
317
|
export declare function resolveRunSoftTimeoutMs(overrideMs?: number, options?: ResolveRunSoftTimeoutOptions): number;
|
|
318
318
|
export declare function resolveCompletedRunRetentionMs(): number;
|
|
319
319
|
export declare function resolveErroredRunRetentionMs(): number;
|
|
320
|
+
/**
|
|
321
|
+
* A completed tool with no later assistant text is an unfinished turn, not a
|
|
322
|
+
* successful terminal response. Keep this predicate beside the run-manager's
|
|
323
|
+
* terminal synthesis so the run-manager and production continuation paths use
|
|
324
|
+
* the same boundary evidence.
|
|
325
|
+
*/
|
|
326
|
+
export declare function endsAfterCompletedToolWithoutAssistantFinal(run: ActiveRun): boolean;
|
|
320
327
|
/**
|
|
321
328
|
* Start a new agent run in the background.
|
|
322
329
|
* `runFn` receives a `send` callback and an `AbortSignal`.
|
|
@@ -416,6 +416,34 @@ function isTerminalRunEvent(event) {
|
|
|
416
416
|
event.type === "loop_limit" ||
|
|
417
417
|
event.type === "auto_continue");
|
|
418
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* A completed tool with no later assistant text is an unfinished turn, not a
|
|
421
|
+
* successful terminal response. Keep this predicate beside the run-manager's
|
|
422
|
+
* terminal synthesis so the run-manager and production continuation paths use
|
|
423
|
+
* the same boundary evidence.
|
|
424
|
+
*/
|
|
425
|
+
export function endsAfterCompletedToolWithoutAssistantFinal(run) {
|
|
426
|
+
let completedToolAfterLastAssistantText = false;
|
|
427
|
+
for (const { event } of run.events) {
|
|
428
|
+
if (event.type === "text" && event.text.trim().length > 0) {
|
|
429
|
+
completedToolAfterLastAssistantText = false;
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
if (event.type === "tool_done" && event.isError !== true) {
|
|
433
|
+
completedToolAfterLastAssistantText =
|
|
434
|
+
event.chatUI === undefined && event.mcpApp === undefined;
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
if (event.type === "clear" ||
|
|
438
|
+
event.type === "error" ||
|
|
439
|
+
event.type === "missing_api_key" ||
|
|
440
|
+
event.type === "auto_continue" ||
|
|
441
|
+
event.type === "loop_limit") {
|
|
442
|
+
completedToolAfterLastAssistantText = false;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return completedToolAfterLastAssistantText;
|
|
446
|
+
}
|
|
419
447
|
function terminalEventForcesErroredStatus(event) {
|
|
420
448
|
return event?.type === "error" || event?.type === "missing_api_key";
|
|
421
449
|
}
|
|
@@ -1220,6 +1248,20 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
|
|
|
1220
1248
|
terminalEventForcesErroredStatus(terminalEvent)
|
|
1221
1249
|
? "errored"
|
|
1222
1250
|
: "completed";
|
|
1251
|
+
const shouldAutoContinueAfterCompletedTool = finalStatus === "completed" &&
|
|
1252
|
+
endsAfterCompletedToolWithoutAssistantFinal(run) &&
|
|
1253
|
+
(!terminalEventForCompletion ||
|
|
1254
|
+
(terminalEventForCompletion.event.type === "done" &&
|
|
1255
|
+
terminalEventForCompletion.event.reason !== "user"));
|
|
1256
|
+
const completedToolContinuationEvent = shouldAutoContinueAfterCompletedTool
|
|
1257
|
+
? {
|
|
1258
|
+
type: "auto_continue",
|
|
1259
|
+
reason: "stream_ended",
|
|
1260
|
+
}
|
|
1261
|
+
: null;
|
|
1262
|
+
if (completedToolContinuationEvent) {
|
|
1263
|
+
terminalEvent = completedToolContinuationEvent;
|
|
1264
|
+
}
|
|
1223
1265
|
const terminalReason = terminalReasonForRun(finalStatus, terminalEvent, run.abortReason, completionError);
|
|
1224
1266
|
// A run that stopped at a continuation boundary did not finish, so it is
|
|
1225
1267
|
// not `completed`. Persisted directly here rather than left for
|
|
@@ -1247,8 +1289,9 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
|
|
|
1247
1289
|
// insertRunEvent's `ON CONFLICT (run_id, seq) DO NOTHING`, so the
|
|
1248
1290
|
// client would never see the terminal/continuation signal. We always
|
|
1249
1291
|
// re-stamp the seq at emit time (max-seq+1) just below.
|
|
1250
|
-
const
|
|
1251
|
-
? (
|
|
1292
|
+
const terminalEventToEmit = finalStatus === "completed"
|
|
1293
|
+
? (completedToolContinuationEvent ??
|
|
1294
|
+
terminalEventForCompletion?.event ?? { type: "done" })
|
|
1252
1295
|
: terminalEventForCompletion?.event.type === "error" ||
|
|
1253
1296
|
terminalEventForCompletion?.event.type === "missing_api_key"
|
|
1254
1297
|
? terminalEventForCompletion.event
|
|
@@ -1274,7 +1317,7 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
|
|
|
1274
1317
|
// terminal event was stashed.
|
|
1275
1318
|
const terminal = {
|
|
1276
1319
|
seq: run.events.length,
|
|
1277
|
-
event:
|
|
1320
|
+
event: terminalEventToEmit,
|
|
1278
1321
|
};
|
|
1279
1322
|
try {
|
|
1280
1323
|
await emitRunEvent(terminal, { surfacePersistenceError: true });
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { MigrationEntry } from "../db/migrations.js";
|
|
2
|
+
export declare const AGENT_TOOL_APPROVAL_MIGRATIONS_TABLE = "_agent_tool_approval_migrations";
|
|
3
|
+
export declare const AGENT_TOOL_APPROVAL_TABLE_SQL: {
|
|
4
|
+
readonly postgres: `CREATE TABLE IF NOT EXISTS agent_tool_approvals (
|
|
5
|
+
id TEXT PRIMARY KEY,
|
|
6
|
+
owner_email TEXT NOT NULL,
|
|
7
|
+
org_id TEXT,
|
|
8
|
+
thread_id TEXT,
|
|
9
|
+
turn_id TEXT,
|
|
10
|
+
tool_name TEXT NOT NULL,
|
|
11
|
+
call_id TEXT NOT NULL,
|
|
12
|
+
approval_key_hash TEXT NOT NULL,
|
|
13
|
+
status TEXT NOT NULL,
|
|
14
|
+
expires_at BIGINT NOT NULL,
|
|
15
|
+
consumed_at BIGINT,
|
|
16
|
+
created_at BIGINT NOT NULL,
|
|
17
|
+
updated_at BIGINT NOT NULL
|
|
18
|
+
)`;
|
|
19
|
+
readonly sqlite: `CREATE TABLE IF NOT EXISTS agent_tool_approvals (
|
|
20
|
+
id TEXT PRIMARY KEY,
|
|
21
|
+
owner_email TEXT NOT NULL,
|
|
22
|
+
org_id TEXT,
|
|
23
|
+
thread_id TEXT,
|
|
24
|
+
turn_id TEXT,
|
|
25
|
+
tool_name TEXT NOT NULL,
|
|
26
|
+
call_id TEXT NOT NULL,
|
|
27
|
+
approval_key_hash TEXT NOT NULL,
|
|
28
|
+
status TEXT NOT NULL,
|
|
29
|
+
expires_at INTEGER NOT NULL,
|
|
30
|
+
consumed_at INTEGER,
|
|
31
|
+
created_at INTEGER NOT NULL,
|
|
32
|
+
updated_at INTEGER NOT NULL
|
|
33
|
+
)`;
|
|
34
|
+
};
|
|
35
|
+
export declare const AGENT_TOOL_APPROVAL_INDEX_SQL = "CREATE INDEX IF NOT EXISTS idx_agent_tool_approvals_binding\n ON agent_tool_approvals(owner_email, org_id, thread_id, tool_name, call_id, status)";
|
|
36
|
+
/**
|
|
37
|
+
* Durable approval grants are created and consumed on request paths, but their
|
|
38
|
+
* schema belongs to the release migration boundary in production.
|
|
39
|
+
*/
|
|
40
|
+
export declare const AGENT_TOOL_APPROVAL_MIGRATIONS: MigrationEntry[];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const AGENT_TOOL_APPROVAL_MIGRATIONS_TABLE = "_agent_tool_approval_migrations";
|
|
2
|
+
export const AGENT_TOOL_APPROVAL_TABLE_SQL = {
|
|
3
|
+
postgres: `CREATE TABLE IF NOT EXISTS agent_tool_approvals (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
owner_email TEXT NOT NULL,
|
|
6
|
+
org_id TEXT,
|
|
7
|
+
thread_id TEXT,
|
|
8
|
+
turn_id TEXT,
|
|
9
|
+
tool_name TEXT NOT NULL,
|
|
10
|
+
call_id TEXT NOT NULL,
|
|
11
|
+
approval_key_hash TEXT NOT NULL,
|
|
12
|
+
status TEXT NOT NULL,
|
|
13
|
+
expires_at BIGINT NOT NULL,
|
|
14
|
+
consumed_at BIGINT,
|
|
15
|
+
created_at BIGINT NOT NULL,
|
|
16
|
+
updated_at BIGINT NOT NULL
|
|
17
|
+
)`,
|
|
18
|
+
sqlite: `CREATE TABLE IF NOT EXISTS agent_tool_approvals (
|
|
19
|
+
id TEXT PRIMARY KEY,
|
|
20
|
+
owner_email TEXT NOT NULL,
|
|
21
|
+
org_id TEXT,
|
|
22
|
+
thread_id TEXT,
|
|
23
|
+
turn_id TEXT,
|
|
24
|
+
tool_name TEXT NOT NULL,
|
|
25
|
+
call_id TEXT NOT NULL,
|
|
26
|
+
approval_key_hash TEXT NOT NULL,
|
|
27
|
+
status TEXT NOT NULL,
|
|
28
|
+
expires_at INTEGER NOT NULL,
|
|
29
|
+
consumed_at INTEGER,
|
|
30
|
+
created_at INTEGER NOT NULL,
|
|
31
|
+
updated_at INTEGER NOT NULL
|
|
32
|
+
)`,
|
|
33
|
+
};
|
|
34
|
+
export const AGENT_TOOL_APPROVAL_INDEX_SQL = `CREATE INDEX IF NOT EXISTS idx_agent_tool_approvals_binding
|
|
35
|
+
ON agent_tool_approvals(owner_email, org_id, thread_id, tool_name, call_id, status)`;
|
|
36
|
+
/**
|
|
37
|
+
* Durable approval grants are created and consumed on request paths, but their
|
|
38
|
+
* schema belongs to the release migration boundary in production.
|
|
39
|
+
*/
|
|
40
|
+
export const AGENT_TOOL_APPROVAL_MIGRATIONS = [
|
|
41
|
+
{
|
|
42
|
+
version: 1,
|
|
43
|
+
name: "agent-tool-approvals-table-and-index",
|
|
44
|
+
sql: {
|
|
45
|
+
postgres: `${AGENT_TOOL_APPROVAL_TABLE_SQL.postgres};
|
|
46
|
+
${AGENT_TOOL_APPROVAL_INDEX_SQL}`,
|
|
47
|
+
sqlite: `${AGENT_TOOL_APPROVAL_TABLE_SQL.sqlite};
|
|
48
|
+
${AGENT_TOOL_APPROVAL_INDEX_SQL}`,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
];
|
|
@@ -1,37 +1,22 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
-
import { getDbExec,
|
|
2
|
+
import { getDbExec, isPostgres, retryOnDdlRace } from "../db/client.js";
|
|
3
3
|
import { ensureIndexExists, ensureTableExists } from "../db/ddl-guard.js";
|
|
4
|
+
import { AGENT_TOOL_APPROVAL_INDEX_SQL, AGENT_TOOL_APPROVAL_TABLE_SQL, } from "./tool-approval-migrations.js";
|
|
4
5
|
const APPROVAL_TTL_MS = 15 * 60_000;
|
|
5
6
|
const APPROVAL_CLEANUP_AGE_MS = 24 * 60 * 60_000;
|
|
6
7
|
let initPromise;
|
|
7
8
|
async function ensureAgentToolApprovalTable() {
|
|
8
9
|
if (!initPromise) {
|
|
9
10
|
initPromise = (async () => {
|
|
10
|
-
const createSql =
|
|
11
|
-
id TEXT PRIMARY KEY,
|
|
12
|
-
owner_email TEXT NOT NULL,
|
|
13
|
-
org_id TEXT,
|
|
14
|
-
thread_id TEXT,
|
|
15
|
-
turn_id TEXT,
|
|
16
|
-
tool_name TEXT NOT NULL,
|
|
17
|
-
call_id TEXT NOT NULL,
|
|
18
|
-
approval_key_hash TEXT NOT NULL,
|
|
19
|
-
status TEXT NOT NULL,
|
|
20
|
-
expires_at ${intType()} NOT NULL,
|
|
21
|
-
consumed_at ${intType()},
|
|
22
|
-
created_at ${intType()} NOT NULL,
|
|
23
|
-
updated_at ${intType()} NOT NULL
|
|
24
|
-
)`;
|
|
25
|
-
const indexSql = `CREATE INDEX IF NOT EXISTS idx_agent_tool_approvals_binding
|
|
26
|
-
ON agent_tool_approvals(owner_email, org_id, thread_id, tool_name, call_id, status)`;
|
|
11
|
+
const createSql = AGENT_TOOL_APPROVAL_TABLE_SQL[isPostgres() ? "postgres" : "sqlite"];
|
|
27
12
|
if (isPostgres()) {
|
|
28
13
|
await ensureTableExists("agent_tool_approvals", createSql);
|
|
29
|
-
await ensureIndexExists("idx_agent_tool_approvals_binding",
|
|
14
|
+
await ensureIndexExists("idx_agent_tool_approvals_binding", AGENT_TOOL_APPROVAL_INDEX_SQL);
|
|
30
15
|
return;
|
|
31
16
|
}
|
|
32
17
|
const client = getDbExec();
|
|
33
18
|
await retryOnDdlRace(() => client.execute(createSql));
|
|
34
|
-
await retryOnDdlRace(() => client.execute(
|
|
19
|
+
await retryOnDdlRace(() => client.execute(AGENT_TOOL_APPROVAL_INDEX_SQL));
|
|
35
20
|
})().catch((error) => {
|
|
36
21
|
initPromise = undefined;
|
|
37
22
|
throw error;
|
|
@@ -46,8 +46,8 @@ export const TEMPLATES = [
|
|
|
46
46
|
label: "Plan",
|
|
47
47
|
hint: "Structured visual plans and PR recaps with diagrams, wireframes, prototypes, annotations, and sharing",
|
|
48
48
|
icon: "FileText",
|
|
49
|
-
color: "#
|
|
50
|
-
colorRgb: "
|
|
49
|
+
color: "#2F6FED",
|
|
50
|
+
colorRgb: "47 111 237",
|
|
51
51
|
devPort: 8105,
|
|
52
52
|
prodUrl: "https://plan.agent-native.com",
|
|
53
53
|
defaultMode: "prod",
|