@agent-native/core 0.124.3 → 0.124.4
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 +1 -1
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +10 -0
- package/corpus/core/docs/content/cloneable-saas.mdx +9 -9
- package/corpus/core/docs/content/creating-templates.mdx +2 -2
- package/corpus/core/docs/content/deployment.mdx +23 -0
- package/corpus/core/docs/content/faq.mdx +4 -4
- package/corpus/core/docs/content/key-concepts.mdx +1 -1
- package/corpus/core/docs/content/multi-app-workspace.mdx +1 -1
- package/corpus/core/docs/content/syncing-template-changes.mdx +1 -1
- package/corpus/core/docs/content/template-analytics-developers.mdx +2 -2
- package/corpus/core/docs/content/template-analytics.mdx +2 -2
- package/corpus/core/docs/content/template-assets-developers.mdx +3 -3
- package/corpus/core/docs/content/template-assets.mdx +2 -2
- package/corpus/core/docs/content/template-brain-developers.mdx +2 -2
- package/corpus/core/docs/content/template-brain.mdx +1 -1
- package/corpus/core/docs/content/template-calendar-developers.mdx +1 -1
- package/corpus/core/docs/content/template-calendar.mdx +1 -1
- package/corpus/core/docs/content/template-chat.mdx +1 -1
- package/corpus/core/docs/content/template-clips-developers.mdx +4 -4
- package/corpus/core/docs/content/template-clips.mdx +2 -2
- package/corpus/core/docs/content/template-content-developers.mdx +2 -2
- package/corpus/core/docs/content/template-content.mdx +1 -1
- package/corpus/core/docs/content/template-design-brand-and-figma.mdx +1 -1
- package/corpus/core/docs/content/template-design-developers.mdx +2 -2
- package/corpus/core/docs/content/template-design.mdx +2 -2
- package/corpus/core/docs/content/template-dispatch-developers.mdx +5 -5
- package/corpus/core/docs/content/template-forms-developers.mdx +1 -1
- package/corpus/core/docs/content/template-forms.mdx +1 -1
- package/corpus/core/docs/content/template-mail-developers.mdx +2 -2
- package/corpus/core/docs/content/template-mail.mdx +2 -2
- package/corpus/core/docs/content/template-plan-developers.mdx +3 -3
- package/corpus/core/docs/content/template-plan.mdx +3 -3
- package/corpus/core/docs/content/template-slides-developers.mdx +4 -4
- package/corpus/core/docs/content/template-slides.mdx +1 -1
- package/corpus/core/docs/content/what-is-agent-native.mdx +5 -5
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/auth-policy.ts +1 -1
- package/corpus/core/src/agent/production-agent.ts +14 -1
- package/corpus/core/src/agent/run-manager.ts +6 -13
- package/corpus/core/src/cli/index.ts +11 -1
- package/corpus/core/src/client/route-chunk-recovery.ts +18 -7
- package/corpus/core/src/db/client.ts +7 -6
- package/corpus/core/src/db/migrations.ts +2 -1
- package/corpus/core/src/deploy/build.ts +290 -4
- package/corpus/core/src/deploy/nitro-preset.ts +50 -0
- package/corpus/core/src/integrations/pending-tasks-retry-job.ts +2 -1
- package/corpus/core/src/scripts/call-agent.ts +4 -2
- package/corpus/core/src/server/agent-discovery.ts +1 -0
- package/corpus/core/src/server/agent-run-context.ts +13 -3
- package/corpus/core/src/server/request-context.ts +2 -0
- package/corpus/core/src/shared/cloudflare-globals.d.ts +2 -1
- package/corpus/core/src/shared/runtime.ts +2 -0
- package/corpus/core/src/templates/default/.agents/skills/secrets/SKILL.md +29 -0
- package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/de-DE.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/es-ES.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +6 -6
- package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +6 -6
- package/corpus/core/src/templates/headless/.agents/skills/secrets/SKILL.md +29 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +29 -0
- package/corpus/core/src/vite/client.ts +20 -1
- package/corpus/templates/analytics/actions/restore-dashboard-revision.ts +9 -2
- package/corpus/templates/analytics/app/components/dashboard/DashboardHistoryPanel.tsx +3 -0
- package/corpus/templates/analytics/app/components/dashboard/DashboardPanelSkeleton.tsx +1 -1
- package/corpus/templates/analytics/app/global.css +10 -9
- package/corpus/templates/analytics/app/hooks/use-chart-tooltip-portal.ts +59 -18
- package/corpus/templates/analytics/app/hooks/use-dashboard-revisions.ts +14 -2
- package/corpus/templates/analytics/app/i18n-data.ts +102 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +232 -2
- package/corpus/templates/analytics/changelog/2026-07-27-chart-tooltips-stay-beside-the-cursor-when-they-extend-beyon.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-27-chat-no-longer-claims-a-data-source-is-disconnected-when-it-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-27-dashboard-changes-can-be-undone-with-cmd-z-and-actions-menu.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-27-dashboard-redo-with-cmd-shift-z-and-actions-menu.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-27-dashboard-skeletons-are-subtler-and-smoother.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +61 -20
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -3
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +7 -32
- package/corpus/templates/calendar/changelog/2026-07-27-calendar-s-sidebar-now-uses-a-cleaner-layout-with-fewer-util.md +6 -0
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +14 -6
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +32 -37
- package/corpus/templates/content/changelog/2026-07-27-content-sidebar-page-lists-now-load-with-quiet-skeletons-and.md +6 -0
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +16 -18
- package/corpus/templates/design/changelog/2026-07-27-collapsed-sidebar-keeps-the-agent-native-logo.md +6 -0
- package/corpus/templates/dispatch/AGENTS.md +7 -2
- package/corpus/templates/dispatch/actions/view-screen.ts +3 -2
- package/corpus/templates/dispatch/changelog/2026-07-17-curated-template-remixes.md +1 -1
- package/corpus/templates/dispatch/changelog/2026-07-27-creating-an-app-from-a-curated-template-now-uses-clearer-mor.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-27-thread-debug-accepts-request-run-ids.md +6 -0
- package/corpus/templates/slides/actions/create-design-system.ts +10 -2
- package/corpus/templates/slides/actions/import-file.ts +173 -1
- package/corpus/templates/slides/actions/list-slide-comments.ts +16 -1
- package/corpus/templates/slides/actions/update-design-system.ts +13 -2
- package/corpus/templates/slides/app/components/editor/AssetLibraryPanel.tsx +35 -12
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +36 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +3 -0
- package/corpus/templates/slides/app/lib/dynamic-import.ts +63 -0
- package/corpus/templates/slides/app/lib/export-pdf-client.ts +3 -2
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +5 -2
- package/corpus/templates/slides/app/pages/DesignSystems.tsx +9 -1
- package/corpus/templates/slides/server/db/schema.ts +11 -0
- package/corpus/templates/slides/server/handlers/assets.ts +64 -19
- package/corpus/templates/slides/server/handlers/import/html-converter.ts +38 -0
- package/corpus/templates/slides/server/plugins/db.ts +20 -0
- package/corpus/templates/slides/shared/design-system-validation.ts +62 -0
- package/dist/a2a/auth-policy.js +1 -1
- package/dist/a2a/auth-policy.js.map +1 -1
- package/dist/agent/production-agent.d.ts +1 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +12 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +2 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +4 -10
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/cli/index.js +8 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/client/route-chunk-recovery.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery.js +16 -7
- package/dist/client/route-chunk-recovery.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +4 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +2 -1
- package/dist/db/migrations.js.map +1 -1
- package/dist/deploy/build.d.ts +25 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +227 -4
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/nitro-preset.d.ts +8 -0
- package/dist/deploy/nitro-preset.d.ts.map +1 -0
- package/dist/deploy/nitro-preset.js +36 -0
- package/dist/deploy/nitro-preset.js.map +1 -0
- package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.js +2 -1
- package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +4 -2
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +1 -0
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-run-context.d.ts.map +1 -1
- package/dist/server/agent-run-context.js +10 -3
- package/dist/server/agent-run-context.js.map +1 -1
- package/dist/server/request-context.d.ts +2 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/runtime.d.ts.map +1 -1
- package/dist/shared/runtime.js +2 -0
- package/dist/shared/runtime.js.map +1 -1
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +29 -0
- package/dist/templates/default/app/i18n/ar-SA.ts +6 -6
- package/dist/templates/default/app/i18n/de-DE.ts +6 -6
- package/dist/templates/default/app/i18n/en-US.ts +6 -6
- package/dist/templates/default/app/i18n/es-ES.ts +6 -6
- package/dist/templates/default/app/i18n/fr-FR.ts +6 -6
- package/dist/templates/default/app/i18n/hi-IN.ts +6 -6
- package/dist/templates/default/app/i18n/ja-JP.ts +6 -6
- package/dist/templates/default/app/i18n/ko-KR.ts +6 -6
- package/dist/templates/default/app/i18n/pt-BR.ts +6 -6
- package/dist/templates/default/app/i18n/zh-CN.ts +6 -6
- package/dist/templates/default/app/i18n/zh-TW.ts +6 -6
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +29 -0
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +29 -0
- package/dist/vite/client.d.ts +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +16 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/cloneable-saas.mdx +9 -9
- package/docs/content/creating-templates.mdx +2 -2
- package/docs/content/deployment.mdx +23 -0
- package/docs/content/faq.mdx +4 -4
- package/docs/content/key-concepts.mdx +1 -1
- package/docs/content/multi-app-workspace.mdx +1 -1
- package/docs/content/syncing-template-changes.mdx +1 -1
- package/docs/content/template-analytics-developers.mdx +2 -2
- package/docs/content/template-analytics.mdx +2 -2
- package/docs/content/template-assets-developers.mdx +3 -3
- package/docs/content/template-assets.mdx +2 -2
- package/docs/content/template-brain-developers.mdx +2 -2
- package/docs/content/template-brain.mdx +1 -1
- package/docs/content/template-calendar-developers.mdx +1 -1
- package/docs/content/template-calendar.mdx +1 -1
- package/docs/content/template-chat.mdx +1 -1
- package/docs/content/template-clips-developers.mdx +4 -4
- package/docs/content/template-clips.mdx +2 -2
- package/docs/content/template-content-developers.mdx +2 -2
- package/docs/content/template-content.mdx +1 -1
- package/docs/content/template-design-brand-and-figma.mdx +1 -1
- package/docs/content/template-design-developers.mdx +2 -2
- package/docs/content/template-design.mdx +2 -2
- package/docs/content/template-dispatch-developers.mdx +5 -5
- package/docs/content/template-forms-developers.mdx +1 -1
- package/docs/content/template-forms.mdx +1 -1
- package/docs/content/template-mail-developers.mdx +2 -2
- package/docs/content/template-mail.mdx +2 -2
- package/docs/content/template-plan-developers.mdx +3 -3
- package/docs/content/template-plan.mdx +3 -3
- package/docs/content/template-slides-developers.mdx +4 -4
- package/docs/content/template-slides.mdx +1 -1
- package/docs/content/what-is-agent-native.mdx +5 -5
- package/package.json +1 -1
- package/src/a2a/auth-policy.ts +1 -1
- package/src/agent/production-agent.ts +14 -1
- package/src/agent/run-manager.ts +6 -13
- package/src/cli/index.ts +11 -1
- package/src/client/route-chunk-recovery.ts +18 -7
- package/src/db/client.ts +7 -6
- package/src/db/migrations.ts +2 -1
- package/src/deploy/build.ts +290 -4
- package/src/deploy/nitro-preset.ts +50 -0
- package/src/integrations/pending-tasks-retry-job.ts +2 -1
- package/src/scripts/call-agent.ts +4 -2
- package/src/server/agent-discovery.ts +1 -0
- package/src/server/agent-run-context.ts +13 -3
- package/src/server/request-context.ts +2 -0
- package/src/shared/cloudflare-globals.d.ts +2 -1
- package/src/shared/runtime.ts +2 -0
- package/src/templates/default/.agents/skills/secrets/SKILL.md +29 -0
- package/src/templates/default/app/i18n/ar-SA.ts +6 -6
- package/src/templates/default/app/i18n/de-DE.ts +6 -6
- package/src/templates/default/app/i18n/en-US.ts +6 -6
- package/src/templates/default/app/i18n/es-ES.ts +6 -6
- package/src/templates/default/app/i18n/fr-FR.ts +6 -6
- package/src/templates/default/app/i18n/hi-IN.ts +6 -6
- package/src/templates/default/app/i18n/ja-JP.ts +6 -6
- package/src/templates/default/app/i18n/ko-KR.ts +6 -6
- package/src/templates/default/app/i18n/pt-BR.ts +6 -6
- package/src/templates/default/app/i18n/zh-CN.ts +6 -6
- package/src/templates/default/app/i18n/zh-TW.ts +6 -6
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +29 -0
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +29 -0
- package/src/vite/client.ts +20 -1
- /package/corpus/templates/slides/server/routes/api/assets/{[filename].delete.ts → [id].delete.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-run-context.js","sourceRoot":"","sources":["../../src/server/agent-run-context.ts"],"names":[],"mappings":"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","sourcesContent":["import { createError, getHeader, type H3Event } from \"h3\";\n\nimport { resolveOrgIdForEmail, getOrgContext } from \"../org/context.js\";\nimport { getSession } from \"./auth.js\";\nimport {\n runWithRequestContext,\n type RequestContext,\n} from \"./request-context.js\";\n\nexport type AgentRunOwnerContext = {\n owner: string;\n anonymous: boolean;\n name?: string;\n};\n\nexport const AGENT_RUN_OWNER_CONTEXT_KEY = \"__agentNativeOwnerContext\";\n\ntype EventWithAgentRunContext = H3Event & {\n context?: Record<string, unknown>;\n};\n\ntype AnonymousOwnerResolver = (\n event: H3Event,\n) => string | null | Promise<string | null>;\n\ntype OrgIdResolver = (\n event: H3Event,\n) => string | null | undefined | Promise<string | null | undefined>;\n\nfunction eventContext(\n event: EventWithAgentRunContext,\n): Record<string, unknown> {\n event.context = event.context ?? {};\n return event.context;\n}\n\nfunction normalizeId(value: string | null | undefined): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction readHeaderValue(event: any, name: string): unknown {\n try {\n const value = getHeader(event, name);\n if (value !== undefined && value !== null) return value;\n } catch {\n // Unit tests and a few framework internals pass lightweight event shims.\n }\n\n const headers = event?.headers;\n if (headers && typeof headers.get === \"function\") {\n return headers.get(name) ?? headers.get(name.toLowerCase()) ?? undefined;\n }\n\n const reqHeaders = event?.node?.req?.headers ?? event?.req?.headers;\n if (reqHeaders && typeof reqHeaders === \"object\") {\n return reqHeaders[name] ?? reqHeaders[name.toLowerCase()];\n }\n\n return undefined;\n}\n\nexport function readAgentRunTimezone(event: H3Event): string | undefined {\n const raw = readHeaderValue(event, \"x-user-timezone\");\n const value = Array.isArray(raw) ? raw[0] : raw;\n return typeof value === \"string\" &&\n value.trim().length > 0 &&\n value.trim().length < 64\n ? value.trim()\n : undefined;\n}\n\nexport function seedAgentRunOwnerContext(\n event: H3Event,\n ownerContext: AgentRunOwnerContext,\n): AgentRunOwnerContext {\n eventContext(event as EventWithAgentRunContext)[AGENT_RUN_OWNER_CONTEXT_KEY] =\n ownerContext;\n return ownerContext;\n}\n\nexport async function seedBackgroundAgentRunOwnerContext(\n event: H3Event,\n runId: string,\n): Promise<AgentRunOwnerContext | null> {\n try {\n const { getRunOwnerEmail } = await import(\"../agent/run-store.js\");\n const owner = await getRunOwnerEmail(runId);\n if (!owner) return null;\n return seedAgentRunOwnerContext(event, { owner, anonymous: false });\n } catch {\n return null;\n }\n}\n\nexport async function resolveAgentRunOwnerContext(\n event: H3Event,\n options: { anonymousOwner?: AnonymousOwnerResolver } = {},\n): Promise<AgentRunOwnerContext> {\n const ctx = eventContext(event as EventWithAgentRunContext);\n const seeded = ctx[AGENT_RUN_OWNER_CONTEXT_KEY] as\n | AgentRunOwnerContext\n | undefined;\n if (seeded) return seeded;\n\n const session = await getSession(event);\n if (session?.email) {\n return seedAgentRunOwnerContext(event, {\n owner: session.email,\n anonymous: false,\n name: session.name,\n });\n }\n\n const anonymousOwner = await options.anonymousOwner?.(event);\n if (anonymousOwner) {\n return seedAgentRunOwnerContext(event, {\n owner: anonymousOwner,\n anonymous: true,\n });\n }\n\n throw createError({\n statusCode: 401,\n statusMessage: \"Unauthenticated\",\n });\n}\n\nexport async function resolveAgentRunOrgId(options: {\n event: H3Event;\n ownerContext: AgentRunOwnerContext;\n resolveOrgId?: OrgIdResolver;\n}): Promise<string | undefined> {\n let resolvedOrgId: string | undefined;\n\n if (options.resolveOrgId) {\n resolvedOrgId = normalizeId(await options.resolveOrgId(options.event));\n } else {\n try {\n const session = await getSession(options.event);\n resolvedOrgId = normalizeId(session?.orgId);\n } catch {\n // Session not available.\n }\n\n if (!resolvedOrgId) {\n try {\n const orgContext = await getOrgContext(options.event);\n resolvedOrgId = normalizeId(orgContext.orgId);\n } catch {\n // Org tables may not exist yet on first boot.\n }\n }\n }\n\n if (\n !resolvedOrgId &&\n options.ownerContext.owner &&\n !options.ownerContext.anonymous\n ) {\n try {\n resolvedOrgId = normalizeId(\n await resolveOrgIdForEmail(options.ownerContext.owner),\n );\n } catch {\n // Org tables may not exist yet on first boot.\n }\n }\n\n return resolvedOrgId;\n}\n\nexport async function resolveAgentRunRequestContext(options: {\n event: H3Event;\n ownerContext: AgentRunOwnerContext;\n resolveOrgId?: OrgIdResolver;\n isBackgroundWorker?: boolean;\n}): Promise<RequestContext> {\n const orgId = await resolveAgentRunOrgId(options);\n const timezone = readAgentRunTimezone(options.event);\n return {\n userEmail: options.ownerContext.owner,\n userName: options.ownerContext.name,\n orgId,\n timezone,\n ...(options.isBackgroundWorker\n ? { run: { isBackgroundWorker: true } }\n : {}),\n };\n}\n\nexport async function runWithAgentRunContext<T>(\n options: {\n event: H3Event;\n ownerContext: AgentRunOwnerContext;\n resolveOrgId?: OrgIdResolver;\n isBackgroundWorker?: boolean;\n },\n fn: () => T | Promise<T>,\n): Promise<T> {\n const requestContext = await resolveAgentRunRequestContext(options);\n return await runWithRequestContext(requestContext, fn);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-run-context.js","sourceRoot":"","sources":["../../src/server/agent-run-context.ts"],"names":[],"mappings":"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","sourcesContent":["import { createError, getHeader, type H3Event } from \"h3\";\n\nimport { resolveOrgIdForEmail, getOrgContext } from \"../org/context.js\";\nimport { getSession } from \"./auth.js\";\nimport {\n runWithRequestContext,\n type RequestContext,\n} from \"./request-context.js\";\n\nexport type AgentRunOwnerContext = {\n owner: string;\n anonymous: boolean;\n name?: string;\n};\n\nexport const AGENT_RUN_OWNER_CONTEXT_KEY = \"__agentNativeOwnerContext\";\n\ntype EventWithAgentRunContext = H3Event & {\n context?: Record<string, unknown>;\n};\n\ntype AnonymousOwnerResolver = (\n event: H3Event,\n) => string | null | Promise<string | null>;\n\ntype OrgIdResolver = (\n event: H3Event,\n) => string | null | undefined | Promise<string | null | undefined>;\n\nfunction eventContext(\n event: EventWithAgentRunContext,\n): Record<string, unknown> {\n event.context = event.context ?? {};\n return event.context;\n}\n\nfunction requestWaitUntil(\n event: H3Event,\n): ((promise: Promise<unknown>) => void) | undefined {\n const waitUntil = event.req?.waitUntil;\n return typeof waitUntil === \"function\" ? waitUntil : undefined;\n}\n\nfunction normalizeId(value: string | null | undefined): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction readHeaderValue(event: any, name: string): unknown {\n try {\n const value = getHeader(event, name);\n if (value !== undefined && value !== null) return value;\n } catch {\n // Unit tests and a few framework internals pass lightweight event shims.\n }\n\n const headers = event?.headers;\n if (headers && typeof headers.get === \"function\") {\n return headers.get(name) ?? headers.get(name.toLowerCase()) ?? undefined;\n }\n\n const reqHeaders = event?.node?.req?.headers ?? event?.req?.headers;\n if (reqHeaders && typeof reqHeaders === \"object\") {\n return reqHeaders[name] ?? reqHeaders[name.toLowerCase()];\n }\n\n return undefined;\n}\n\nexport function readAgentRunTimezone(event: H3Event): string | undefined {\n const raw = readHeaderValue(event, \"x-user-timezone\");\n const value = Array.isArray(raw) ? raw[0] : raw;\n return typeof value === \"string\" &&\n value.trim().length > 0 &&\n value.trim().length < 64\n ? value.trim()\n : undefined;\n}\n\nexport function seedAgentRunOwnerContext(\n event: H3Event,\n ownerContext: AgentRunOwnerContext,\n): AgentRunOwnerContext {\n eventContext(event as EventWithAgentRunContext)[AGENT_RUN_OWNER_CONTEXT_KEY] =\n ownerContext;\n return ownerContext;\n}\n\nexport async function seedBackgroundAgentRunOwnerContext(\n event: H3Event,\n runId: string,\n): Promise<AgentRunOwnerContext | null> {\n try {\n const { getRunOwnerEmail } = await import(\"../agent/run-store.js\");\n const owner = await getRunOwnerEmail(runId);\n if (!owner) return null;\n return seedAgentRunOwnerContext(event, { owner, anonymous: false });\n } catch {\n return null;\n }\n}\n\nexport async function resolveAgentRunOwnerContext(\n event: H3Event,\n options: { anonymousOwner?: AnonymousOwnerResolver } = {},\n): Promise<AgentRunOwnerContext> {\n const ctx = eventContext(event as EventWithAgentRunContext);\n const seeded = ctx[AGENT_RUN_OWNER_CONTEXT_KEY] as\n | AgentRunOwnerContext\n | undefined;\n if (seeded) return seeded;\n\n const session = await getSession(event);\n if (session?.email) {\n return seedAgentRunOwnerContext(event, {\n owner: session.email,\n anonymous: false,\n name: session.name,\n });\n }\n\n const anonymousOwner = await options.anonymousOwner?.(event);\n if (anonymousOwner) {\n return seedAgentRunOwnerContext(event, {\n owner: anonymousOwner,\n anonymous: true,\n });\n }\n\n throw createError({\n statusCode: 401,\n statusMessage: \"Unauthenticated\",\n });\n}\n\nexport async function resolveAgentRunOrgId(options: {\n event: H3Event;\n ownerContext: AgentRunOwnerContext;\n resolveOrgId?: OrgIdResolver;\n}): Promise<string | undefined> {\n let resolvedOrgId: string | undefined;\n\n if (options.resolveOrgId) {\n resolvedOrgId = normalizeId(await options.resolveOrgId(options.event));\n } else {\n try {\n const session = await getSession(options.event);\n resolvedOrgId = normalizeId(session?.orgId);\n } catch {\n // Session not available.\n }\n\n if (!resolvedOrgId) {\n try {\n const orgContext = await getOrgContext(options.event);\n resolvedOrgId = normalizeId(orgContext.orgId);\n } catch {\n // Org tables may not exist yet on first boot.\n }\n }\n }\n\n if (\n !resolvedOrgId &&\n options.ownerContext.owner &&\n !options.ownerContext.anonymous\n ) {\n try {\n resolvedOrgId = normalizeId(\n await resolveOrgIdForEmail(options.ownerContext.owner),\n );\n } catch {\n // Org tables may not exist yet on first boot.\n }\n }\n\n return resolvedOrgId;\n}\n\nexport async function resolveAgentRunRequestContext(options: {\n event: H3Event;\n ownerContext: AgentRunOwnerContext;\n resolveOrgId?: OrgIdResolver;\n isBackgroundWorker?: boolean;\n}): Promise<RequestContext> {\n const orgId = await resolveAgentRunOrgId(options);\n const timezone = readAgentRunTimezone(options.event);\n const waitUntil = requestWaitUntil(options.event);\n const run = {\n ...(options.isBackgroundWorker ? { isBackgroundWorker: true } : {}),\n ...(waitUntil ? { waitUntil } : {}),\n };\n return {\n userEmail: options.ownerContext.owner,\n userName: options.ownerContext.name,\n orgId,\n timezone,\n ...(Object.keys(run).length > 0 ? { run } : {}),\n };\n}\n\nexport async function runWithAgentRunContext<T>(\n options: {\n event: H3Event;\n ownerContext: AgentRunOwnerContext;\n resolveOrgId?: OrgIdResolver;\n isBackgroundWorker?: boolean;\n },\n fn: () => T | Promise<T>,\n): Promise<T> {\n const requestContext = await resolveAgentRunRequestContext(options);\n return await runWithRequestContext(requestContext, fn);\n}\n"]}
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
* the live per-request value via `getRequestRunContext()`.
|
|
28
28
|
*/
|
|
29
29
|
export interface RequestRunContext {
|
|
30
|
+
/** Request-scoped serverless continuation hook, when the runtime provides one. */
|
|
31
|
+
waitUntil?: (promise: Promise<unknown>) => void;
|
|
30
32
|
/** Origin of the current request (used by the builder-browser tool). */
|
|
31
33
|
requestOrigin?: string;
|
|
32
34
|
/** Stable browser tab id for tab-scoped app-state reads/writes. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Per-request context using AsyncLocalStorage.\n *\n * Replaces the unsafe pattern of mutating `process.env.AGENT_USER_EMAIL` /\n * `process.env.AGENT_ORG_ID` on every request. On Node.js (Netlify, self-hosted)\n * concurrent requests would overwrite each other's env vars. AsyncLocalStorage\n * gives each async call-chain its own isolated context.\n *\n * Supported on all deployment targets:\n * - Node.js (native)\n * - Cloudflare Workers (via nodejs_compat flag)\n * - Deno Deploy (via node:async_hooks compat)\n *\n * For CLI scripts that run outside a request context, the getters fall back to\n * process.env so existing `AGENT_USER_EMAIL=x pnpm action foo` invocations\n * continue to work.\n */\n\ntype AsyncLocalStorageLike<T> = {\n getStore(): T | undefined;\n run<R>(store: T, callback: () => R): R;\n};\n\ntype AsyncLocalStorageCtor = new <T>() => AsyncLocalStorageLike<T>;\n\nclass StackAsyncLocalStorage<T> implements AsyncLocalStorageLike<T> {\n private readonly stack: T[] = [];\n\n getStore(): T | undefined {\n return this.stack.at(-1);\n }\n\n run<R>(store: T, callback: () => R): R {\n this.stack.push(store);\n try {\n const result = callback();\n const maybePromise = result as unknown as\n | { finally?: (callback: () => void) => unknown }\n | undefined;\n if (maybePromise && typeof maybePromise.finally === \"function\") {\n return maybePromise.finally(() => {\n this.stack.pop();\n }) as R;\n }\n this.stack.pop();\n return result;\n } catch (error) {\n this.stack.pop();\n throw error;\n }\n }\n}\n\nfunction getAsyncLocalStorageCtor(): AsyncLocalStorageCtor | undefined {\n if (\n typeof window !== \"undefined\" ||\n typeof process === \"undefined\" ||\n !process.versions?.node ||\n typeof process.getBuiltinModule !== \"function\"\n ) {\n return undefined;\n }\n return process.getBuiltinModule(\"node:async_hooks\")?.AsyncLocalStorage as\n | AsyncLocalStorageCtor\n | undefined;\n}\n\nconst AsyncLocalStorageCtor = getAsyncLocalStorageCtor();\n\nfunction processEnv(name: string): string | undefined {\n if (typeof process === \"undefined\") return undefined;\n return process.env?.[name];\n}\n\n/**\n * Per-request agent-run state. Lives on `RequestContext.run` so the\n * agent-chat plugin can populate fields as the run progresses (owner,\n * resolved API key, system prompt, engine, model, threadId) without\n * mutating module-scope `let` bindings — those leak across concurrent\n * requests on a single Node.js process.\n *\n * Mutated in-place by `prepareRun`, `onEngineResolved`, `onRunStart` so\n * tool factory closures (automation, fetch, team, builder-browser) read\n * the live per-request value via `getRequestRunContext()`.\n */\nexport interface RequestRunContext {\n /** Origin of the current request (used by the builder-browser tool). */\n requestOrigin?: string;\n /** Stable browser tab id for tab-scoped app-state reads/writes. */\n browserTabId?: string;\n /** Resource scope for the current chat thread, e.g. the active deck. */\n chatScope?: {\n type: string;\n id: string;\n label?: string;\n } | null;\n /** Resolved owner email (set by prepareRun). */\n owner?: string;\n /** Owner's active Anthropic API key (set by prepareRun). */\n userApiKey?: string;\n /** Thread ID for the current run (set by onRunStart). */\n threadId?: string;\n /** System prompt actually sent to the model for this run. */\n systemPrompt?: string;\n /** Engine instance for this run (set by onEngineResolved). */\n engine?: import(\"../agent/engine/types.js\").AgentEngine;\n /** Model name for this run (set by onEngineResolved). */\n model?: string;\n /**\n * True when this run is executing inside the durable background-function\n * worker (the `_process-run` self-dispatch), not the synchronous foreground\n * request. Template `extraContext` / system-prompt builders can read this to\n * skip heavy, hang-prone enrichment (large data-dictionary DB reads, etc.)\n * in the worker so it reliably claims its run within the setup budget.\n */\n isBackgroundWorker?: boolean;\n /** Tool calls made so far in the current agent loop. */\n toolCalls?: Array<{ name: string; input: unknown }>;\n /** Tool results returned so far in the current agent loop. */\n toolResults?: Array<{ name: string; content: string; isError: boolean }>;\n /** Per-run fingerprints for large extension bodies already sent to the LLM. */\n extensionContentReads?: Record<string, string>;\n /** Per-run fingerprints for repeated tool-search calls already sent to the LLM. */\n toolSearchReads?: Record<\n string,\n { totalTools: number; resultNames: string[] }\n >;\n}\n\nexport interface RequestContext {\n userEmail?: string;\n userName?: string;\n orgId?: string;\n timezone?: string;\n /**\n * Set when code reads authenticated request context. Public SSR shell/data\n * should not depend on this value; user/org-specific reads belong behind\n * client-side actions/API after hydration.\n */\n authContextAccessed?: boolean;\n /**\n * Origin of the inbound request (e.g. `http://127.0.0.1:8100`). Set by the\n * MCP mount from the request headers so actions that build externally\n * fetchable URLs (e.g. design `export-coding-handoff`'s signed raw-code URL)\n * resolve the real local-workspace origin instead of a prod/localhost\n * fallback. Optional — absent on paths that don't populate it.\n */\n requestOrigin?: string;\n /**\n * True when this request is being processed by an integration-platform\n * webhook (Slack, Telegram, etc.) where the function timeout is the\n * binding constraint. Code that calls slow remote APIs can use this to apply\n * tighter budgets on this path while leaving normal agent-chat callers\n * (5+ min budget) unaffected.\n */\n isIntegrationCaller?: boolean;\n /**\n * Metadata for the currently-processing integration task. This lets tools\n * that start long-running remote work persist a continuation that can update\n * the originating platform thread after the current function budget ends.\n */\n integration?: {\n taskId: string;\n attempts?: number;\n incoming: import(\"../integrations/types.js\").IncomingMessage;\n placeholderRef?: string;\n /** Opaque provider-native progress surface for a durable continuation. */\n progressRef?: import(\"../integrations/types.js\").PlatformRunProgressRef;\n installationId?: string;\n scopeId?: string;\n principalType?: \"user\" | \"service\";\n lineage?: {\n runId?: string;\n parentTaskId?: string;\n source?: {\n kind: string;\n platform?: string;\n id: string;\n url?: string;\n };\n network?: {\n protocol: \"a2a\" | \"mcp\" | \"provider-api\";\n id: string;\n peer?: string;\n };\n };\n };\n /**\n * Mutable per-request agent-run state. Populated by the agent-chat plugin\n * during a run; tool closures dereference it on each invocation.\n */\n run?: RequestRunContext;\n}\n\nconst GLOBAL_KEY = \"__agentNativeRequestContextAls\" as const;\nconst OBSERVERS_KEY = \"__agentNativeRequestContextObservers\" as const;\nconst BOUNDARY_KEY = \"__agentNativeRequestBoundaryInstalled\" as const;\ntype RequestContextObserver = (ctx: RequestContext) => void;\ntype GlobalWithRequestContext = typeof globalThis & {\n [GLOBAL_KEY]?: AsyncLocalStorageLike<RequestContext>;\n [OBSERVERS_KEY]?: RequestContextObserver[];\n [BOUNDARY_KEY]?: boolean;\n};\nconst globalRef = globalThis as GlobalWithRequestContext;\nif (!globalRef[GLOBAL_KEY]) {\n globalRef[GLOBAL_KEY] = AsyncLocalStorageCtor\n ? new AsyncLocalStorageCtor<RequestContext>()\n : new StackAsyncLocalStorage<RequestContext>();\n}\nif (!globalRef[OBSERVERS_KEY]) {\n globalRef[OBSERVERS_KEY] = [];\n}\nconst als = globalRef[GLOBAL_KEY]!;\nconst observers = globalRef[OBSERVERS_KEY]!;\n\n/**\n * Register a callback fired every time `runWithRequestContext` enters a new\n * scope. The hook runs INSIDE the AsyncLocalStorage scope, so observability\n * helpers that read the current isolation scope (e.g. Sentry) attach to the\n * right per-request context.\n *\n * Returned function unregisters the observer. Observers must never throw —\n * any error is swallowed so a misbehaving observer can't break the request\n * path.\n */\nexport function addRequestContextObserver(\n observer: RequestContextObserver,\n): () => void {\n observers.push(observer);\n return () => {\n const i = observers.indexOf(observer);\n if (i !== -1) observers.splice(i, 1);\n };\n}\n\n/**\n * Run a callback within a per-request context. The context is available to all\n * async operations spawned from `fn` via `getRequestUserEmail()` / `getRequestOrgId()`.\n *\n * Any registered `addRequestContextObserver` callbacks fire inside the new\n * scope before `fn` runs, so observability code can pin user/org info onto\n * isolation-scoped backends (Sentry, OpenTelemetry, etc.).\n */\nexport function runWithRequestContext<T>(\n ctx: RequestContext,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n return als.run(ctx, () => {\n if (observers.length > 0) {\n for (const obs of observers) {\n try {\n obs(ctx);\n } catch {\n // Observers must never break the request path.\n }\n }\n }\n return fn();\n });\n}\n\n/**\n * Return the active request context, if this call chain is running under one.\n *\n * This is intentionally distinct from `getRequestUserEmail()`: callers that\n * have an active context with no authenticated user must not fall through to\n * process-wide CLI fallbacks such as `AGENT_USER_EMAIL` or \"latest session\".\n */\nexport function getRequestContext(): RequestContext | undefined {\n const store = als.getStore();\n markAuthContextAccess(store);\n return store;\n}\n\n/**\n * True when AsyncLocalStorage has an active context for this call chain.\n * Useful for helpers that support both HTTP requests and standalone CLI runs.\n */\nexport function hasRequestContext(): boolean {\n return als.getStore() !== undefined;\n}\n\n/**\n * Record that the framework's request-boundary middleware is installed in this\n * process, so every inbound HTTP request runs inside a `RequestContext`.\n *\n * Once that is true, a request-scoped identity read that finds no store can no\n * longer be an HTTP caller — which is what makes the ambient-identity warning\n * in `getRequestUserEmail()` specific enough to be worth emitting.\n */\nexport function markRequestBoundaryInstalled(): void {\n globalRef[BOUNDARY_KEY] = true;\n}\n\nexport function hasRequestBoundary(): boolean {\n return globalRef[BOUNDARY_KEY] === true;\n}\n\n/**\n * The ambient, process-wide identity configured for this deployment\n * (`AGENT_USER_EMAIL`). Legitimate callers are the ones with no request behind\n * them at all: CLI invocations, cron/scheduled jobs, seed and QA scripts.\n *\n * TRAP: this is not the caller's identity, and a request handler that reads it\n * authorizes whoever the deploy env names rather than whoever signed in — it\n * fails open toward more privilege. Request handlers read\n * `getRequestUserEmail()` and fail closed when it returns undefined.\n */\nexport function getAmbientUserEmail(): string | undefined {\n return processEnv(\"AGENT_USER_EMAIL\");\n}\n\n/** Ambient process-wide org (`AGENT_ORG_ID`). Same trap as `getAmbientUserEmail()`. */\nexport function getAmbientOrgId(): string | undefined {\n return processEnv(\"AGENT_ORG_ID\");\n}\n\nconst warnedAmbientIdentities = new Set<string>();\n\nfunction warnAmbientIdentitySatisfiedRead(email: string): void {\n if (!hasRequestBoundary()) return;\n if (warnedAmbientIdentities.has(email)) return;\n warnedAmbientIdentities.add(email);\n console.warn(\n `[agent-native] getRequestUserEmail() found no request context and answered with the ambient ` +\n `AGENT_USER_EMAIL identity (${email}). This process serves HTTP requests, so a request-scoped ` +\n `read reaching the ambient identity is a bug: it authorizes the deploy env, not the signed-in ` +\n `user. Wrap the caller in runWithRequestContext({ userEmail }), or call getAmbientUserEmail() ` +\n `explicitly if the process identity really is what you mean.`,\n );\n}\n\n/**\n * Get the current request's user email.\n *\n * - If a request context exists (HTTP/A2A path), returns its `userEmail` —\n * even when that value is `undefined`. The env fallback MUST NOT fire here:\n * a stale process-wide `AGENT_USER_EMAIL` from a CLI run or previous bug\n * would leak into an unauthenticated A2A/API call (e.g. unsigned or API-key\n * modes where `runWithRequestContext({ userEmail: undefined })` is used).\n * - Only when there is NO request context (CLI scripts) do we fall back to\n * `process.env.AGENT_USER_EMAIL`. In a process that serves HTTP requests the\n * framework installs a request boundary so that case cannot be a request;\n * if it happens anyway we warn loudly rather than answer silently.\n */\nexport function getRequestUserEmail(): string | undefined {\n const store = als.getStore();\n if (store !== undefined) {\n if (store.userEmail) markAuthContextAccess(store);\n return store.userEmail;\n }\n const ambient = processEnv(\"AGENT_USER_EMAIL\");\n if (ambient) warnAmbientIdentitySatisfiedRead(ambient);\n return ambient;\n}\n\n/**\n * Get the current request's display name, when the auth provider supplied one.\n *\n * The same request-context fallback rules as `getRequestUserEmail()` apply:\n * HTTP/A2A calls only read AsyncLocalStorage, while CLI scripts may opt in via\n * `AGENT_USER_NAME`.\n */\nexport function getRequestUserName(): string | undefined {\n const store = als.getStore();\n if (store !== undefined) {\n if (store.userName) markAuthContextAccess(store);\n return store.userName;\n }\n return processEnv(\"AGENT_USER_NAME\");\n}\n\n/**\n * Get the current request's org ID.\n *\n * Same store-aware semantics as `getRequestUserEmail()` — env fallback is\n * CLI-only, so a request that explicitly has no org doesn't inherit a stale\n * `process.env.AGENT_ORG_ID` from a prior request on the same Lambda instance.\n */\nexport function getRequestOrgId(): string | undefined {\n const store = als.getStore();\n if (store !== undefined) {\n if (store.orgId) markAuthContextAccess(store);\n return store.orgId;\n }\n return processEnv(\"AGENT_ORG_ID\");\n}\n\nfunction markAuthContextAccess(ctx: RequestContext | undefined) {\n if (!ctx) return;\n if (ctx.userEmail || ctx.userName || ctx.orgId) {\n ctx.authContextAccessed = true;\n }\n}\n\nexport function hasAuthContextAccess(ctx: RequestContext | undefined): boolean {\n return Boolean(ctx?.authContextAccessed);\n}\n\n/**\n * Get the current request's IANA timezone (e.g. \"America/Los_Angeles\").\n * The UI sends this via the `x-user-timezone` header on every action call, and\n * the agent chat plugin propagates it into the request context so that\n * agent-initiated tool calls also see the user's timezone. Falls back to\n * `process.env.AGENT_USER_TIMEZONE` only for CLI scripts (no request context).\n */\nexport function getRequestTimezone(): string | undefined {\n const store = als.getStore();\n if (store !== undefined) return store.timezone;\n return processEnv(\"AGENT_USER_TIMEZONE\");\n}\n\n/**\n * Returns true when this request is on an integration-platform path (Slack,\n * Telegram, etc.) — i.e. we're inside the integration plugin's processor\n * function and the platform's deliver-by deadline plus the host's function\n * timeout are the binding budget. Non-integration callers (CLI, normal\n * agent chat) should treat this as `false`.\n */\nexport function isIntegrationCallerRequest(): boolean {\n return als.getStore()?.isIntegrationCaller === true;\n}\n\nexport function getIntegrationRequestContext():\n | NonNullable<RequestContext[\"integration\"]>\n | undefined {\n return als.getStore()?.integration;\n}\n\n/**\n * Convenience: returns `{ userEmail, orgId }` from the active request context,\n * suitable for passing to `resolveCredential(key, ctx)`. Returns `null` when\n * no user is associated with the call (e.g. an unauthenticated public route).\n *\n * For framework actions auto-mounted at `/_agent-native/actions/...` this is\n * always populated because action-routes wraps every invocation in\n * `runWithRequestContext`. For hand-written `/api/*` routes the calling code\n * is responsible for setting up the context (see `runWithRequestContext`).\n */\nexport function getCredentialContext(): {\n userEmail: string;\n orgId: string | null;\n} | null {\n const userEmail = getRequestUserEmail();\n if (!userEmail) return null;\n return { userEmail, orgId: getRequestOrgId() ?? null };\n}\n\n/**\n * Get the active request's mutable agent-run state. Returns `undefined` when\n * called outside an agent run (e.g. before `prepareRun` or in a non-agent\n * code path). Callers must tolerate the field absence; use the helper\n * `requireRequestRunContext()` if missing context is a programming error.\n */\nexport function getRequestRunContext(): RequestRunContext | undefined {\n const store = als.getStore();\n if (!store) return undefined;\n return store.run;\n}\n\n/**\n * Ensure a `RequestRunContext` exists on the active request store and\n * return it. Used by the agent-chat handler to attach run state once it\n * starts processing a chat request. Returns `undefined` if there is no\n * active request store (caller should not be invoking this outside ALS).\n */\nexport function ensureRequestRunContext(): RequestRunContext | undefined {\n const store = als.getStore();\n if (!store) return undefined;\n if (!store.run) store.run = {};\n return store.run;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Per-request context using AsyncLocalStorage.\n *\n * Replaces the unsafe pattern of mutating `process.env.AGENT_USER_EMAIL` /\n * `process.env.AGENT_ORG_ID` on every request. On Node.js (Netlify, self-hosted)\n * concurrent requests would overwrite each other's env vars. AsyncLocalStorage\n * gives each async call-chain its own isolated context.\n *\n * Supported on all deployment targets:\n * - Node.js (native)\n * - Cloudflare Workers (via nodejs_compat flag)\n * - Deno Deploy (via node:async_hooks compat)\n *\n * For CLI scripts that run outside a request context, the getters fall back to\n * process.env so existing `AGENT_USER_EMAIL=x pnpm action foo` invocations\n * continue to work.\n */\n\ntype AsyncLocalStorageLike<T> = {\n getStore(): T | undefined;\n run<R>(store: T, callback: () => R): R;\n};\n\ntype AsyncLocalStorageCtor = new <T>() => AsyncLocalStorageLike<T>;\n\nclass StackAsyncLocalStorage<T> implements AsyncLocalStorageLike<T> {\n private readonly stack: T[] = [];\n\n getStore(): T | undefined {\n return this.stack.at(-1);\n }\n\n run<R>(store: T, callback: () => R): R {\n this.stack.push(store);\n try {\n const result = callback();\n const maybePromise = result as unknown as\n | { finally?: (callback: () => void) => unknown }\n | undefined;\n if (maybePromise && typeof maybePromise.finally === \"function\") {\n return maybePromise.finally(() => {\n this.stack.pop();\n }) as R;\n }\n this.stack.pop();\n return result;\n } catch (error) {\n this.stack.pop();\n throw error;\n }\n }\n}\n\nfunction getAsyncLocalStorageCtor(): AsyncLocalStorageCtor | undefined {\n if (\n typeof window !== \"undefined\" ||\n typeof process === \"undefined\" ||\n !process.versions?.node ||\n typeof process.getBuiltinModule !== \"function\"\n ) {\n return undefined;\n }\n return process.getBuiltinModule(\"node:async_hooks\")?.AsyncLocalStorage as\n | AsyncLocalStorageCtor\n | undefined;\n}\n\nconst AsyncLocalStorageCtor = getAsyncLocalStorageCtor();\n\nfunction processEnv(name: string): string | undefined {\n if (typeof process === \"undefined\") return undefined;\n return process.env?.[name];\n}\n\n/**\n * Per-request agent-run state. Lives on `RequestContext.run` so the\n * agent-chat plugin can populate fields as the run progresses (owner,\n * resolved API key, system prompt, engine, model, threadId) without\n * mutating module-scope `let` bindings — those leak across concurrent\n * requests on a single Node.js process.\n *\n * Mutated in-place by `prepareRun`, `onEngineResolved`, `onRunStart` so\n * tool factory closures (automation, fetch, team, builder-browser) read\n * the live per-request value via `getRequestRunContext()`.\n */\nexport interface RequestRunContext {\n /** Request-scoped serverless continuation hook, when the runtime provides one. */\n waitUntil?: (promise: Promise<unknown>) => void;\n /** Origin of the current request (used by the builder-browser tool). */\n requestOrigin?: string;\n /** Stable browser tab id for tab-scoped app-state reads/writes. */\n browserTabId?: string;\n /** Resource scope for the current chat thread, e.g. the active deck. */\n chatScope?: {\n type: string;\n id: string;\n label?: string;\n } | null;\n /** Resolved owner email (set by prepareRun). */\n owner?: string;\n /** Owner's active Anthropic API key (set by prepareRun). */\n userApiKey?: string;\n /** Thread ID for the current run (set by onRunStart). */\n threadId?: string;\n /** System prompt actually sent to the model for this run. */\n systemPrompt?: string;\n /** Engine instance for this run (set by onEngineResolved). */\n engine?: import(\"../agent/engine/types.js\").AgentEngine;\n /** Model name for this run (set by onEngineResolved). */\n model?: string;\n /**\n * True when this run is executing inside the durable background-function\n * worker (the `_process-run` self-dispatch), not the synchronous foreground\n * request. Template `extraContext` / system-prompt builders can read this to\n * skip heavy, hang-prone enrichment (large data-dictionary DB reads, etc.)\n * in the worker so it reliably claims its run within the setup budget.\n */\n isBackgroundWorker?: boolean;\n /** Tool calls made so far in the current agent loop. */\n toolCalls?: Array<{ name: string; input: unknown }>;\n /** Tool results returned so far in the current agent loop. */\n toolResults?: Array<{ name: string; content: string; isError: boolean }>;\n /** Per-run fingerprints for large extension bodies already sent to the LLM. */\n extensionContentReads?: Record<string, string>;\n /** Per-run fingerprints for repeated tool-search calls already sent to the LLM. */\n toolSearchReads?: Record<\n string,\n { totalTools: number; resultNames: string[] }\n >;\n}\n\nexport interface RequestContext {\n userEmail?: string;\n userName?: string;\n orgId?: string;\n timezone?: string;\n /**\n * Set when code reads authenticated request context. Public SSR shell/data\n * should not depend on this value; user/org-specific reads belong behind\n * client-side actions/API after hydration.\n */\n authContextAccessed?: boolean;\n /**\n * Origin of the inbound request (e.g. `http://127.0.0.1:8100`). Set by the\n * MCP mount from the request headers so actions that build externally\n * fetchable URLs (e.g. design `export-coding-handoff`'s signed raw-code URL)\n * resolve the real local-workspace origin instead of a prod/localhost\n * fallback. Optional — absent on paths that don't populate it.\n */\n requestOrigin?: string;\n /**\n * True when this request is being processed by an integration-platform\n * webhook (Slack, Telegram, etc.) where the function timeout is the\n * binding constraint. Code that calls slow remote APIs can use this to apply\n * tighter budgets on this path while leaving normal agent-chat callers\n * (5+ min budget) unaffected.\n */\n isIntegrationCaller?: boolean;\n /**\n * Metadata for the currently-processing integration task. This lets tools\n * that start long-running remote work persist a continuation that can update\n * the originating platform thread after the current function budget ends.\n */\n integration?: {\n taskId: string;\n attempts?: number;\n incoming: import(\"../integrations/types.js\").IncomingMessage;\n placeholderRef?: string;\n /** Opaque provider-native progress surface for a durable continuation. */\n progressRef?: import(\"../integrations/types.js\").PlatformRunProgressRef;\n installationId?: string;\n scopeId?: string;\n principalType?: \"user\" | \"service\";\n lineage?: {\n runId?: string;\n parentTaskId?: string;\n source?: {\n kind: string;\n platform?: string;\n id: string;\n url?: string;\n };\n network?: {\n protocol: \"a2a\" | \"mcp\" | \"provider-api\";\n id: string;\n peer?: string;\n };\n };\n };\n /**\n * Mutable per-request agent-run state. Populated by the agent-chat plugin\n * during a run; tool closures dereference it on each invocation.\n */\n run?: RequestRunContext;\n}\n\nconst GLOBAL_KEY = \"__agentNativeRequestContextAls\" as const;\nconst OBSERVERS_KEY = \"__agentNativeRequestContextObservers\" as const;\nconst BOUNDARY_KEY = \"__agentNativeRequestBoundaryInstalled\" as const;\ntype RequestContextObserver = (ctx: RequestContext) => void;\ntype GlobalWithRequestContext = typeof globalThis & {\n [GLOBAL_KEY]?: AsyncLocalStorageLike<RequestContext>;\n [OBSERVERS_KEY]?: RequestContextObserver[];\n [BOUNDARY_KEY]?: boolean;\n};\nconst globalRef = globalThis as GlobalWithRequestContext;\nif (!globalRef[GLOBAL_KEY]) {\n globalRef[GLOBAL_KEY] = AsyncLocalStorageCtor\n ? new AsyncLocalStorageCtor<RequestContext>()\n : new StackAsyncLocalStorage<RequestContext>();\n}\nif (!globalRef[OBSERVERS_KEY]) {\n globalRef[OBSERVERS_KEY] = [];\n}\nconst als = globalRef[GLOBAL_KEY]!;\nconst observers = globalRef[OBSERVERS_KEY]!;\n\n/**\n * Register a callback fired every time `runWithRequestContext` enters a new\n * scope. The hook runs INSIDE the AsyncLocalStorage scope, so observability\n * helpers that read the current isolation scope (e.g. Sentry) attach to the\n * right per-request context.\n *\n * Returned function unregisters the observer. Observers must never throw —\n * any error is swallowed so a misbehaving observer can't break the request\n * path.\n */\nexport function addRequestContextObserver(\n observer: RequestContextObserver,\n): () => void {\n observers.push(observer);\n return () => {\n const i = observers.indexOf(observer);\n if (i !== -1) observers.splice(i, 1);\n };\n}\n\n/**\n * Run a callback within a per-request context. The context is available to all\n * async operations spawned from `fn` via `getRequestUserEmail()` / `getRequestOrgId()`.\n *\n * Any registered `addRequestContextObserver` callbacks fire inside the new\n * scope before `fn` runs, so observability code can pin user/org info onto\n * isolation-scoped backends (Sentry, OpenTelemetry, etc.).\n */\nexport function runWithRequestContext<T>(\n ctx: RequestContext,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n return als.run(ctx, () => {\n if (observers.length > 0) {\n for (const obs of observers) {\n try {\n obs(ctx);\n } catch {\n // Observers must never break the request path.\n }\n }\n }\n return fn();\n });\n}\n\n/**\n * Return the active request context, if this call chain is running under one.\n *\n * This is intentionally distinct from `getRequestUserEmail()`: callers that\n * have an active context with no authenticated user must not fall through to\n * process-wide CLI fallbacks such as `AGENT_USER_EMAIL` or \"latest session\".\n */\nexport function getRequestContext(): RequestContext | undefined {\n const store = als.getStore();\n markAuthContextAccess(store);\n return store;\n}\n\n/**\n * True when AsyncLocalStorage has an active context for this call chain.\n * Useful for helpers that support both HTTP requests and standalone CLI runs.\n */\nexport function hasRequestContext(): boolean {\n return als.getStore() !== undefined;\n}\n\n/**\n * Record that the framework's request-boundary middleware is installed in this\n * process, so every inbound HTTP request runs inside a `RequestContext`.\n *\n * Once that is true, a request-scoped identity read that finds no store can no\n * longer be an HTTP caller — which is what makes the ambient-identity warning\n * in `getRequestUserEmail()` specific enough to be worth emitting.\n */\nexport function markRequestBoundaryInstalled(): void {\n globalRef[BOUNDARY_KEY] = true;\n}\n\nexport function hasRequestBoundary(): boolean {\n return globalRef[BOUNDARY_KEY] === true;\n}\n\n/**\n * The ambient, process-wide identity configured for this deployment\n * (`AGENT_USER_EMAIL`). Legitimate callers are the ones with no request behind\n * them at all: CLI invocations, cron/scheduled jobs, seed and QA scripts.\n *\n * TRAP: this is not the caller's identity, and a request handler that reads it\n * authorizes whoever the deploy env names rather than whoever signed in — it\n * fails open toward more privilege. Request handlers read\n * `getRequestUserEmail()` and fail closed when it returns undefined.\n */\nexport function getAmbientUserEmail(): string | undefined {\n return processEnv(\"AGENT_USER_EMAIL\");\n}\n\n/** Ambient process-wide org (`AGENT_ORG_ID`). Same trap as `getAmbientUserEmail()`. */\nexport function getAmbientOrgId(): string | undefined {\n return processEnv(\"AGENT_ORG_ID\");\n}\n\nconst warnedAmbientIdentities = new Set<string>();\n\nfunction warnAmbientIdentitySatisfiedRead(email: string): void {\n if (!hasRequestBoundary()) return;\n if (warnedAmbientIdentities.has(email)) return;\n warnedAmbientIdentities.add(email);\n console.warn(\n `[agent-native] getRequestUserEmail() found no request context and answered with the ambient ` +\n `AGENT_USER_EMAIL identity (${email}). This process serves HTTP requests, so a request-scoped ` +\n `read reaching the ambient identity is a bug: it authorizes the deploy env, not the signed-in ` +\n `user. Wrap the caller in runWithRequestContext({ userEmail }), or call getAmbientUserEmail() ` +\n `explicitly if the process identity really is what you mean.`,\n );\n}\n\n/**\n * Get the current request's user email.\n *\n * - If a request context exists (HTTP/A2A path), returns its `userEmail` —\n * even when that value is `undefined`. The env fallback MUST NOT fire here:\n * a stale process-wide `AGENT_USER_EMAIL` from a CLI run or previous bug\n * would leak into an unauthenticated A2A/API call (e.g. unsigned or API-key\n * modes where `runWithRequestContext({ userEmail: undefined })` is used).\n * - Only when there is NO request context (CLI scripts) do we fall back to\n * `process.env.AGENT_USER_EMAIL`. In a process that serves HTTP requests the\n * framework installs a request boundary so that case cannot be a request;\n * if it happens anyway we warn loudly rather than answer silently.\n */\nexport function getRequestUserEmail(): string | undefined {\n const store = als.getStore();\n if (store !== undefined) {\n if (store.userEmail) markAuthContextAccess(store);\n return store.userEmail;\n }\n const ambient = processEnv(\"AGENT_USER_EMAIL\");\n if (ambient) warnAmbientIdentitySatisfiedRead(ambient);\n return ambient;\n}\n\n/**\n * Get the current request's display name, when the auth provider supplied one.\n *\n * The same request-context fallback rules as `getRequestUserEmail()` apply:\n * HTTP/A2A calls only read AsyncLocalStorage, while CLI scripts may opt in via\n * `AGENT_USER_NAME`.\n */\nexport function getRequestUserName(): string | undefined {\n const store = als.getStore();\n if (store !== undefined) {\n if (store.userName) markAuthContextAccess(store);\n return store.userName;\n }\n return processEnv(\"AGENT_USER_NAME\");\n}\n\n/**\n * Get the current request's org ID.\n *\n * Same store-aware semantics as `getRequestUserEmail()` — env fallback is\n * CLI-only, so a request that explicitly has no org doesn't inherit a stale\n * `process.env.AGENT_ORG_ID` from a prior request on the same Lambda instance.\n */\nexport function getRequestOrgId(): string | undefined {\n const store = als.getStore();\n if (store !== undefined) {\n if (store.orgId) markAuthContextAccess(store);\n return store.orgId;\n }\n return processEnv(\"AGENT_ORG_ID\");\n}\n\nfunction markAuthContextAccess(ctx: RequestContext | undefined) {\n if (!ctx) return;\n if (ctx.userEmail || ctx.userName || ctx.orgId) {\n ctx.authContextAccessed = true;\n }\n}\n\nexport function hasAuthContextAccess(ctx: RequestContext | undefined): boolean {\n return Boolean(ctx?.authContextAccessed);\n}\n\n/**\n * Get the current request's IANA timezone (e.g. \"America/Los_Angeles\").\n * The UI sends this via the `x-user-timezone` header on every action call, and\n * the agent chat plugin propagates it into the request context so that\n * agent-initiated tool calls also see the user's timezone. Falls back to\n * `process.env.AGENT_USER_TIMEZONE` only for CLI scripts (no request context).\n */\nexport function getRequestTimezone(): string | undefined {\n const store = als.getStore();\n if (store !== undefined) return store.timezone;\n return processEnv(\"AGENT_USER_TIMEZONE\");\n}\n\n/**\n * Returns true when this request is on an integration-platform path (Slack,\n * Telegram, etc.) — i.e. we're inside the integration plugin's processor\n * function and the platform's deliver-by deadline plus the host's function\n * timeout are the binding budget. Non-integration callers (CLI, normal\n * agent chat) should treat this as `false`.\n */\nexport function isIntegrationCallerRequest(): boolean {\n return als.getStore()?.isIntegrationCaller === true;\n}\n\nexport function getIntegrationRequestContext():\n | NonNullable<RequestContext[\"integration\"]>\n | undefined {\n return als.getStore()?.integration;\n}\n\n/**\n * Convenience: returns `{ userEmail, orgId }` from the active request context,\n * suitable for passing to `resolveCredential(key, ctx)`. Returns `null` when\n * no user is associated with the call (e.g. an unauthenticated public route).\n *\n * For framework actions auto-mounted at `/_agent-native/actions/...` this is\n * always populated because action-routes wraps every invocation in\n * `runWithRequestContext`. For hand-written `/api/*` routes the calling code\n * is responsible for setting up the context (see `runWithRequestContext`).\n */\nexport function getCredentialContext(): {\n userEmail: string;\n orgId: string | null;\n} | null {\n const userEmail = getRequestUserEmail();\n if (!userEmail) return null;\n return { userEmail, orgId: getRequestOrgId() ?? null };\n}\n\n/**\n * Get the active request's mutable agent-run state. Returns `undefined` when\n * called outside an agent run (e.g. before `prepareRun` or in a non-agent\n * code path). Callers must tolerate the field absence; use the helper\n * `requireRequestRunContext()` if missing context is a programming error.\n */\nexport function getRequestRunContext(): RequestRunContext | undefined {\n const store = als.getStore();\n if (!store) return undefined;\n return store.run;\n}\n\n/**\n * Ensure a `RequestRunContext` exists on the active request store and\n * return it. Used by the agent-chat handler to attach run state once it\n * starts processing a chat request. Returns `undefined` if there is no\n * active request store (caller should not be invoking this outside ALS).\n */\nexport function ensureRequestRunContext(): RequestRunContext | undefined {\n const store = als.getStore();\n if (!store) return undefined;\n if (!store.run) store.run = {};\n return store.run;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/shared/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,kFAAkF;AAClF,wBAAgB,aAAa,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/shared/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,kFAAkF;AAClF,wBAAgB,aAAa,IAAI,OAAO,CAQvC;AAED,qDAAqD;AACrD,wBAAgB,mBAAmB,IAAI,OAAO,CAO7C;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
|
package/dist/shared/runtime.js
CHANGED
|
@@ -10,11 +10,13 @@ export function isNodeRuntime() {
|
|
|
10
10
|
return (typeof process !== "undefined" &&
|
|
11
11
|
typeof process.versions?.node === "string" &&
|
|
12
12
|
!("__cf_env" in globalThis) &&
|
|
13
|
+
!("__env__" in globalThis) &&
|
|
13
14
|
!("Deno" in globalThis));
|
|
14
15
|
}
|
|
15
16
|
/** True when running in Cloudflare Workers/Pages. */
|
|
16
17
|
export function isCloudflareRuntime() {
|
|
17
18
|
return ("__cf_env" in globalThis ||
|
|
19
|
+
"__env__" in globalThis ||
|
|
18
20
|
(typeof navigator !== "undefined" &&
|
|
19
21
|
navigator.userAgent === "Cloudflare-Workers"));
|
|
20
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/shared/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,kFAAkF;AAClF,MAAM,UAAU,aAAa;IAC3B,OAAO,CACL,OAAO,OAAO,KAAK,WAAW;QAC9B,OAAO,OAAO,CAAC,QAAQ,EAAE,IAAI,KAAK,QAAQ;QAC1C,CAAC,CAAC,UAAU,IAAI,UAAU,CAAC;QAC3B,CAAC,CAAC,MAAM,IAAI,UAAU,CAAC,CACxB,CAAC;AACJ,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,mBAAmB;IACjC,OAAO,CACL,UAAU,IAAI,UAAU;QACxB,CAAC,OAAO,SAAS,KAAK,WAAW;YAC/B,SAAS,CAAC,SAAS,KAAK,oBAAoB,CAAC,CAChD,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,aAAa;IAC3B,OAAO,CAAC,aAAa,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["/**\n * Runtime detection utilities.\n *\n * Detect whether the code is running in Node.js, Cloudflare Workers,\n * Deno, or another edge runtime. Used to gracefully skip Node-only\n * features (filesystem, PTY, file watching) on edge runtimes.\n */\n\n/** True when running in a full Node.js environment (not CF Workers, not Deno). */\nexport function isNodeRuntime(): boolean {\n return (\n typeof process !== \"undefined\" &&\n typeof process.versions?.node === \"string\" &&\n !(\"__cf_env\" in globalThis) &&\n !(\"Deno\" in globalThis)\n );\n}\n\n/** True when running in Cloudflare Workers/Pages. */\nexport function isCloudflareRuntime(): boolean {\n return (\n \"__cf_env\" in globalThis ||\n (typeof navigator !== \"undefined\" &&\n navigator.userAgent === \"Cloudflare-Workers\")\n );\n}\n\n/** True when running in any edge/serverless runtime (not full Node.js). */\nexport function isEdgeRuntime(): boolean {\n return !isNodeRuntime();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/shared/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,kFAAkF;AAClF,MAAM,UAAU,aAAa;IAC3B,OAAO,CACL,OAAO,OAAO,KAAK,WAAW;QAC9B,OAAO,OAAO,CAAC,QAAQ,EAAE,IAAI,KAAK,QAAQ;QAC1C,CAAC,CAAC,UAAU,IAAI,UAAU,CAAC;QAC3B,CAAC,CAAC,SAAS,IAAI,UAAU,CAAC;QAC1B,CAAC,CAAC,MAAM,IAAI,UAAU,CAAC,CACxB,CAAC;AACJ,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,mBAAmB;IACjC,OAAO,CACL,UAAU,IAAI,UAAU;QACxB,SAAS,IAAI,UAAU;QACvB,CAAC,OAAO,SAAS,KAAK,WAAW;YAC/B,SAAS,CAAC,SAAS,KAAK,oBAAoB,CAAC,CAChD,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,aAAa;IAC3B,OAAO,CAAC,aAAa,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["/**\n * Runtime detection utilities.\n *\n * Detect whether the code is running in Node.js, Cloudflare Workers,\n * Deno, or another edge runtime. Used to gracefully skip Node-only\n * features (filesystem, PTY, file watching) on edge runtimes.\n */\n\n/** True when running in a full Node.js environment (not CF Workers, not Deno). */\nexport function isNodeRuntime(): boolean {\n return (\n typeof process !== \"undefined\" &&\n typeof process.versions?.node === \"string\" &&\n !(\"__cf_env\" in globalThis) &&\n !(\"__env__\" in globalThis) &&\n !(\"Deno\" in globalThis)\n );\n}\n\n/** True when running in Cloudflare Workers/Pages. */\nexport function isCloudflareRuntime(): boolean {\n return (\n \"__cf_env\" in globalThis ||\n \"__env__\" in globalThis ||\n (typeof navigator !== \"undefined\" &&\n navigator.userAgent === \"Cloudflare-Workers\")\n );\n}\n\n/** True when running in any edge/serverless runtime (not full Node.js). */\nexport function isEdgeRuntime(): boolean {\n return !isNodeRuntime();\n}\n"]}
|
|
@@ -151,6 +151,35 @@ Rules:
|
|
|
151
151
|
- **Scope matches the registration.** `scope: "user"` → pass the user email.
|
|
152
152
|
`scope: "workspace"` → pass the active `orgId` from
|
|
153
153
|
`getOrgContext(event).orgId`.
|
|
154
|
+
- **One resolver per key, and every runtime path goes through it.** Before
|
|
155
|
+
reading a credential, grep the app for the key name. If a resolver already
|
|
156
|
+
exists (`resolveXConfig`, a connector, a client factory), call it — do not
|
|
157
|
+
read `process.env` for that key a second time somewhere else.
|
|
158
|
+
- **Identity comes from the caller, not the module.** A shared helper under
|
|
159
|
+
`server/lib/` takes the email as a parameter; only an entrypoint (action,
|
|
160
|
+
route, cron) decides whose identity it is. A library that resolves its own
|
|
161
|
+
identity from `process.env.AGENT_USER_EMAIL` authorizes the deployment rather
|
|
162
|
+
than the caller.
|
|
163
|
+
|
|
164
|
+
The failure this prevents is not a leak — it is a split brain. When the config
|
|
165
|
+
check reads the vault and the feature reads `process.env`, the settings UI and
|
|
166
|
+
onboarding checklist report the integration as **configured** while every actual
|
|
167
|
+
call fails with "env var is required". The credential is right there in the
|
|
168
|
+
vault, so the error names the wrong cause and sends everyone hunting for a sync
|
|
169
|
+
or redeploy problem that does not exist. This has now shipped four times in one
|
|
170
|
+
app (BigQuery, Jira, Pylon, Academy).
|
|
171
|
+
|
|
172
|
+
Before finishing any change that touches a credential, run the guard from the
|
|
173
|
+
app directory — it finds this whether the app lives in `templates/` or in a
|
|
174
|
+
workspace repo:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
npx agent-native doctor --only no-env-credentials
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Findings in files that already call `resolveCredential` are usually the
|
|
181
|
+
sanctioned `resolveCredential(key, ctx) ?? process.env.KEY` fallback. The bugs
|
|
182
|
+
are the files with **no** resolver at all.
|
|
154
183
|
|
|
155
184
|
## HTTP routes
|
|
156
185
|
|
|
@@ -92,19 +92,19 @@ const messages = {
|
|
|
92
92
|
curatedTemplates: "قوالب منسقة",
|
|
93
93
|
curatedTemplatesDescription:
|
|
94
94
|
"ابدأ من شكل تطبيق تمت مراجعته، ثم اجعله خاصًا بك.",
|
|
95
|
-
remix: "
|
|
96
|
-
remixTemplate: "
|
|
95
|
+
remix: "إنشاء من قالب",
|
|
96
|
+
remixTemplate: "إنشاء تطبيق {{name}}",
|
|
97
97
|
remixAppIdLabel: "معرّف التطبيق الجديد",
|
|
98
|
-
remixStarted: "
|
|
98
|
+
remixStarted: "بدأ إنشاء {{name}}",
|
|
99
99
|
viewLiveApp: "عرض التطبيق المباشر",
|
|
100
100
|
alreadyInWorkspace: "موجود بالفعل في مساحة العمل",
|
|
101
101
|
remixAppIdDescription:
|
|
102
102
|
"اختر معرّفًا آمنًا لعنوان URL لتطبيق مساحة العمل الجديد.",
|
|
103
103
|
integrationSetup: "إعداد التكامل",
|
|
104
104
|
source: "المصدر",
|
|
105
|
-
remixing: "جارٍ
|
|
106
|
-
remixSuccess: "
|
|
107
|
-
remixError: "
|
|
105
|
+
remixing: "جارٍ إنشاء التطبيق…",
|
|
106
|
+
remixSuccess: "بدأ إنشاء التطبيق من القالب.",
|
|
107
|
+
remixError: "تعذر إنشاء تطبيق من هذا القالب",
|
|
108
108
|
appIdRequired: "معرّف التطبيق مطلوب.",
|
|
109
109
|
hide: "إخفاء",
|
|
110
110
|
show: "Show",
|
|
@@ -91,19 +91,19 @@ const messages = {
|
|
|
91
91
|
curatedTemplates: "Kuratierte Vorlagen",
|
|
92
92
|
curatedTemplatesDescription:
|
|
93
93
|
"Starte mit einer geprüften App-Struktur und passe sie an.",
|
|
94
|
-
remix: "
|
|
95
|
-
remixTemplate: "{{name}}
|
|
94
|
+
remix: "Aus Vorlage erstellen",
|
|
95
|
+
remixTemplate: "{{name}}-App erstellen",
|
|
96
96
|
remixAppIdLabel: "Neue App-ID",
|
|
97
|
-
remixStarted: "
|
|
97
|
+
remixStarted: "Erstellung von {{name}} gestartet",
|
|
98
98
|
viewLiveApp: "Live-App öffnen",
|
|
99
99
|
alreadyInWorkspace: "Bereits im Workspace",
|
|
100
100
|
remixAppIdDescription:
|
|
101
101
|
"Wähle eine URL-sichere ID für die neue Workspace-App.",
|
|
102
102
|
integrationSetup: "Integration einrichten",
|
|
103
103
|
source: "Quelle",
|
|
104
|
-
remixing: "
|
|
105
|
-
remixSuccess: "
|
|
106
|
-
remixError: "
|
|
104
|
+
remixing: "App wird erstellt…",
|
|
105
|
+
remixSuccess: "Erstellung der App aus der Vorlage gestartet.",
|
|
106
|
+
remixError: "App konnte nicht aus dieser Vorlage erstellt werden",
|
|
107
107
|
appIdRequired: "App-ID ist erforderlich.",
|
|
108
108
|
hide: "Ausblenden",
|
|
109
109
|
show: "Show",
|
|
@@ -89,19 +89,19 @@ const messages = {
|
|
|
89
89
|
curatedTemplates: "Curated templates",
|
|
90
90
|
curatedTemplatesDescription:
|
|
91
91
|
"Start from a reviewed app shape, then make it your own.",
|
|
92
|
-
remix: "
|
|
93
|
-
remixTemplate: "
|
|
92
|
+
remix: "Create from template",
|
|
93
|
+
remixTemplate: "Create {{name}} app",
|
|
94
94
|
remixAppIdLabel: "New app id",
|
|
95
|
-
remixStarted: "Started {{name}}
|
|
95
|
+
remixStarted: "Started creating {{name}}",
|
|
96
96
|
viewLiveApp: "View live app",
|
|
97
97
|
alreadyInWorkspace: "Already in workspace",
|
|
98
98
|
remixAppIdDescription:
|
|
99
99
|
"Choose the URL-safe id for the new workspace app.",
|
|
100
100
|
integrationSetup: "Integration setup",
|
|
101
101
|
source: "Source",
|
|
102
|
-
remixing: "
|
|
103
|
-
remixSuccess: "Template
|
|
104
|
-
remixError: "Could not
|
|
102
|
+
remixing: "Creating app…",
|
|
103
|
+
remixSuccess: "Template app creation started.",
|
|
104
|
+
remixError: "Could not create an app from this template",
|
|
105
105
|
appIdRequired: "App ID is required.",
|
|
106
106
|
hide: "Hide",
|
|
107
107
|
show: "Show",
|
|
@@ -91,19 +91,19 @@ const messages = {
|
|
|
91
91
|
curatedTemplates: "Plantillas seleccionadas",
|
|
92
92
|
curatedTemplatesDescription:
|
|
93
93
|
"Empieza con una estructura de aplicación revisada y hazla tuya.",
|
|
94
|
-
remix: "
|
|
95
|
-
remixTemplate: "
|
|
94
|
+
remix: "Crear desde plantilla",
|
|
95
|
+
remixTemplate: "Crear app de {{name}}",
|
|
96
96
|
remixAppIdLabel: "Nuevo ID de aplicación",
|
|
97
|
-
remixStarted: "Se inició la
|
|
97
|
+
remixStarted: "Se inició la creación de {{name}}",
|
|
98
98
|
viewLiveApp: "Ver aplicación en vivo",
|
|
99
99
|
alreadyInWorkspace: "Ya está en el espacio de trabajo",
|
|
100
100
|
remixAppIdDescription:
|
|
101
101
|
"Elige un ID seguro para URL para la nueva aplicación.",
|
|
102
102
|
integrationSetup: "Configuración de integración",
|
|
103
103
|
source: "Origen",
|
|
104
|
-
remixing: "
|
|
105
|
-
remixSuccess: "Se inició la
|
|
106
|
-
remixError: "No se pudo
|
|
104
|
+
remixing: "Creando app…",
|
|
105
|
+
remixSuccess: "Se inició la creación de la app desde la plantilla.",
|
|
106
|
+
remixError: "No se pudo crear una app desde esta plantilla",
|
|
107
107
|
appIdRequired: "El ID de aplicación es obligatorio.",
|
|
108
108
|
hide: "Ocultar",
|
|
109
109
|
show: "Show",
|
|
@@ -93,19 +93,19 @@ const messages = {
|
|
|
93
93
|
curatedTemplates: "Modèles sélectionnés",
|
|
94
94
|
curatedTemplatesDescription:
|
|
95
95
|
"Partez d’une structure d’application vérifiée et personnalisez-la.",
|
|
96
|
-
remix: "
|
|
97
|
-
remixTemplate: "
|
|
96
|
+
remix: "Créer à partir du modèle",
|
|
97
|
+
remixTemplate: "Créer l’app {{name}}",
|
|
98
98
|
remixAppIdLabel: "Nouvel identifiant d’application",
|
|
99
|
-
remixStarted: "
|
|
99
|
+
remixStarted: "Création de {{name}} démarrée",
|
|
100
100
|
viewLiveApp: "Voir l’application en direct",
|
|
101
101
|
alreadyInWorkspace: "Déjà dans l’espace de travail",
|
|
102
102
|
remixAppIdDescription:
|
|
103
103
|
"Choisissez un identifiant compatible avec l’URL pour la nouvelle application.",
|
|
104
104
|
integrationSetup: "Configuration de l’intégration",
|
|
105
105
|
source: "Source",
|
|
106
|
-
remixing: "
|
|
107
|
-
remixSuccess: "
|
|
108
|
-
remixError: "Impossible de
|
|
106
|
+
remixing: "Création de l’app…",
|
|
107
|
+
remixSuccess: "Création de l’app à partir du modèle démarrée.",
|
|
108
|
+
remixError: "Impossible de créer une app à partir de ce modèle",
|
|
109
109
|
appIdRequired: "L’identifiant de l’application est requis.",
|
|
110
110
|
hide: "Masquer",
|
|
111
111
|
show: "Show",
|
|
@@ -87,18 +87,18 @@ const messages = {
|
|
|
87
87
|
curatedTemplates: "चयनित टेम्पलेट",
|
|
88
88
|
curatedTemplatesDescription:
|
|
89
89
|
"समीक्षित ऐप संरचना से शुरू करें और इसे अपने अनुसार बनाएं।",
|
|
90
|
-
remix: "
|
|
91
|
-
remixTemplate: "{{name}}
|
|
90
|
+
remix: "टेम्पलेट से बनाएं",
|
|
91
|
+
remixTemplate: "{{name}} ऐप बनाएं",
|
|
92
92
|
remixAppIdLabel: "नया ऐप आईडी",
|
|
93
|
-
remixStarted: "{{name}}
|
|
93
|
+
remixStarted: "{{name}} बनाना शुरू किया",
|
|
94
94
|
viewLiveApp: "लाइव ऐप देखें",
|
|
95
95
|
alreadyInWorkspace: "वर्कस्पेस में पहले से मौजूद",
|
|
96
96
|
remixAppIdDescription: "नए वर्कस्पेस ऐप के लिए URL-सुरक्षित आईडी चुनें।",
|
|
97
97
|
integrationSetup: "इंटीग्रेशन सेटअप",
|
|
98
98
|
source: "स्रोत",
|
|
99
|
-
remixing: "
|
|
100
|
-
remixSuccess: "टेम्पलेट
|
|
101
|
-
remixError: "
|
|
99
|
+
remixing: "ऐप बनाया जा रहा है…",
|
|
100
|
+
remixSuccess: "टेम्पलेट से ऐप बनाना शुरू किया गया।",
|
|
101
|
+
remixError: "इस टेम्पलेट से ऐप नहीं बना सके",
|
|
102
102
|
appIdRequired: "ऐप आईडी आवश्यक है।",
|
|
103
103
|
hide: "छिपाएं",
|
|
104
104
|
show: "Show",
|
|
@@ -89,19 +89,19 @@ const messages = {
|
|
|
89
89
|
curatedTemplates: "厳選テンプレート",
|
|
90
90
|
curatedTemplatesDescription:
|
|
91
91
|
"レビュー済みのアプリ構成をベースに、自分用にカスタマイズできます。",
|
|
92
|
-
remix: "
|
|
93
|
-
remixTemplate: "{{name}}
|
|
92
|
+
remix: "テンプレートから作成",
|
|
93
|
+
remixTemplate: "{{name}} アプリを作成",
|
|
94
94
|
remixAppIdLabel: "新しいアプリ ID",
|
|
95
|
-
remixStarted: "{{name}}
|
|
95
|
+
remixStarted: "{{name}} の作成を開始しました",
|
|
96
96
|
viewLiveApp: "ライブアプリを見る",
|
|
97
97
|
alreadyInWorkspace: "ワークスペースに追加済み",
|
|
98
98
|
remixAppIdDescription:
|
|
99
99
|
"新しいワークスペースアプリの URL セーフな ID を選択してください。",
|
|
100
100
|
integrationSetup: "連携の設定",
|
|
101
101
|
source: "提供元",
|
|
102
|
-
remixing: "
|
|
103
|
-
remixSuccess: "
|
|
104
|
-
remixError: "
|
|
102
|
+
remixing: "アプリを作成中…",
|
|
103
|
+
remixSuccess: "テンプレートからのアプリ作成を開始しました。",
|
|
104
|
+
remixError: "このテンプレートからアプリを作成できませんでした",
|
|
105
105
|
appIdRequired: "アプリ ID は必須です。",
|
|
106
106
|
hide: "非表示",
|
|
107
107
|
show: "Show",
|
|
@@ -88,18 +88,18 @@ const messages = {
|
|
|
88
88
|
curatedTemplates: "엄선된 템플릿",
|
|
89
89
|
curatedTemplatesDescription:
|
|
90
90
|
"검토된 앱 구조에서 시작해 나만의 앱으로 만들어 보세요.",
|
|
91
|
-
remix: "
|
|
92
|
-
remixTemplate: "{{name}}
|
|
91
|
+
remix: "템플릿에서 만들기",
|
|
92
|
+
remixTemplate: "{{name}} 앱 만들기",
|
|
93
93
|
remixAppIdLabel: "새 앱 ID",
|
|
94
|
-
remixStarted: "{{name}}
|
|
94
|
+
remixStarted: "{{name}} 생성을 시작했습니다",
|
|
95
95
|
viewLiveApp: "라이브 앱 보기",
|
|
96
96
|
alreadyInWorkspace: "워크스페이스에 이미 있음",
|
|
97
97
|
remixAppIdDescription: "새 워크스페이스 앱의 URL 안전 ID를 선택하세요.",
|
|
98
98
|
integrationSetup: "연동 설정",
|
|
99
99
|
source: "소스",
|
|
100
|
-
remixing: "
|
|
101
|
-
remixSuccess: "
|
|
102
|
-
remixError: "이
|
|
100
|
+
remixing: "앱 만드는 중…",
|
|
101
|
+
remixSuccess: "템플릿에서 앱 만들기를 시작했습니다.",
|
|
102
|
+
remixError: "이 템플릿에서 앱을 만들 수 없습니다",
|
|
103
103
|
appIdRequired: "앱 ID가 필요합니다.",
|
|
104
104
|
hide: "숨기기",
|
|
105
105
|
show: "Show",
|
|
@@ -92,19 +92,19 @@ const messages = {
|
|
|
92
92
|
curatedTemplates: "Modelos selecionados",
|
|
93
93
|
curatedTemplatesDescription:
|
|
94
94
|
"Comece com uma estrutura de app revisada e personalize-a.",
|
|
95
|
-
remix: "
|
|
96
|
-
remixTemplate: "
|
|
95
|
+
remix: "Criar a partir do modelo",
|
|
96
|
+
remixTemplate: "Criar app {{name}}",
|
|
97
97
|
remixAppIdLabel: "Novo ID do app",
|
|
98
|
-
remixStarted: "
|
|
98
|
+
remixStarted: "Criação de {{name}} iniciada",
|
|
99
99
|
viewLiveApp: "Ver app ao vivo",
|
|
100
100
|
alreadyInWorkspace: "Já está no workspace",
|
|
101
101
|
remixAppIdDescription:
|
|
102
102
|
"Escolha um ID seguro para URL para o novo app do workspace.",
|
|
103
103
|
integrationSetup: "Configuração da integração",
|
|
104
104
|
source: "Origem",
|
|
105
|
-
remixing: "
|
|
106
|
-
remixSuccess: "
|
|
107
|
-
remixError: "Não foi possível
|
|
105
|
+
remixing: "Criando app…",
|
|
106
|
+
remixSuccess: "Criação do app a partir do modelo iniciada.",
|
|
107
|
+
remixError: "Não foi possível criar um app a partir deste modelo",
|
|
108
108
|
appIdRequired: "O ID do app é obrigatório.",
|
|
109
109
|
hide: "Ocultar",
|
|
110
110
|
show: "Show",
|
|
@@ -85,18 +85,18 @@ const messages = {
|
|
|
85
85
|
curatedTemplates: "精选模板",
|
|
86
86
|
curatedTemplatesDescription:
|
|
87
87
|
"从经过审核的应用结构开始,然后打造属于你的应用。",
|
|
88
|
-
remix: "
|
|
89
|
-
remixTemplate: "
|
|
88
|
+
remix: "从模板创建",
|
|
89
|
+
remixTemplate: "创建 {{name}} 应用",
|
|
90
90
|
remixAppIdLabel: "新应用 ID",
|
|
91
|
-
remixStarted: "
|
|
91
|
+
remixStarted: "已开始创建 {{name}}",
|
|
92
92
|
viewLiveApp: "查看在线应用",
|
|
93
93
|
alreadyInWorkspace: "已在工作区中",
|
|
94
94
|
remixAppIdDescription: "为新的工作区应用选择一个 URL 安全的 ID。",
|
|
95
95
|
integrationSetup: "集成设置",
|
|
96
96
|
source: "来源",
|
|
97
|
-
remixing: "
|
|
98
|
-
remixSuccess: "
|
|
99
|
-
remixError: "
|
|
97
|
+
remixing: "正在创建应用…",
|
|
98
|
+
remixSuccess: "已开始从模板创建应用。",
|
|
99
|
+
remixError: "无法从此模板创建应用",
|
|
100
100
|
appIdRequired: "应用 ID 是必填项。",
|
|
101
101
|
hide: "隐藏",
|
|
102
102
|
show: "Show",
|
|
@@ -85,18 +85,18 @@ const messages = {
|
|
|
85
85
|
curatedTemplates: "精選範本",
|
|
86
86
|
curatedTemplatesDescription:
|
|
87
87
|
"從經過審核的應用程式結構開始,打造屬於你的應用程式。",
|
|
88
|
-
remix: "
|
|
89
|
-
remixTemplate: "
|
|
88
|
+
remix: "從範本建立",
|
|
89
|
+
remixTemplate: "建立 {{name}} 應用程式",
|
|
90
90
|
remixAppIdLabel: "新應用程式 ID",
|
|
91
|
-
remixStarted: "
|
|
91
|
+
remixStarted: "已開始建立 {{name}}",
|
|
92
92
|
viewLiveApp: "查看線上應用程式",
|
|
93
93
|
alreadyInWorkspace: "已在工作區中",
|
|
94
94
|
remixAppIdDescription: "為新的工作區應用程式選擇 URL 安全的 ID。",
|
|
95
95
|
integrationSetup: "整合設定",
|
|
96
96
|
source: "來源",
|
|
97
|
-
remixing: "
|
|
98
|
-
remixSuccess: "
|
|
99
|
-
remixError: "
|
|
97
|
+
remixing: "正在建立應用程式…",
|
|
98
|
+
remixSuccess: "已開始從範本建立應用程式。",
|
|
99
|
+
remixError: "無法從此範本建立應用程式",
|
|
100
100
|
appIdRequired: "應用程式 ID 為必填項目。",
|
|
101
101
|
hide: "隱藏",
|
|
102
102
|
show: "Show",
|
|
@@ -151,6 +151,35 @@ Rules:
|
|
|
151
151
|
- **Scope matches the registration.** `scope: "user"` → pass the user email.
|
|
152
152
|
`scope: "workspace"` → pass the active `orgId` from
|
|
153
153
|
`getOrgContext(event).orgId`.
|
|
154
|
+
- **One resolver per key, and every runtime path goes through it.** Before
|
|
155
|
+
reading a credential, grep the app for the key name. If a resolver already
|
|
156
|
+
exists (`resolveXConfig`, a connector, a client factory), call it — do not
|
|
157
|
+
read `process.env` for that key a second time somewhere else.
|
|
158
|
+
- **Identity comes from the caller, not the module.** A shared helper under
|
|
159
|
+
`server/lib/` takes the email as a parameter; only an entrypoint (action,
|
|
160
|
+
route, cron) decides whose identity it is. A library that resolves its own
|
|
161
|
+
identity from `process.env.AGENT_USER_EMAIL` authorizes the deployment rather
|
|
162
|
+
than the caller.
|
|
163
|
+
|
|
164
|
+
The failure this prevents is not a leak — it is a split brain. When the config
|
|
165
|
+
check reads the vault and the feature reads `process.env`, the settings UI and
|
|
166
|
+
onboarding checklist report the integration as **configured** while every actual
|
|
167
|
+
call fails with "env var is required". The credential is right there in the
|
|
168
|
+
vault, so the error names the wrong cause and sends everyone hunting for a sync
|
|
169
|
+
or redeploy problem that does not exist. This has now shipped four times in one
|
|
170
|
+
app (BigQuery, Jira, Pylon, Academy).
|
|
171
|
+
|
|
172
|
+
Before finishing any change that touches a credential, run the guard from the
|
|
173
|
+
app directory — it finds this whether the app lives in `templates/` or in a
|
|
174
|
+
workspace repo:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
npx agent-native doctor --only no-env-credentials
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Findings in files that already call `resolveCredential` are usually the
|
|
181
|
+
sanctioned `resolveCredential(key, ctx) ?? process.env.KEY` fallback. The bugs
|
|
182
|
+
are the files with **no** resolver at all.
|
|
154
183
|
|
|
155
184
|
## HTTP routes
|
|
156
185
|
|