@agent-native/core 0.96.0 → 0.97.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/README.md +6 -0
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +39 -0
- package/corpus/core/docs/content/audit-log.mdx +2 -1
- package/corpus/core/docs/content/automations.mdx +7 -7
- package/corpus/core/docs/content/creating-templates.mdx +1 -1
- package/corpus/core/docs/content/internationalization.mdx +2 -1
- package/corpus/core/docs/content/locales/ar-SA/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/ar-SA/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/ar-SA/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/ar-SA/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/package-lifecycle.mdx +19 -0
- package/corpus/core/docs/content/locales/ar-SA/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/ar-SA/security.mdx +8 -0
- package/corpus/core/docs/content/locales/de-DE/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/de-DE/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/de-DE/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/de-DE/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/package-lifecycle.mdx +22 -0
- package/corpus/core/docs/content/locales/de-DE/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/de-DE/security.mdx +8 -0
- package/corpus/core/docs/content/locales/es-ES/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/es-ES/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/es-ES/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/es-ES/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/package-lifecycle.mdx +22 -0
- package/corpus/core/docs/content/locales/es-ES/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/es-ES/security.mdx +8 -0
- package/corpus/core/docs/content/locales/fr-FR/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/fr-FR/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/fr-FR/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/fr-FR/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/package-lifecycle.mdx +21 -0
- package/corpus/core/docs/content/locales/fr-FR/sandbox-adapters.mdx +19 -8
- package/corpus/core/docs/content/locales/fr-FR/security.mdx +8 -0
- package/corpus/core/docs/content/locales/hi-IN/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/hi-IN/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/hi-IN/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/hi-IN/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/package-lifecycle.mdx +20 -0
- package/corpus/core/docs/content/locales/hi-IN/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/hi-IN/security.mdx +8 -0
- package/corpus/core/docs/content/locales/ja-JP/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/ja-JP/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/ja-JP/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/ja-JP/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/package-lifecycle.mdx +21 -0
- package/corpus/core/docs/content/locales/ja-JP/sandbox-adapters.mdx +17 -6
- package/corpus/core/docs/content/locales/ja-JP/security.mdx +8 -0
- package/corpus/core/docs/content/locales/ko-KR/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/ko-KR/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/ko-KR/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/ko-KR/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/package-lifecycle.mdx +20 -0
- package/corpus/core/docs/content/locales/ko-KR/sandbox-adapters.mdx +17 -6
- package/corpus/core/docs/content/locales/ko-KR/security.mdx +8 -0
- package/corpus/core/docs/content/locales/pt-BR/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/pt-BR/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/pt-BR/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/pt-BR/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/package-lifecycle.mdx +21 -0
- package/corpus/core/docs/content/locales/pt-BR/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/pt-BR/security.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-CN/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/zh-CN/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/zh-CN/getting-started.mdx +6 -4
- package/corpus/core/docs/content/locales/zh-CN/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/package-lifecycle.mdx +19 -0
- package/corpus/core/docs/content/locales/zh-CN/sandbox-adapters.mdx +17 -6
- package/corpus/core/docs/content/locales/zh-CN/security.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-TW/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/zh-TW/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/zh-TW/getting-started.mdx +6 -4
- package/corpus/core/docs/content/locales/zh-TW/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/package-lifecycle.mdx +19 -0
- package/corpus/core/docs/content/locales/zh-TW/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/zh-TW/security.mdx +8 -0
- package/corpus/core/docs/content/package-lifecycle.mdx +51 -0
- package/corpus/core/docs/content/sandbox-adapters.mdx +16 -5
- package/corpus/core/package.json +9 -2
- package/corpus/core/src/a2a/auth-policy.ts +33 -0
- package/corpus/core/src/agent/durable-background.ts +15 -7
- package/corpus/core/src/agent/run-store.ts +13 -4
- package/corpus/core/src/audit/actions/export-audit-events.ts +162 -0
- package/corpus/core/src/audit/store.ts +8 -3
- package/corpus/core/src/audit/types.ts +3 -0
- package/corpus/core/src/cli/doctor.ts +396 -0
- package/corpus/core/src/cli/index.ts +56 -0
- package/corpus/core/src/cli/info.ts +3 -3
- package/corpus/core/src/cli/package-lifecycle.ts +821 -0
- package/corpus/core/src/client/agent-chat-adapter.ts +9 -9
- package/corpus/core/src/guards/db-tool-scoping.ts +129 -0
- package/corpus/core/src/guards/index.ts +23 -0
- package/corpus/core/src/guards/no-drizzle-push.ts +116 -0
- package/corpus/core/src/guards/no-env-credentials.ts +229 -0
- package/corpus/core/src/guards/no-env-mutation.ts +114 -0
- package/corpus/core/src/guards/no-localhost-fallback.ts +124 -0
- package/corpus/core/src/guards/no-unscoped-credentials.ts +227 -0
- package/corpus/core/src/guards/no-unscoped-queries.ts +834 -0
- package/corpus/core/src/guards/scan-utils.ts +105 -0
- package/corpus/core/src/guards/types.ts +30 -0
- package/corpus/core/src/org/accept-pending.ts +9 -1
- package/corpus/core/src/org/migrations.ts +41 -0
- package/corpus/core/src/package-lifecycle/index.ts +1 -0
- package/corpus/core/src/package-lifecycle/manifest.ts +120 -0
- package/corpus/core/src/provider-api/custom-registry.ts +56 -0
- package/corpus/core/src/provider-api/index.ts +2 -0
- package/corpus/core/src/secrets/storage.ts +47 -27
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +54 -12
- package/corpus/core/src/server/core-routes-plugin.ts +30 -14
- package/corpus/core/src/server/csrf.ts +24 -5
- package/corpus/core/src/server/framework-request-handler.ts +34 -0
- package/corpus/core/src/server/google-realtime-session.ts +1 -36
- package/corpus/core/src/server/poll.ts +24 -2
- package/corpus/core/src/server/realtime-voice.ts +9 -0
- package/corpus/core/src/server/request-origin.ts +63 -0
- package/corpus/core/src/server/transcribe-voice.ts +1 -50
- package/corpus/core/src/templates/default/package.json +2 -2
- package/corpus/core/src/templates/headless/package.json +0 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/package.json +0 -1
- package/corpus/core/src/templates/workspace-root/package.json +0 -1
- package/corpus/core/src/triggers/actions.ts +11 -3
- package/corpus/core/src/triggers/types.ts +7 -1
- package/corpus/templates/analytics/actions/compose-dashboard.ts +65 -37
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +73 -24
- package/corpus/templates/analytics/actions/reorder-dashboard-panels.ts +16 -13
- package/corpus/templates/analytics/actions/update-dashboard.ts +53 -42
- package/corpus/templates/analytics/changelog/2026-07-10-dashboard-edits-from-the-agent-and-the-ui-at-the-same-time-n.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-timed-out-bigquery-jobs-are-now-cancelled-so-they-stop-consu.md +6 -0
- package/corpus/templates/analytics/package.json +1 -2
- package/corpus/templates/analytics/server/lib/bigquery.ts +3 -2
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +154 -11
- package/corpus/templates/assets/package.json +1 -2
- package/corpus/templates/brain/package.json +1 -2
- package/corpus/templates/calendar/package.json +1 -2
- package/corpus/templates/chat/package.json +1 -2
- package/corpus/templates/clips/changelog/2026-07-10-atomic-view-tracking.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +3 -2
- package/corpus/templates/clips/desktop/package.json +6 -4
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +26 -13
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +4 -1
- package/corpus/templates/clips/package.json +1 -2
- package/corpus/templates/clips/server/db/schema.ts +29 -17
- package/corpus/templates/clips/server/plugins/db.ts +8 -0
- package/corpus/templates/clips/server/routes/api/view-event.post.ts +260 -105
- package/corpus/templates/content/.agents/skills/notion-integration/SKILL.md +16 -0
- package/corpus/templates/content/AGENTS.md +72 -62
- package/corpus/templates/content/actions/_content-database-source-adapters.ts +84 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +206 -96
- package/corpus/templates/content/actions/_notion-database-source-adapter.ts +216 -0
- package/corpus/templates/content/actions/_position-utils.ts +76 -0
- package/corpus/templates/content/actions/_property-utils.ts +31 -20
- package/corpus/templates/content/actions/add-database-item.ts +52 -39
- package/corpus/templates/content/actions/attach-content-database-source.ts +95 -11
- package/corpus/templates/content/actions/change-content-database-source-role.ts +24 -1
- package/corpus/templates/content/actions/configure-document-property.ts +36 -27
- package/corpus/templates/content/actions/create-content-database.ts +40 -30
- package/corpus/templates/content/actions/create-document.ts +39 -32
- package/corpus/templates/content/actions/duplicate-document-property.ts +37 -28
- package/corpus/templates/content/actions/list-notion-database-sources.ts +80 -0
- package/corpus/templates/content/actions/move-document.ts +64 -48
- package/corpus/templates/content/actions/refresh-content-database-source.ts +42 -3
- package/corpus/templates/content/actions/share-local-file-document.ts +36 -27
- package/corpus/templates/content/actions/suggest-source-join-key.ts +39 -16
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +89 -23
- package/corpus/templates/content/app/components/editor/database/settings.tsx +1 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +18 -1
- package/corpus/templates/content/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/content/app/i18n-data.ts +40 -0
- package/corpus/templates/content/changelog/2026-07-10-failed-row-creation-and-source-attach-now-show-an-error-inst.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-items-added-at-the-same-time-no-longer-end-up-with-identical.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-notion-databases-can-add-read-only-details-to-content-tables.md +6 -0
- package/corpus/templates/content/package.json +1 -2
- package/corpus/templates/content/parity/matrix.md +25 -25
- package/corpus/templates/content/parity/matrix.ts +1 -0
- package/corpus/templates/content/server/routes/api/documents/[id]/move.patch.ts +43 -26
- package/corpus/templates/content/shared/api.ts +16 -1
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +8 -4
- package/corpus/templates/design/AGENTS.md +12 -2
- package/corpus/templates/design/DEVELOPING.md +10 -6
- package/corpus/templates/design/actions/apply-visual-edit.ts +191 -6
- package/corpus/templates/design/actions/duplicate-design.ts +31 -25
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +5 -1
- package/corpus/templates/design/changelog/2026-07-10-duplicating-a-design-can-no-longer-produce-a-copy-with-missi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-local-visual-edits-can-now-save-safe-leaf-text-class-and.md +6 -0
- package/corpus/templates/design/package.json +1 -1
- package/corpus/templates/design/shared/local-jsx-visual-edit.ts +388 -0
- package/corpus/templates/dispatch/package.json +1 -2
- package/corpus/templates/forms/actions/patch-form-fields.ts +82 -44
- package/corpus/templates/forms/changelog/2026-07-10-simultaneous-edits-to-different-form-fields-no-longer-overwr.md +6 -0
- package/corpus/templates/forms/package.json +1 -2
- package/corpus/templates/macros/package.json +1 -2
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +3 -1
- package/corpus/templates/mail/changelog/2026-07-10-fixed-calendar-rsvp-buttons-in-emails-firing-duplicate-respo.md +6 -0
- package/corpus/templates/mail/package.json +1 -2
- package/corpus/templates/plan/actions/restore-plan-version.ts +126 -96
- package/corpus/templates/plan/changelog/2026-07-10-restoring-a-plan-version-can-no-longer-leave-a-plan-half-res.md +6 -0
- package/corpus/templates/plan/package.json +1 -2
- package/corpus/templates/plan/server/plans.ts +9 -2
- package/corpus/templates/slides/actions/list-decks.ts +28 -0
- package/corpus/templates/slides/app/components/deck/MermaidRenderer.tsx +41 -26
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +4 -8
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +2 -4
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +4 -8
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +5 -12
- package/corpus/templates/slides/app/components/editor/HistoryPanel.tsx +3 -6
- package/corpus/templates/slides/app/components/editor/ImageDropPromptPopover.tsx +3 -6
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +2 -5
- package/corpus/templates/slides/app/context/DeckContext.tsx +47 -4
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +11 -30
- package/corpus/templates/slides/app/pages/Index.tsx +2 -3
- package/corpus/templates/slides/app/root.tsx +0 -5
- package/corpus/templates/slides/changelog/2026-07-10-deck-lists-load-much-faster-and-no-longer-re-download-slide-.md +6 -0
- package/corpus/templates/slides/package.json +1 -2
- package/dist/a2a/auth-policy.d.ts +19 -0
- package/dist/a2a/auth-policy.d.ts.map +1 -1
- package/dist/a2a/auth-policy.js +32 -0
- package/dist/a2a/auth-policy.js.map +1 -1
- package/dist/agent/durable-background.d.ts +8 -5
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +15 -8
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +9 -4
- package/dist/agent/run-store.js.map +1 -1
- package/dist/audit/actions/export-audit-events.d.ts +27 -0
- package/dist/audit/actions/export-audit-events.d.ts.map +1 -0
- package/dist/audit/actions/export-audit-events.js +144 -0
- package/dist/audit/actions/export-audit-events.js.map +1 -0
- package/dist/audit/store.d.ts +1 -0
- package/dist/audit/store.d.ts.map +1 -1
- package/dist/audit/store.js +8 -3
- package/dist/audit/store.js.map +1 -1
- package/dist/audit/types.d.ts +3 -0
- package/dist/audit/types.d.ts.map +1 -1
- package/dist/audit/types.js.map +1 -1
- package/dist/cli/doctor.d.ts +83 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +277 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.js +50 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/info.js +3 -3
- package/dist/cli/info.js.map +1 -1
- package/dist/cli/package-lifecycle.d.ts +50 -0
- package/dist/cli/package-lifecycle.d.ts.map +1 -0
- package/dist/cli/package-lifecycle.js +560 -0
- package/dist/cli/package-lifecycle.js.map +1 -0
- package/dist/client/agent-chat-adapter.js +7 -3
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/guards/db-tool-scoping.d.ts +38 -0
- package/dist/guards/db-tool-scoping.d.ts.map +1 -0
- package/dist/guards/db-tool-scoping.js +114 -0
- package/dist/guards/db-tool-scoping.js.map +1 -0
- package/dist/guards/index.d.ts +23 -0
- package/dist/guards/index.d.ts.map +1 -0
- package/dist/guards/index.js +19 -0
- package/dist/guards/index.js.map +1 -0
- package/dist/guards/no-drizzle-push.d.ts +14 -0
- package/dist/guards/no-drizzle-push.d.ts.map +1 -0
- package/dist/guards/no-drizzle-push.js +97 -0
- package/dist/guards/no-drizzle-push.js.map +1 -0
- package/dist/guards/no-env-credentials.d.ts +36 -0
- package/dist/guards/no-env-credentials.d.ts.map +1 -0
- package/dist/guards/no-env-credentials.js +204 -0
- package/dist/guards/no-env-credentials.js.map +1 -0
- package/dist/guards/no-env-mutation.d.ts +23 -0
- package/dist/guards/no-env-mutation.d.ts.map +1 -0
- package/dist/guards/no-env-mutation.js +90 -0
- package/dist/guards/no-env-mutation.js.map +1 -0
- package/dist/guards/no-localhost-fallback.d.ts +30 -0
- package/dist/guards/no-localhost-fallback.d.ts.map +1 -0
- package/dist/guards/no-localhost-fallback.js +105 -0
- package/dist/guards/no-localhost-fallback.js.map +1 -0
- package/dist/guards/no-unscoped-credentials.d.ts +28 -0
- package/dist/guards/no-unscoped-credentials.d.ts.map +1 -0
- package/dist/guards/no-unscoped-credentials.js +199 -0
- package/dist/guards/no-unscoped-credentials.js.map +1 -0
- package/dist/guards/no-unscoped-queries.d.ts +32 -0
- package/dist/guards/no-unscoped-queries.d.ts.map +1 -0
- package/dist/guards/no-unscoped-queries.js +720 -0
- package/dist/guards/no-unscoped-queries.js.map +1 -0
- package/dist/guards/scan-utils.d.ts +28 -0
- package/dist/guards/scan-utils.d.ts.map +1 -0
- package/dist/guards/scan-utils.js +92 -0
- package/dist/guards/scan-utils.js.map +1 -0
- package/dist/guards/types.d.ts +28 -0
- package/dist/guards/types.d.ts.map +1 -0
- package/dist/guards/types.js +11 -0
- package/dist/guards/types.js.map +1 -0
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +9 -1
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/migrations.d.ts +7 -2
- package/dist/org/migrations.d.ts.map +1 -1
- package/dist/org/migrations.js +41 -0
- package/dist/org/migrations.js.map +1 -1
- package/dist/package-lifecycle/index.d.ts +2 -0
- package/dist/package-lifecycle/index.d.ts.map +1 -0
- package/dist/package-lifecycle/index.js +2 -0
- package/dist/package-lifecycle/index.js.map +1 -0
- package/dist/package-lifecycle/manifest.d.ts +24 -0
- package/dist/package-lifecycle/manifest.d.ts.map +1 -0
- package/dist/package-lifecycle/manifest.js +81 -0
- package/dist/package-lifecycle/manifest.js.map +1 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/custom-registry.d.ts +32 -1
- package/dist/provider-api/custom-registry.d.ts.map +1 -1
- package/dist/provider-api/custom-registry.js +41 -1
- package/dist/provider-api/custom-registry.js.map +1 -1
- package/dist/provider-api/index.d.ts +1 -1
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +1 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +45 -27
- package/dist/secrets/storage.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +47 -13
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +23 -12
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/csrf.js +18 -5
- package/dist/server/csrf.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +34 -0
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-realtime-session.d.ts.map +1 -1
- package/dist/server/google-realtime-session.js +2 -34
- package/dist/server/google-realtime-session.js.map +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +24 -2
- package/dist/server/poll.js.map +1 -1
- package/dist/server/realtime-voice.d.ts.map +1 -1
- package/dist/server/realtime-voice.js +9 -0
- package/dist/server/realtime-voice.js.map +1 -1
- package/dist/server/request-origin.d.ts +10 -0
- package/dist/server/request-origin.d.ts.map +1 -0
- package/dist/server/request-origin.js +60 -0
- package/dist/server/request-origin.js.map +1 -0
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +2 -48
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/templates/default/package.json +2 -2
- package/dist/templates/headless/package.json +0 -1
- package/dist/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
- package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
- package/dist/templates/workspace-core/package.json +0 -1
- package/dist/templates/workspace-root/package.json +0 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +8 -3
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/types.d.ts +7 -1
- package/dist/triggers/types.d.ts.map +1 -1
- package/dist/triggers/types.js.map +1 -1
- package/docs/content/audit-log.mdx +2 -1
- package/docs/content/automations.mdx +7 -7
- package/docs/content/creating-templates.mdx +1 -1
- package/docs/content/internationalization.mdx +2 -1
- package/docs/content/locales/ar-SA/audit-log.mdx +2 -1
- package/docs/content/locales/ar-SA/automations.mdx +7 -7
- package/docs/content/locales/ar-SA/getting-started.mdx +7 -1
- package/docs/content/locales/ar-SA/internationalization.mdx +1 -1
- package/docs/content/locales/ar-SA/package-lifecycle.mdx +19 -0
- package/docs/content/locales/ar-SA/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/ar-SA/security.mdx +8 -0
- package/docs/content/locales/de-DE/audit-log.mdx +2 -1
- package/docs/content/locales/de-DE/automations.mdx +7 -7
- package/docs/content/locales/de-DE/getting-started.mdx +7 -1
- package/docs/content/locales/de-DE/internationalization.mdx +1 -1
- package/docs/content/locales/de-DE/package-lifecycle.mdx +22 -0
- package/docs/content/locales/de-DE/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/de-DE/security.mdx +8 -0
- package/docs/content/locales/es-ES/audit-log.mdx +2 -1
- package/docs/content/locales/es-ES/automations.mdx +7 -7
- package/docs/content/locales/es-ES/getting-started.mdx +7 -1
- package/docs/content/locales/es-ES/internationalization.mdx +1 -1
- package/docs/content/locales/es-ES/package-lifecycle.mdx +22 -0
- package/docs/content/locales/es-ES/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/es-ES/security.mdx +8 -0
- package/docs/content/locales/fr-FR/audit-log.mdx +2 -1
- package/docs/content/locales/fr-FR/automations.mdx +7 -7
- package/docs/content/locales/fr-FR/getting-started.mdx +7 -1
- package/docs/content/locales/fr-FR/internationalization.mdx +1 -1
- package/docs/content/locales/fr-FR/package-lifecycle.mdx +21 -0
- package/docs/content/locales/fr-FR/sandbox-adapters.mdx +19 -8
- package/docs/content/locales/fr-FR/security.mdx +8 -0
- package/docs/content/locales/hi-IN/audit-log.mdx +2 -1
- package/docs/content/locales/hi-IN/automations.mdx +7 -7
- package/docs/content/locales/hi-IN/getting-started.mdx +7 -1
- package/docs/content/locales/hi-IN/internationalization.mdx +1 -1
- package/docs/content/locales/hi-IN/package-lifecycle.mdx +20 -0
- package/docs/content/locales/hi-IN/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/hi-IN/security.mdx +8 -0
- package/docs/content/locales/ja-JP/audit-log.mdx +2 -1
- package/docs/content/locales/ja-JP/automations.mdx +7 -7
- package/docs/content/locales/ja-JP/getting-started.mdx +7 -1
- package/docs/content/locales/ja-JP/internationalization.mdx +1 -1
- package/docs/content/locales/ja-JP/package-lifecycle.mdx +21 -0
- package/docs/content/locales/ja-JP/sandbox-adapters.mdx +17 -6
- package/docs/content/locales/ja-JP/security.mdx +8 -0
- package/docs/content/locales/ko-KR/audit-log.mdx +2 -1
- package/docs/content/locales/ko-KR/automations.mdx +7 -7
- package/docs/content/locales/ko-KR/getting-started.mdx +7 -1
- package/docs/content/locales/ko-KR/internationalization.mdx +1 -1
- package/docs/content/locales/ko-KR/package-lifecycle.mdx +20 -0
- package/docs/content/locales/ko-KR/sandbox-adapters.mdx +17 -6
- package/docs/content/locales/ko-KR/security.mdx +8 -0
- package/docs/content/locales/pt-BR/audit-log.mdx +2 -1
- package/docs/content/locales/pt-BR/automations.mdx +7 -7
- package/docs/content/locales/pt-BR/getting-started.mdx +7 -1
- package/docs/content/locales/pt-BR/internationalization.mdx +1 -1
- package/docs/content/locales/pt-BR/package-lifecycle.mdx +21 -0
- package/docs/content/locales/pt-BR/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/pt-BR/security.mdx +8 -0
- package/docs/content/locales/zh-CN/audit-log.mdx +2 -1
- package/docs/content/locales/zh-CN/automations.mdx +7 -7
- package/docs/content/locales/zh-CN/getting-started.mdx +6 -4
- package/docs/content/locales/zh-CN/internationalization.mdx +1 -1
- package/docs/content/locales/zh-CN/package-lifecycle.mdx +19 -0
- package/docs/content/locales/zh-CN/sandbox-adapters.mdx +17 -6
- package/docs/content/locales/zh-CN/security.mdx +8 -0
- package/docs/content/locales/zh-TW/audit-log.mdx +2 -1
- package/docs/content/locales/zh-TW/automations.mdx +7 -7
- package/docs/content/locales/zh-TW/getting-started.mdx +6 -4
- package/docs/content/locales/zh-TW/internationalization.mdx +1 -1
- package/docs/content/locales/zh-TW/package-lifecycle.mdx +19 -0
- package/docs/content/locales/zh-TW/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/zh-TW/security.mdx +8 -0
- package/docs/content/package-lifecycle.mdx +51 -0
- package/docs/content/sandbox-adapters.mdx +16 -5
- package/package.json +10 -3
- package/src/templates/default/package.json +2 -2
- package/src/templates/headless/package.json +0 -1
- package/src/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
- package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
- package/src/templates/workspace-core/package.json +0 -1
- package/src/templates/workspace-root/package.json +0 -1
- package/corpus/templates/slides/app/components/ui/toast.tsx +0 -1
- package/corpus/templates/slides/app/components/ui/toaster.tsx +0 -1
- package/corpus/templates/slides/app/hooks/use-toast.ts +0 -1
|
@@ -415,3 +415,11 @@ AGENT_NATIVE_KEYS_WORKSPACE_FALLBACK=1
|
|
|
415
415
|
```
|
|
416
416
|
|
|
417
417
|
無論此標誌如何,工作空間範圍的秘密寫入仍然需要組織所有者/管理員角色。
|
|
418
|
+
|
|
419
|
+
## 下一步
|
|
420
|
+
|
|
421
|
+
- [**Authentication**](/docs/authentication) — 本頁所依賴的驗證模式、cookie realm 和工作階段細節
|
|
422
|
+
- [**Multi-Tenancy**](/docs/multi-tenancy) — `org_id` 範圍界定背後的組織成員模型
|
|
423
|
+
- [**Sharing**](/docs/sharing) — 應用於可共用資源的 `ownableColumns()` 和存取守衛模式
|
|
424
|
+
- [**Messaging**](/docs/messaging#env-vars) — 上方清單中提到的每個整合的 webhook 簽名金鑰
|
|
425
|
+
- [**Deployment**](/docs/deployment) — 此清單假定已設定的正式環境變數
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Package Lifecycle
|
|
3
|
+
description: Inspect, add, and eject manifest-driven Agent Native packages safely.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Package lifecycle
|
|
7
|
+
|
|
8
|
+
Reusable Agent Native packages can publish a versioned static
|
|
9
|
+
`agent-native.package.json`. The CLI reads that JSON without executing package
|
|
10
|
+
code and reports the package's actions, schema entry point, skills, secret key
|
|
11
|
+
names, and peer providers.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
agent-native package inspect @agent-native/scheduling
|
|
15
|
+
agent-native package inspect @agent-native/scheduling --json
|
|
16
|
+
agent-native package add @agent-native/scheduling
|
|
17
|
+
agent-native package add @agent-native/scheduling --apply
|
|
18
|
+
agent-native package eject @agent-native/scheduling --apply
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`add` and `eject` are dry-run by default. `--apply` is required before the CLI
|
|
22
|
+
writes files or runs the detected package manager. Use `--root` for a different
|
|
23
|
+
project root; at a workspace root, pass `--app <name>` to select the target app.
|
|
24
|
+
|
|
25
|
+
## Safety and idempotency
|
|
26
|
+
|
|
27
|
+
Before writing, the CLI resolves every contribution and refuses missing or
|
|
28
|
+
ambiguous layouts, existing files with different content, escaping manifest
|
|
29
|
+
paths, and eject targets that already exist. It stages the complete write set,
|
|
30
|
+
uses atomic renames, snapshots package and lock files, and rolls back if the
|
|
31
|
+
package-manager install fails. A provenance record under
|
|
32
|
+
`.agent-native/packages/` makes a repeated add a no-op when generated files are
|
|
33
|
+
unchanged.
|
|
34
|
+
|
|
35
|
+
Inspection and registry staging use static package metadata only. The CLI never
|
|
36
|
+
imports a package's JavaScript manifest and passes `--ignore-scripts` while
|
|
37
|
+
downloading an uninstalled package archive. Reports show credential key names,
|
|
38
|
+
never credential values.
|
|
39
|
+
|
|
40
|
+
## Scheduling pilot
|
|
41
|
+
|
|
42
|
+
`@agent-native/scheduling` is the first package with the generic manifest. Add
|
|
43
|
+
creates action re-export stubs, adds the schema export, copies its agent skills,
|
|
44
|
+
records the dependency, and reports required secret names and providers.
|
|
45
|
+
Eject copies the published Scheduling source to `packages/scheduling`, switches
|
|
46
|
+
the dependency to `workspace:*`, and preserves canonical
|
|
47
|
+
`@agent-native/scheduling` imports so workspace resolution selects the local
|
|
48
|
+
copy.
|
|
49
|
+
|
|
50
|
+
Ejecting other packages, including Pinpoint, is intentionally refused until the
|
|
51
|
+
Scheduling pilot has proven the contract.
|
|
@@ -106,6 +106,10 @@ The seam lives in core at `packages/core/src/coding-tools/sandbox/` — `adapter
|
|
|
106
106
|
path: "index.ts",
|
|
107
107
|
note: "selection: getSandboxAdapter() / registerSandboxAdapter()",
|
|
108
108
|
},
|
|
109
|
+
{
|
|
110
|
+
path: "background.ts",
|
|
111
|
+
note: "durable queue marker and background execution lifecycle",
|
|
112
|
+
},
|
|
109
113
|
{
|
|
110
114
|
path: "local-child-process-adapter.ts",
|
|
111
115
|
note: "the default backend — locked-down Node child process",
|
|
@@ -189,12 +193,17 @@ registerSandboxAdapter(adapter) → AGENT_NATIVE_SANDBOX → local default
|
|
|
189
193
|
|
|
190
194
|
#### `AGENT_NATIVE_SANDBOX` env var {#env}
|
|
191
195
|
|
|
192
|
-
Selects a built-in adapter by id.
|
|
196
|
+
Selects a built-in adapter by id. Both `local` (the default) and `background` are wired; unknown values fall back to local rather than failing the run.
|
|
193
197
|
|
|
194
198
|
```bash
|
|
195
|
-
AGENT_NATIVE_SANDBOX=local
|
|
199
|
+
AGENT_NATIVE_SANDBOX=local # the default — explicit
|
|
200
|
+
AGENT_NATIVE_SANDBOX=background # enqueue every run-code call durably
|
|
196
201
|
```
|
|
197
202
|
|
|
203
|
+
`background` stores the raw code in `sandbox_executions` and returns an `executionId` with `status: "queued"` immediately. A signed self-dispatch starts a fresh serverless invocation; long-lived Node starts detached in-process work; status polling and the periodic sweep redrive lost dispatches or expired leases. Poll the execution later for its persisted result.
|
|
204
|
+
|
|
205
|
+
`BackgroundQueueAdapter` is a durable queue marker, not the executor. Queued work uses a registered non-queued execution adapter when one is available; otherwise it falls back to the local child process. Selecting `background` alone does not provide remote or container isolation, and it does not make an edge runtime compatible with `node:child_process`.
|
|
206
|
+
|
|
198
207
|
#### `registerSandboxAdapter()` {#register}
|
|
199
208
|
|
|
200
209
|
A host process overrides the backend for all subsequent `run-code` invocations through the seam's `index.ts` — for example, to run every call in a remote container:
|
|
@@ -219,13 +228,15 @@ registerSandboxAdapter(new RemoteSandboxAdapter());
|
|
|
219
228
|
|
|
220
229
|
### The seam for a durable runner {#durable}
|
|
221
230
|
|
|
222
|
-
|
|
231
|
+
The built-in `background` adapter already provides durable queuing and a fresh execution budget, while actual execution still uses a non-queued adapter or the local child-process fallback. A separately registered remote or isolated adapter (Docker or a Vercel-Sandbox-style runner) can provide a different execution boundary and can also execute per-call background work.
|
|
232
|
+
|
|
233
|
+
Such an adapter would:
|
|
223
234
|
|
|
224
235
|
1. Implement `SandboxAdapter.run` against an out-of-process runtime.
|
|
225
236
|
2. Tunnel the loopback bridge (or proxy bridge calls back to the parent).
|
|
226
|
-
3.
|
|
237
|
+
3. Supply remote or container isolation independently of the shipped durable queue lifecycle.
|
|
227
238
|
|
|
228
|
-
Register it
|
|
239
|
+
Register it programmatically via `registerSandboxAdapter()`. The agent loop and `run-code.ts` do not need to change.
|
|
229
240
|
|
|
230
241
|
<Callout id="doc-block-adap1tip" tone="info">
|
|
231
242
|
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.97.0",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -101,6 +101,10 @@
|
|
|
101
101
|
"./shared": "./dist/shared/index.js",
|
|
102
102
|
"./voice": "./dist/voice/index.js",
|
|
103
103
|
"./scripts": "./dist/scripts/index.js",
|
|
104
|
+
"./guards": {
|
|
105
|
+
"types": "./dist/guards/index.d.ts",
|
|
106
|
+
"default": "./dist/guards/index.js"
|
|
107
|
+
},
|
|
104
108
|
"./application-state": "./dist/application-state/index.js",
|
|
105
109
|
"./settings": "./dist/settings/index.js",
|
|
106
110
|
"./localization": "./dist/localization/index.js",
|
|
@@ -207,6 +211,10 @@
|
|
|
207
211
|
"default": "./dist/local-artifacts/index.js"
|
|
208
212
|
},
|
|
209
213
|
"./workspace-files": "./dist/workspace-files/index.js",
|
|
214
|
+
"./package-lifecycle": {
|
|
215
|
+
"types": "./dist/package-lifecycle/index.d.ts",
|
|
216
|
+
"default": "./dist/package-lifecycle/index.js"
|
|
217
|
+
},
|
|
210
218
|
"./code-agents": "./dist/code-agents/index.js",
|
|
211
219
|
"./code-agents/transcript-normalizer": "./dist/code-agents/transcript-normalizer.js",
|
|
212
220
|
"./workspace-connections": "./dist/workspace-connections/index.js",
|
|
@@ -373,7 +381,6 @@
|
|
|
373
381
|
"react-dom": "^19.2.7",
|
|
374
382
|
"react-router": "^8.1.0",
|
|
375
383
|
"tailwindcss": "catalog:",
|
|
376
|
-
"typescript": "catalog:",
|
|
377
384
|
"typescript-7": "catalog:",
|
|
378
385
|
"vite": "catalog:",
|
|
379
386
|
"vitest": "^4.1.5",
|
|
@@ -31,3 +31,36 @@ export function hasConfiguredA2ASecret(): boolean {
|
|
|
31
31
|
export function shouldAdvertiseJwtA2AAuth(): boolean {
|
|
32
32
|
return hasConfiguredA2ASecret() || isA2AProductionRuntime();
|
|
33
33
|
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* True only when unsigned internal self-dispatch is acceptable: no A2A_SECRET
|
|
37
|
+
* is configured AND we can positively identify a local/dev runtime. Everything
|
|
38
|
+
* else — production, or any UNRECOGNIZED deployed/networked host — must fail
|
|
39
|
+
* closed and require A2A_SECRET. `loopback` should be whether the inbound
|
|
40
|
+
* request arrived over the loopback interface (127.0.0.1/::1); callers that
|
|
41
|
+
* cannot determine the peer address pass `false`.
|
|
42
|
+
*
|
|
43
|
+
* NODE_ENV alone is deliberately NOT a trust grant: a self-hosted deployment
|
|
44
|
+
* that doesn't set NODE_ENV=production and isn't recognized by
|
|
45
|
+
* `isA2AProductionRuntime()` (a bare Docker/VPS/K8s pod) must still fail
|
|
46
|
+
* closed unless the request actually came from loopback or the explicit
|
|
47
|
+
* opt-in flag is set.
|
|
48
|
+
*/
|
|
49
|
+
export function isTrustedLocalRuntime(opts: { loopback: boolean }): boolean {
|
|
50
|
+
if (isA2AProductionRuntime()) return false;
|
|
51
|
+
if (process.env.A2A_ALLOW_UNSIGNED_INTERNAL === "1") return true;
|
|
52
|
+
return opts.loopback === true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** True if a socket peer address is a loopback/local address. */
|
|
56
|
+
export function isLoopbackAddress(addr: string | undefined | null): boolean {
|
|
57
|
+
if (!addr) return false;
|
|
58
|
+
const a = addr.trim();
|
|
59
|
+
return (
|
|
60
|
+
a === "127.0.0.1" ||
|
|
61
|
+
a === "::1" ||
|
|
62
|
+
a === "::ffff:127.0.0.1" ||
|
|
63
|
+
a.startsWith("127.") ||
|
|
64
|
+
a === "localhost"
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
*/
|
|
40
40
|
import {
|
|
41
41
|
hasConfiguredA2ASecret,
|
|
42
|
-
|
|
42
|
+
isTrustedLocalRuntime,
|
|
43
43
|
} from "../a2a/auth-policy.js";
|
|
44
44
|
import {
|
|
45
45
|
extractBearerToken,
|
|
@@ -469,10 +469,13 @@ export function extractProcessRunId(body: unknown): string | null {
|
|
|
469
469
|
*
|
|
470
470
|
* Auth policy mirrors the agent-teams processor exactly:
|
|
471
471
|
* - `A2A_SECRET` set → require a valid `verifyInternalToken(runId, token)`.
|
|
472
|
-
* - no secret
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
472
|
+
* - no secret → require `isTrustedLocalRuntime({ loopback })` (see
|
|
473
|
+
* auth-policy.ts): refuse (503) unless `A2A_ALLOW_UNSIGNED_INTERNAL=1` is
|
|
474
|
+
* set. This function has no h3 `event` of its own, so callers that CAN
|
|
475
|
+
* see the inbound socket peer (the route handler, which has the event)
|
|
476
|
+
* should compute `loopback` from it and pass it through; callers that
|
|
477
|
+
* can't determine the peer address should omit it (defaults to `false`
|
|
478
|
+
* — never trust unsigned dispatch without an explicit opt-in).
|
|
476
479
|
*
|
|
477
480
|
* Extracted from the route handler so the auth + marker-prep decision is unit
|
|
478
481
|
* testable without booting the whole Nitro plugin. The route only adds body
|
|
@@ -481,6 +484,7 @@ export function extractProcessRunId(body: unknown): string | null {
|
|
|
481
484
|
export function prepareProcessRunRequest(
|
|
482
485
|
body: unknown,
|
|
483
486
|
authHeader: string | undefined,
|
|
487
|
+
loopback: boolean = false,
|
|
484
488
|
): ProcessRunPreparation {
|
|
485
489
|
if (!body || typeof body !== "object") {
|
|
486
490
|
return {
|
|
@@ -514,12 +518,16 @@ export function prepareProcessRunRequest(
|
|
|
514
518
|
runId,
|
|
515
519
|
};
|
|
516
520
|
}
|
|
517
|
-
} else if (
|
|
521
|
+
} else if (!isTrustedLocalRuntime({ loopback })) {
|
|
522
|
+
// Callers that can see the h3 `event` (the route handler) pass the real
|
|
523
|
+
// loopback signal; callers without one default to non-loopback. Unsigned
|
|
524
|
+
// dispatch is still allowed via A2A_ALLOW_UNSIGNED_INTERNAL=1 for trusted
|
|
525
|
+
// local/dev setups; see auth-policy.ts `isTrustedLocalRuntime`.
|
|
518
526
|
return {
|
|
519
527
|
ok: false,
|
|
520
528
|
status: 503,
|
|
521
529
|
error:
|
|
522
|
-
"Agent chat background processor not configured — set A2A_SECRET on this deployment.",
|
|
530
|
+
"Agent chat background processor not configured — set A2A_SECRET on this deployment (or A2A_ALLOW_UNSIGNED_INTERNAL=1 for trusted local dev).",
|
|
523
531
|
runId,
|
|
524
532
|
};
|
|
525
533
|
}
|
|
@@ -1759,7 +1759,7 @@ export async function listRunsForThread(
|
|
|
1759
1759
|
LIMIT ?`,
|
|
1760
1760
|
args: [threadId, limit],
|
|
1761
1761
|
});
|
|
1762
|
-
|
|
1762
|
+
const reconcileCandidateIds: string[] = [];
|
|
1763
1763
|
for (const r of rows) {
|
|
1764
1764
|
const row = r as {
|
|
1765
1765
|
id?: string;
|
|
@@ -1773,10 +1773,19 @@ export async function listRunsForThread(
|
|
|
1773
1773
|
(row.status === "errored" &&
|
|
1774
1774
|
row.error_code === STALE_RUN_ERROR_EVENT.errorCode);
|
|
1775
1775
|
if (!canReconcileFromEvents) continue;
|
|
1776
|
-
|
|
1777
|
-
(await reconcileTerminalRunFromEvents(runId).catch(() => false)) ||
|
|
1778
|
-
repairedTerminalRow;
|
|
1776
|
+
reconcileCandidateIds.push(runId);
|
|
1779
1777
|
}
|
|
1778
|
+
// Each candidate's reconciliation is independently fenced by the UPDATE's
|
|
1779
|
+
// WHERE clause (status = 'running' OR errored-with-stale-code) inside
|
|
1780
|
+
// reconcileTerminalRunFromEvents, keyed on that run's own id — reconciling
|
|
1781
|
+
// several stale runs in parallel is safe and avoids N sequential
|
|
1782
|
+
// SELECT+UPDATE round-trip pairs on a shared-thread page load.
|
|
1783
|
+
const reconcileResults = await Promise.all(
|
|
1784
|
+
reconcileCandidateIds.map((runId) =>
|
|
1785
|
+
reconcileTerminalRunFromEvents(runId).catch(() => false),
|
|
1786
|
+
),
|
|
1787
|
+
);
|
|
1788
|
+
const repairedTerminalRow = reconcileResults.some(Boolean);
|
|
1780
1789
|
if (repairedTerminalRow) {
|
|
1781
1790
|
const refreshed = await client.execute({
|
|
1782
1791
|
sql: `SELECT id, thread_id, turn_id, status, started_at, heartbeat_at, completed_at, last_progress_at, error_code, abort_reason, dispatch_mode, terminal_reason, diag_stage
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import { defineAction } from "../../action.js";
|
|
4
|
+
import { MAX_LIMIT, queryAuditEvents } from "../store.js";
|
|
5
|
+
import type { AuditEvent } from "../types.js";
|
|
6
|
+
|
|
7
|
+
const DEFAULT_MAX_ROWS = 5000;
|
|
8
|
+
const HARD_CAP_ROWS = 10000;
|
|
9
|
+
|
|
10
|
+
// Deterministic column order for CSV — mirrors the store's list projection
|
|
11
|
+
// (`LIST_COLUMNS`), which deliberately excludes `input` so a bulk export
|
|
12
|
+
// never streams every event's (redacted) request body at once. Future
|
|
13
|
+
// columns added to the audit store must be reflected here too.
|
|
14
|
+
const CSV_COLUMNS: Array<[key: keyof AuditEvent, header: string]> = [
|
|
15
|
+
["id", "id"],
|
|
16
|
+
["createdAt", "created_at"],
|
|
17
|
+
["action", "action"],
|
|
18
|
+
["caller", "caller"],
|
|
19
|
+
["actorKind", "actor_kind"],
|
|
20
|
+
["actorEmail", "actor_email"],
|
|
21
|
+
["orgId", "org_id"],
|
|
22
|
+
["threadId", "thread_id"],
|
|
23
|
+
["turnId", "turn_id"],
|
|
24
|
+
["targetType", "target_type"],
|
|
25
|
+
["targetId", "target_id"],
|
|
26
|
+
["status", "status"],
|
|
27
|
+
["summary", "summary"],
|
|
28
|
+
["errorCode", "error_code"],
|
|
29
|
+
["ownerEmail", "owner_email"],
|
|
30
|
+
["visibility", "visibility"],
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
/** Hand-rolled CSV field escaper — quotes a field when it contains a comma,
|
|
34
|
+
* quote, or newline, doubling any embedded quotes. No dependency needed for
|
|
35
|
+
* ~10 lines of RFC 4180 escaping. */
|
|
36
|
+
function csvField(value: unknown): string {
|
|
37
|
+
if (value === null || value === undefined) return "";
|
|
38
|
+
const raw = String(value);
|
|
39
|
+
if (/[",\n\r]/.test(raw)) {
|
|
40
|
+
return `"${raw.replace(/"/g, '""')}"`;
|
|
41
|
+
}
|
|
42
|
+
return raw;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function toCsv(events: AuditEvent[]): string {
|
|
46
|
+
const header = CSV_COLUMNS.map(([, label]) => label).join(",");
|
|
47
|
+
const rows = events.map((event) =>
|
|
48
|
+
CSV_COLUMNS.map(([key]) => csvField(event[key])).join(","),
|
|
49
|
+
);
|
|
50
|
+
return [header, ...rows].join("\n");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function toNdjson(events: AuditEvent[]): string {
|
|
54
|
+
return events.map((event) => JSON.stringify(event)).join("\n");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Bulk-export audit-log events as CSV or NDJSON — the "bulk export" sensitive
|
|
59
|
+
* read the audit doc itself names. Pages past the per-call row clamp
|
|
60
|
+
* (`queryAuditEvents`'s `MAX_LIMIT`) up to `maxRows`, scoped in SQL to the
|
|
61
|
+
* caller's identity exactly like `list-audit-events`. Read-only; never
|
|
62
|
+
* exposes other tenants' rows.
|
|
63
|
+
*/
|
|
64
|
+
export default defineAction({
|
|
65
|
+
description:
|
|
66
|
+
"Export audit-log events as a CSV or NDJSON document for offline/compliance pulls (up to maxRows, default 5000, hard cap 10000). Use this instead of hand-paging list-audit-events when you need a bulk download of the trail; use list-audit-events instead for browsing recent activity or answering 'what changed'.",
|
|
67
|
+
schema: z.object({
|
|
68
|
+
targetType: z
|
|
69
|
+
.string()
|
|
70
|
+
.optional()
|
|
71
|
+
.describe("Filter to one resource type, e.g. 'recording'."),
|
|
72
|
+
targetId: z
|
|
73
|
+
.string()
|
|
74
|
+
.optional()
|
|
75
|
+
.describe("Filter to one resource id (pair with targetType)."),
|
|
76
|
+
actorKind: z
|
|
77
|
+
.enum(["agent", "human", "system"])
|
|
78
|
+
.optional()
|
|
79
|
+
.describe("Filter to changes made by the agent, a human, or the system."),
|
|
80
|
+
actorEmail: z.string().optional().describe("Filter to one actor's email."),
|
|
81
|
+
status: z
|
|
82
|
+
.enum(["success", "error", "denied"])
|
|
83
|
+
.optional()
|
|
84
|
+
.describe("Filter by outcome."),
|
|
85
|
+
threadId: z.string().optional().describe("Filter to one agent thread."),
|
|
86
|
+
turnId: z
|
|
87
|
+
.string()
|
|
88
|
+
.optional()
|
|
89
|
+
.describe("Filter to one agent turn (a single agent response)."),
|
|
90
|
+
action: z.string().optional().describe("Filter to one action name."),
|
|
91
|
+
sinceMs: z
|
|
92
|
+
.number()
|
|
93
|
+
.optional()
|
|
94
|
+
.describe("Only events at or after this Unix epoch (ms)."),
|
|
95
|
+
format: z
|
|
96
|
+
.enum(["csv", "ndjson"])
|
|
97
|
+
.default("csv")
|
|
98
|
+
.describe(
|
|
99
|
+
"Export format — CSV with a header row, or one JSON event per line.",
|
|
100
|
+
),
|
|
101
|
+
maxRows: z
|
|
102
|
+
.number()
|
|
103
|
+
.optional()
|
|
104
|
+
.describe("Max rows to export (default 5000, hard cap 10000)."),
|
|
105
|
+
}),
|
|
106
|
+
http: { method: "GET" },
|
|
107
|
+
audit: {
|
|
108
|
+
// Read-only actions are skipped by default — this is exactly the
|
|
109
|
+
// "bulk export" sensitive read the framework's own audit doc calls out.
|
|
110
|
+
onRead: true,
|
|
111
|
+
summary: (args) =>
|
|
112
|
+
`Bulk export of audit events (${(args as { format?: string }).format ?? "csv"})`,
|
|
113
|
+
},
|
|
114
|
+
run: async (args, ctx) => {
|
|
115
|
+
const scope = { userEmail: ctx?.userEmail, orgId: ctx?.orgId ?? null };
|
|
116
|
+
const cap = Math.min(
|
|
117
|
+
Math.max(1, Math.floor(args.maxRows ?? DEFAULT_MAX_ROWS)),
|
|
118
|
+
HARD_CAP_ROWS,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const filters = {
|
|
122
|
+
...(args.targetType ? { targetType: args.targetType } : {}),
|
|
123
|
+
...(args.targetId ? { targetId: args.targetId } : {}),
|
|
124
|
+
...(args.actorKind ? { actorKind: args.actorKind } : {}),
|
|
125
|
+
...(args.actorEmail ? { actorEmail: args.actorEmail } : {}),
|
|
126
|
+
...(args.status ? { status: args.status } : {}),
|
|
127
|
+
...(args.threadId ? { threadId: args.threadId } : {}),
|
|
128
|
+
...(args.turnId ? { turnId: args.turnId } : {}),
|
|
129
|
+
...(args.action ? { action: args.action } : {}),
|
|
130
|
+
...(typeof args.sinceMs === "number" ? { sinceMs: args.sinceMs } : {}),
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const events: AuditEvent[] = [];
|
|
134
|
+
let offset = 0;
|
|
135
|
+
while (events.length < cap) {
|
|
136
|
+
const pageLimit = Math.min(MAX_LIMIT, cap - events.length);
|
|
137
|
+
const page = await queryAuditEvents(scope, {
|
|
138
|
+
...filters,
|
|
139
|
+
limit: pageLimit,
|
|
140
|
+
offset,
|
|
141
|
+
});
|
|
142
|
+
events.push(...page);
|
|
143
|
+
offset += page.length;
|
|
144
|
+
if (page.length < pageLimit) break; // exhausted — no more matching rows
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// We stopped because we hit the cap, not because we ran out of rows —
|
|
148
|
+
// probe one more row to know whether the export was actually truncated.
|
|
149
|
+
let truncated = false;
|
|
150
|
+
if (events.length >= cap) {
|
|
151
|
+
const probe = await queryAuditEvents(scope, {
|
|
152
|
+
...filters,
|
|
153
|
+
limit: 1,
|
|
154
|
+
offset,
|
|
155
|
+
});
|
|
156
|
+
truncated = probe.length > 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const content = args.format === "ndjson" ? toNdjson(events) : toCsv(events);
|
|
160
|
+
return { content, rowCount: events.length, truncated, format: args.format };
|
|
161
|
+
},
|
|
162
|
+
});
|
|
@@ -250,7 +250,9 @@ function scopeClause(scope: AuditReadScope): { sql: string; args: any[] } {
|
|
|
250
250
|
return { sql: `(${clauses.join(" OR ")})`, args };
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
// Exported so callers that must page past a single call (e.g.
|
|
254
|
+
// `export-audit-events`) can mirror the clamp instead of guessing it.
|
|
255
|
+
export const MAX_LIMIT = 500;
|
|
254
256
|
const DEFAULT_LIMIT = 100;
|
|
255
257
|
|
|
256
258
|
// Columns returned by the list surface — deliberately EXCLUDES `input` so a
|
|
@@ -297,13 +299,16 @@ export async function queryAuditEvents(
|
|
|
297
299
|
Math.max(1, Math.floor(filters.limit ?? DEFAULT_LIMIT)),
|
|
298
300
|
MAX_LIMIT,
|
|
299
301
|
);
|
|
302
|
+
// 0-based, default-compatible: existing callers that never pass `offset`
|
|
303
|
+
// keep selecting from the top of the ordered result set.
|
|
304
|
+
const offset = Math.max(0, Math.floor(filters.offset ?? 0));
|
|
300
305
|
|
|
301
306
|
const result = await client.execute({
|
|
302
307
|
sql: `SELECT ${LIST_COLUMNS} FROM agent_audit_log
|
|
303
308
|
WHERE ${where.join(" AND ")}
|
|
304
309
|
ORDER BY created_at DESC
|
|
305
|
-
LIMIT ?`,
|
|
306
|
-
args: [...args, limit],
|
|
310
|
+
LIMIT ? OFFSET ?`,
|
|
311
|
+
args: [...args, limit, offset],
|
|
307
312
|
});
|
|
308
313
|
return (result.rows ?? []).map(mapRow);
|
|
309
314
|
}
|
|
@@ -135,4 +135,7 @@ export interface AuditQueryFilters {
|
|
|
135
135
|
sourcePlatform?: string;
|
|
136
136
|
sinceMs?: number;
|
|
137
137
|
limit?: number;
|
|
138
|
+
/** Skip this many matching rows before applying `limit` (0-based). Used by
|
|
139
|
+
* `export-audit-events` to page past the per-call `MAX_LIMIT` clamp. */
|
|
140
|
+
offset?: number;
|
|
138
141
|
}
|