@agent-native/core 0.7.81 → 0.7.83
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/dist/action.d.ts +8 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +4 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +12 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +58 -20
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +8 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +11 -12
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +13 -17
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/types.d.ts +4 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/application-state/handlers.js +3 -8
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/application-state/script-helpers.d.ts +2 -4
- package/dist/application-state/script-helpers.d.ts.map +1 -1
- package/dist/application-state/script-helpers.js +10 -47
- package/dist/application-state/script-helpers.js.map +1 -1
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +35 -10
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/workspace-dev.js +78 -15
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +6 -2
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +0 -15
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +69 -57
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts +7 -1
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
- package/dist/client/ConnectBuilderCard.js +46 -5
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/ErrorBoundary.d.ts.map +1 -1
- package/dist/client/ErrorBoundary.js +20 -5
- package/dist/client/ErrorBoundary.js.map +1 -1
- package/dist/client/FeedbackButton.d.ts +3 -2
- package/dist/client/FeedbackButton.d.ts.map +1 -1
- package/dist/client/FeedbackButton.js +23 -15
- package/dist/client/FeedbackButton.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +303 -169
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/builder-frame.d.ts +36 -0
- package/dist/client/builder-frame.d.ts.map +1 -1
- package/dist/client/builder-frame.js +80 -9
- package/dist/client/builder-frame.js.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +7 -2
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/PastedTextChip.d.ts +9 -0
- package/dist/client/composer/PastedTextChip.d.ts.map +1 -0
- package/dist/client/composer/PastedTextChip.js +47 -0
- package/dist/client/composer/PastedTextChip.js.map +1 -0
- package/dist/client/composer/PromptComposer.d.ts +4 -2
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +33 -5
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +13 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +61 -16
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts.map +1 -1
- package/dist/client/composer/VoiceButton.js +5 -1
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/composer/pasted-text.d.ts +6 -0
- package/dist/client/composer/pasted-text.d.ts.map +1 -0
- package/dist/client/composer/pasted-text.js +49 -0
- package/dist/client/composer/pasted-text.js.map +1 -0
- package/dist/client/composer/useVoiceDictation.d.ts +1 -0
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +18 -0
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +0 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationCard.js +14 -2
- package/dist/client/integrations/IntegrationCard.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +23 -4
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
- package/dist/client/notifications/NotificationsBell.js +4 -42
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +4 -6
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +84 -74
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +3 -154
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +13 -35
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/settings/SettingsPanel.js +1 -1
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +6 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +3 -0
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +15 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +58 -54
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/tools/ToolEditor.d.ts.map +1 -1
- package/dist/client/tools/ToolEditor.js +34 -4
- package/dist/client/tools/ToolEditor.js.map +1 -1
- package/dist/client/tools/ToolViewer.d.ts.map +1 -1
- package/dist/client/tools/ToolViewer.js +20 -1
- package/dist/client/tools/ToolViewer.js.map +1 -1
- package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
- package/dist/client/tools/ToolsListPage.js +2 -1
- package/dist/client/tools/ToolsListPage.js.map +1 -1
- package/dist/client/tools/ToolsSidebarSection.js +1 -1
- package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
- package/dist/client/transcription/BuilderTranscriptionCta.js +1 -1
- package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +7 -2
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +26 -7
- package/dist/collab/client.js.map +1 -1
- package/dist/jobs/scheduler.js +0 -4
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts +0 -4
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +3 -24
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/observability/routes.d.ts.map +1 -1
- package/dist/observability/routes.js +1 -9
- package/dist/observability/routes.js.map +1 -1
- package/dist/onboarding/default-steps.js +1 -1
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/onboarding/plugin.d.ts.map +1 -1
- package/dist/onboarding/plugin.js +1 -8
- package/dist/onboarding/plugin.js.map +1 -1
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +1 -2
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/context.d.ts +0 -2
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +0 -5
- package/dist/org/context.js.map +1 -1
- package/dist/resources/script-helpers.d.ts +3 -4
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +8 -15
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +4 -4
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/scripts/manage-agent-loop-settings.js +2 -2
- package/dist/scripts/manage-agent-loop-settings.js.map +1 -1
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
- package/dist/scripts/resources/delete-memory.js +4 -2
- package/dist/scripts/resources/delete-memory.js.map +1 -1
- package/dist/scripts/resources/delete.d.ts.map +1 -1
- package/dist/scripts/resources/delete.js +11 -4
- package/dist/scripts/resources/delete.js.map +1 -1
- package/dist/scripts/resources/list.d.ts.map +1 -1
- package/dist/scripts/resources/list.js +5 -3
- package/dist/scripts/resources/list.js.map +1 -1
- package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
- package/dist/scripts/resources/migrate-learnings.js +5 -2
- package/dist/scripts/resources/migrate-learnings.js.map +1 -1
- package/dist/scripts/resources/read.d.ts.map +1 -1
- package/dist/scripts/resources/read.js +4 -2
- package/dist/scripts/resources/read.js.map +1 -1
- package/dist/scripts/resources/save-memory.d.ts.map +1 -1
- package/dist/scripts/resources/save-memory.js +4 -2
- package/dist/scripts/resources/save-memory.js.map +1 -1
- package/dist/scripts/resources/write.d.ts.map +1 -1
- package/dist/scripts/resources/write.js +11 -4
- package/dist/scripts/resources/write.js.map +1 -1
- package/dist/secrets/onboarding.d.ts.map +1 -1
- package/dist/secrets/onboarding.js +1 -9
- package/dist/secrets/onboarding.js.map +1 -1
- package/dist/secrets/routes.d.ts.map +1 -1
- package/dist/secrets/routes.js +2 -7
- package/dist/secrets/routes.js.map +1 -1
- package/dist/server/action-discovery.d.ts +15 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +49 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +5 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +81 -20
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +5 -7
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/auth.d.ts +16 -20
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +115 -333
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +23 -16
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +1 -2
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/google-oauth.d.ts +14 -2
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +32 -10
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/oauth-helpers.d.ts +2 -4
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +2 -4
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +2 -4
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +0 -3
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +13 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.md +1 -0
- package/docs/content/authentication.md +3 -20
- package/docs/content/creating-templates.md +1 -1
- package/docs/content/deployment.md +0 -1
- package/docs/content/security.md +0 -1
- package/docs/content/template-analytics.md +10 -0
- package/docs/content/template-calendar.md +10 -0
- package/docs/content/template-clips.md +10 -0
- package/docs/content/template-content.md +11 -1
- package/docs/content/template-dispatch.md +10 -0
- package/docs/content/template-forms.md +10 -0
- package/docs/content/template-mail.md +10 -0
- package/docs/content/template-slides.md +11 -1
- package/docs/content/template-starter.md +11 -1
- package/docs/content/template-video.md +10 -0
- package/package.json +1 -1
- package/dist/client/dev-mode.d.ts +0 -14
- package/dist/client/dev-mode.d.ts.map +0 -1
- package/dist/client/dev-mode.js +0 -14
- package/dist/client/dev-mode.js.map +0 -1
- package/dist/server/local-migration.d.ts +0 -41
- package/dist/server/local-migration.d.ts.map +0 -1
- package/dist/server/local-migration.js +0 -235
- package/dist/server/local-migration.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/onboarding/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Onboarding plugin — auto-mounts the `/_agent-native/onboarding/*` routes.\n *\n * Routes:\n * GET /_agent-native/onboarding/steps — list steps + completion\n * POST /_agent-native/onboarding/steps/:id/complete — manual override (marks complete)\n * POST /_agent-native/onboarding/dismiss — dismiss the banner\n * GET /_agent-native/onboarding/dismissed — dismissed flag + allComplete\n */\n\nimport {\n defineEventHandler,\n getMethod,\n getQuery,\n setResponseStatus,\n type H3Event,\n} from \"h3\";\nimport {\n awaitBootstrap,\n getH3App,\n markDefaultPluginProvided,\n} from \"../server/framework-request-handler.js\";\nimport { appStateGet, appStatePut } from \"../application-state/store.js\";\nimport { getSession, DEV_MODE_USER_EMAIL } from \"../server/auth.js\";\nimport { runWithRequestContext } from \"../server/request-context.js\";\nimport { listOnboardingSteps } from \"./registry.js\";\nimport { registerDefaultOnboardingSteps } from \"./default-steps.js\";\nimport type {\n OnboardingResolveContext,\n OnboardingStepStatus,\n} from \"./types.js\";\n\ntype NitroPluginDef = (nitroApp: any) => void | Promise<void>;\n\nconst ONBOARDING_PREFIX = \"/_agent-native/onboarding\";\nconst OVERRIDE_KEY_PREFIX = \"onboarding:override:\";\nconst DISMISSED_KEY = \"onboarding:dismissed\";\n\nexport interface OnboardingPluginOptions {\n /** Skip registering the built-in default steps (llm, database, auth). */\n skipDefaultSteps?: boolean;\n}\n\n/** Resolve the caller context used for onboarding and application-state scoping. */\nasync function resolveOnboardingContext(\n event: H3Event,\n): Promise<OnboardingResolveContext> {\n const session = await getSession(event);\n if (!session) return { sessionId: \"local\" };\n if (session.email === DEV_MODE_USER_EMAIL) {\n return {\n sessionId: \"local\",\n userEmail: session.email,\n orgId: session.orgId ?? null,\n };\n }\n return {\n sessionId: session.email,\n userEmail: session.email,\n orgId: session.orgId ?? null,\n };\n}\n\nasync function hasOverride(\n sessionId: string,\n stepId: string,\n): Promise<boolean> {\n // appStateGet hits the DB; on transient connection errors (flaky network /\n // Neon timeout) treat as \"no override\" rather than 500ing the whole route.\n try {\n const val = await appStateGet(sessionId, `${OVERRIDE_KEY_PREFIX}${stepId}`);\n return !!(val && (val as { complete?: boolean }).complete);\n } catch {\n return false;\n }\n}\n\n/**\n * Serialise every registered onboarding step (awaiting `isComplete()`).\n * Honours the per-session \"manual override\" flag in application-state.\n *\n * `preview` short-circuits both the resolver and the override lookup so the\n * dev overlay can render the new-user flow without touching real state.\n */\nasync function serializeSteps(\n context: OnboardingResolveContext,\n options: { preview?: boolean } = {},\n): Promise<OnboardingStepStatus[]> {\n const steps = listOnboardingSteps();\n const out: OnboardingStepStatus[] = [];\n for (const step of steps) {\n let complete = false;\n if (!options.preview) {\n try {\n complete = (await step.isComplete(context)) === true;\n } catch {\n complete = false;\n }\n if (!complete) {\n complete = await hasOverride(context.sessionId, step.id);\n }\n }\n out.push({\n id: step.id,\n title: step.title,\n description: step.description,\n order: step.order,\n required: step.required ?? false,\n complete,\n methods: step.methods,\n });\n }\n return out;\n}\n\nfunction withOnboardingRequestContext<T>(\n context: OnboardingResolveContext,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n return runWithRequestContext(\n {\n userEmail: context.userEmail,\n orgId: context.orgId ?? undefined,\n },\n fn,\n );\n}\n\nfunction allRequiredComplete(statuses: OnboardingStepStatus[]): boolean {\n return statuses.filter((s) => s.required).every((s) => s.complete);\n}\n\nexport function createOnboardingPlugin(\n options: OnboardingPluginOptions = {},\n): NitroPluginDef {\n return async (nitroApp: any) => {\n markDefaultPluginProvided(nitroApp, \"onboarding\");\n await awaitBootstrap(nitroApp);\n\n if (!options.skipDefaultSteps) {\n registerDefaultOnboardingSteps();\n }\n\n // GET /_agent-native/onboarding/steps — list steps\n // POST /_agent-native/onboarding/steps/:id/complete — manual override\n //\n // Mounting on `/steps` means the middleware wrapper strips that prefix,\n // so this handler sees `/` for the list and `/<stepId>/complete` for the\n // override.\n getH3App(nitroApp).use(\n `${ONBOARDING_PREFIX}/steps`,\n defineEventHandler(async (event: H3Event) => {\n const method = getMethod(event);\n const pathname = event.url?.pathname || \"/\";\n const trimmed = pathname.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n\n // List endpoint — GET /steps (pathname becomes \"\" or \"/\")\n if (trimmed === \"\") {\n if (method !== \"GET\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n const context = await resolveOnboardingContext(event);\n const query = getQuery(event) as Record<string, unknown>;\n const preview = query.preview === \"1\" || query.preview === 1;\n return withOnboardingRequestContext(context, () =>\n serializeSteps(context, { preview }),\n );\n }\n\n // Override endpoint — POST /steps/:id/complete\n const [id, action] = trimmed.split(\"/\");\n if (action === \"complete\") {\n if (method !== \"POST\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n if (!id) {\n setResponseStatus(event, 400);\n return { error: \"id required\" };\n }\n const { sessionId } = await resolveOnboardingContext(event);\n await appStatePut(\n sessionId,\n `${OVERRIDE_KEY_PREFIX}${id}`,\n { complete: true },\n { requestSource: \"agent\" },\n );\n return { ok: true, id };\n }\n\n // Unknown subroute — fall through to other middleware.\n return;\n }),\n );\n\n // POST /_agent-native/onboarding/dismiss\n getH3App(nitroApp).use(\n `${ONBOARDING_PREFIX}/dismiss`,\n defineEventHandler(async (event: H3Event) => {\n if (getMethod(event) !== \"POST\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n const { sessionId } = await resolveOnboardingContext(event);\n await appStatePut(\n sessionId,\n DISMISSED_KEY,\n { dismissed: true, at: new Date().toISOString() },\n { requestSource: \"agent\" },\n );\n return { ok: true };\n }),\n );\n\n // POST /_agent-native/onboarding/reopen — clear dismissed flag\n getH3App(nitroApp).use(\n `${ONBOARDING_PREFIX}/reopen`,\n defineEventHandler(async (event: H3Event) => {\n if (getMethod(event) !== \"POST\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n const { sessionId } = await resolveOnboardingContext(event);\n await appStatePut(\n sessionId,\n DISMISSED_KEY,\n { dismissed: false, at: new Date().toISOString() },\n { requestSource: \"agent\" },\n );\n return { ok: true };\n }),\n );\n\n // GET /_agent-native/onboarding/dismissed\n getH3App(nitroApp).use(\n `${ONBOARDING_PREFIX}/dismissed`,\n defineEventHandler(async (event: H3Event) => {\n if (getMethod(event) !== \"GET\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n const context = await resolveOnboardingContext(event);\n // On flaky networks (or transient Neon hiccups) the DB call below\n // can throw — return safe defaults so a transient connection error\n // doesn't surface as a 500 to the client.\n try {\n return await withOnboardingRequestContext(context, async () => {\n const value = await appStateGet(context.sessionId, DISMISSED_KEY);\n const dismissed = !!(\n value && (value as { dismissed?: boolean }).dismissed\n );\n const statuses = await serializeSteps(context);\n return {\n dismissed,\n allComplete: allRequiredComplete(statuses),\n };\n });\n } catch {\n return { dismissed: false, allComplete: false };\n }\n }),\n );\n };\n}\n\n/** Default plugin instance — mounted automatically when a template doesn't override. */\nexport const defaultOnboardingPlugin: NitroPluginDef = createOnboardingPlugin();\n"]}
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/onboarding/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Onboarding plugin — auto-mounts the `/_agent-native/onboarding/*` routes.\n *\n * Routes:\n * GET /_agent-native/onboarding/steps — list steps + completion\n * POST /_agent-native/onboarding/steps/:id/complete — manual override (marks complete)\n * POST /_agent-native/onboarding/dismiss — dismiss the banner\n * GET /_agent-native/onboarding/dismissed — dismissed flag + allComplete\n */\n\nimport {\n defineEventHandler,\n getMethod,\n getQuery,\n setResponseStatus,\n type H3Event,\n} from \"h3\";\nimport {\n awaitBootstrap,\n getH3App,\n markDefaultPluginProvided,\n} from \"../server/framework-request-handler.js\";\nimport { appStateGet, appStatePut } from \"../application-state/store.js\";\nimport { getSession } from \"../server/auth.js\";\nimport { runWithRequestContext } from \"../server/request-context.js\";\nimport { listOnboardingSteps } from \"./registry.js\";\nimport { registerDefaultOnboardingSteps } from \"./default-steps.js\";\nimport type {\n OnboardingResolveContext,\n OnboardingStepStatus,\n} from \"./types.js\";\n\ntype NitroPluginDef = (nitroApp: any) => void | Promise<void>;\n\nconst ONBOARDING_PREFIX = \"/_agent-native/onboarding\";\nconst OVERRIDE_KEY_PREFIX = \"onboarding:override:\";\nconst DISMISSED_KEY = \"onboarding:dismissed\";\n\nexport interface OnboardingPluginOptions {\n /** Skip registering the built-in default steps (llm, database, auth). */\n skipDefaultSteps?: boolean;\n}\n\n/** Resolve the caller context used for onboarding and application-state scoping. */\nasync function resolveOnboardingContext(\n event: H3Event,\n): Promise<OnboardingResolveContext> {\n const session = await getSession(event);\n if (!session) return { sessionId: \"local\" };\n return {\n sessionId: session.email,\n userEmail: session.email,\n orgId: session.orgId ?? null,\n };\n}\n\nasync function hasOverride(\n sessionId: string,\n stepId: string,\n): Promise<boolean> {\n // appStateGet hits the DB; on transient connection errors (flaky network /\n // Neon timeout) treat as \"no override\" rather than 500ing the whole route.\n try {\n const val = await appStateGet(sessionId, `${OVERRIDE_KEY_PREFIX}${stepId}`);\n return !!(val && (val as { complete?: boolean }).complete);\n } catch {\n return false;\n }\n}\n\n/**\n * Serialise every registered onboarding step (awaiting `isComplete()`).\n * Honours the per-session \"manual override\" flag in application-state.\n *\n * `preview` short-circuits both the resolver and the override lookup so the\n * dev overlay can render the new-user flow without touching real state.\n */\nasync function serializeSteps(\n context: OnboardingResolveContext,\n options: { preview?: boolean } = {},\n): Promise<OnboardingStepStatus[]> {\n const steps = listOnboardingSteps();\n const out: OnboardingStepStatus[] = [];\n for (const step of steps) {\n let complete = false;\n if (!options.preview) {\n try {\n complete = (await step.isComplete(context)) === true;\n } catch {\n complete = false;\n }\n if (!complete) {\n complete = await hasOverride(context.sessionId, step.id);\n }\n }\n out.push({\n id: step.id,\n title: step.title,\n description: step.description,\n order: step.order,\n required: step.required ?? false,\n complete,\n methods: step.methods,\n });\n }\n return out;\n}\n\nfunction withOnboardingRequestContext<T>(\n context: OnboardingResolveContext,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n return runWithRequestContext(\n {\n userEmail: context.userEmail,\n orgId: context.orgId ?? undefined,\n },\n fn,\n );\n}\n\nfunction allRequiredComplete(statuses: OnboardingStepStatus[]): boolean {\n return statuses.filter((s) => s.required).every((s) => s.complete);\n}\n\nexport function createOnboardingPlugin(\n options: OnboardingPluginOptions = {},\n): NitroPluginDef {\n return async (nitroApp: any) => {\n markDefaultPluginProvided(nitroApp, \"onboarding\");\n await awaitBootstrap(nitroApp);\n\n if (!options.skipDefaultSteps) {\n registerDefaultOnboardingSteps();\n }\n\n // GET /_agent-native/onboarding/steps — list steps\n // POST /_agent-native/onboarding/steps/:id/complete — manual override\n //\n // Mounting on `/steps` means the middleware wrapper strips that prefix,\n // so this handler sees `/` for the list and `/<stepId>/complete` for the\n // override.\n getH3App(nitroApp).use(\n `${ONBOARDING_PREFIX}/steps`,\n defineEventHandler(async (event: H3Event) => {\n const method = getMethod(event);\n const pathname = event.url?.pathname || \"/\";\n const trimmed = pathname.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n\n // List endpoint — GET /steps (pathname becomes \"\" or \"/\")\n if (trimmed === \"\") {\n if (method !== \"GET\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n const context = await resolveOnboardingContext(event);\n const query = getQuery(event) as Record<string, unknown>;\n const preview = query.preview === \"1\" || query.preview === 1;\n return withOnboardingRequestContext(context, () =>\n serializeSteps(context, { preview }),\n );\n }\n\n // Override endpoint — POST /steps/:id/complete\n const [id, action] = trimmed.split(\"/\");\n if (action === \"complete\") {\n if (method !== \"POST\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n if (!id) {\n setResponseStatus(event, 400);\n return { error: \"id required\" };\n }\n const { sessionId } = await resolveOnboardingContext(event);\n await appStatePut(\n sessionId,\n `${OVERRIDE_KEY_PREFIX}${id}`,\n { complete: true },\n { requestSource: \"agent\" },\n );\n return { ok: true, id };\n }\n\n // Unknown subroute — fall through to other middleware.\n return;\n }),\n );\n\n // POST /_agent-native/onboarding/dismiss\n getH3App(nitroApp).use(\n `${ONBOARDING_PREFIX}/dismiss`,\n defineEventHandler(async (event: H3Event) => {\n if (getMethod(event) !== \"POST\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n const { sessionId } = await resolveOnboardingContext(event);\n await appStatePut(\n sessionId,\n DISMISSED_KEY,\n { dismissed: true, at: new Date().toISOString() },\n { requestSource: \"agent\" },\n );\n return { ok: true };\n }),\n );\n\n // POST /_agent-native/onboarding/reopen — clear dismissed flag\n getH3App(nitroApp).use(\n `${ONBOARDING_PREFIX}/reopen`,\n defineEventHandler(async (event: H3Event) => {\n if (getMethod(event) !== \"POST\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n const { sessionId } = await resolveOnboardingContext(event);\n await appStatePut(\n sessionId,\n DISMISSED_KEY,\n { dismissed: false, at: new Date().toISOString() },\n { requestSource: \"agent\" },\n );\n return { ok: true };\n }),\n );\n\n // GET /_agent-native/onboarding/dismissed\n getH3App(nitroApp).use(\n `${ONBOARDING_PREFIX}/dismissed`,\n defineEventHandler(async (event: H3Event) => {\n if (getMethod(event) !== \"GET\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n const context = await resolveOnboardingContext(event);\n // On flaky networks (or transient Neon hiccups) the DB call below\n // can throw — return safe defaults so a transient connection error\n // doesn't surface as a 500 to the client.\n try {\n return await withOnboardingRequestContext(context, async () => {\n const value = await appStateGet(context.sessionId, DISMISSED_KEY);\n const dismissed = !!(\n value && (value as { dismissed?: boolean }).dismissed\n );\n const statuses = await serializeSteps(context);\n return {\n dismissed,\n allComplete: allRequiredComplete(statuses),\n };\n });\n } catch {\n return { dismissed: false, allComplete: false };\n }\n }),\n );\n };\n}\n\n/** Default plugin instance — mounted automatically when a template doesn't override. */\nexport const defaultOnboardingPlugin: NitroPluginDef = createOnboardingPlugin();\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accept-pending.d.ts","sourceRoot":"","sources":["../../src/org/accept-pending.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"accept-pending.d.ts","sourceRoot":"","sources":["../../src/org/accept-pending.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,CAAC,CA4D9B"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { getDbExec } from "../db/client.js";
|
|
2
2
|
import { putUserSetting } from "../settings/user-settings.js";
|
|
3
|
-
import { DEV_MODE_USER_EMAIL } from "../server/auth.js";
|
|
4
3
|
const nanoid = () => globalThis.crypto?.randomUUID?.().replace(/-/g, "") ??
|
|
5
4
|
Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
6
5
|
/**
|
|
@@ -18,7 +17,7 @@ const nanoid = () => globalThis.crypto?.randomUUID?.().replace(/-/g, "") ??
|
|
|
18
17
|
*/
|
|
19
18
|
export async function acceptPendingInvitationsForEmail(rawEmail) {
|
|
20
19
|
const email = rawEmail.trim().toLowerCase();
|
|
21
|
-
if (!email
|
|
20
|
+
if (!email) {
|
|
22
21
|
return { accepted: [], activeOrgId: null };
|
|
23
22
|
}
|
|
24
23
|
const db = getDbExec();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accept-pending.js","sourceRoot":"","sources":["../../src/org/accept-pending.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"accept-pending.js","sourceRoot":"","sources":["../../src/org/accept-pending.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,MAAM,GAAG,GAAW,EAAE,CAC1B,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;IACnD,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAOhE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,QAAgB;IAEhB,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAEvB,IAAI,IAAI,GAAyC,EAAE,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;YAC3B,GAAG,EAAE;;qCAE0B;YAC/B,IAAI,EAAE,CAAC,KAAK,CAAC;SACd,CAAC,CAAC;QACH,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;YAC/B,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;SACnC,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,iEAAiE;QACjE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,QAAQ,GAAoC,EAAE,CAAC;IACrD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;YAChC,GAAG,EAAE,yEAAyE;YAC9E,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;SACzB,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,EAAE,CAAC,OAAO,CAAC;gBACf,GAAG,EAAE,4FAA4F;gBACjG,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;aAC/C,CAAC,CAAC;QACL,CAAC;QACD,MAAM,EAAE,CAAC,OAAO,CAAC;YACf,GAAG,EAAE,6DAA6D;YAClE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;SACf,CAAC,CAAC;QACH,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,qEAAqE;IACrE,qCAAqC;IACrC,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;IAC/C,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACvE,CAAC;QAAC,MAAM,CAAC;YACP,yEAAyE;QAC3E,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACnC,CAAC","sourcesContent":["import { getDbExec } from \"../db/client.js\";\nimport { putUserSetting } from \"../settings/user-settings.js\";\n\nconst nanoid = (): string =>\n globalThis.crypto?.randomUUID?.().replace(/-/g, \"\") ??\n Math.random().toString(36).slice(2) + Date.now().toString(36);\n\nexport interface AcceptPendingResult {\n accepted: Array<{ invitationId: string; orgId: string }>;\n activeOrgId: string | null;\n}\n\n/**\n * Accept every pending `org_invitations` row for this email:\n * - insert a matching `org_members` row (role 'member') when one doesn't exist\n * - flip the invitation's status to 'accepted'\n * - set the user's `active-org-id` to the most-recently-created invite\n *\n * Called from the Better Auth `user.create.after` hook so that a user who signs\n * up with an email they were just invited to lands in the org immediately,\n * rather than seeing a blank-slate app until they navigate to /team.\n *\n * Safe to call when the org tables don't exist (some templates don't use the\n * org module) — it swallows the \"no such table\" error and returns empty.\n */\nexport async function acceptPendingInvitationsForEmail(\n rawEmail: string,\n): Promise<AcceptPendingResult> {\n const email = rawEmail.trim().toLowerCase();\n if (!email) {\n return { accepted: [], activeOrgId: null };\n }\n\n const db = getDbExec();\n\n let rows: Array<{ id: string; orgId: string }> = [];\n try {\n const res = await db.execute({\n sql: `SELECT id, org_id AS \"orgId\" FROM org_invitations\n WHERE LOWER(email) = ? AND status = 'pending'\n ORDER BY created_at DESC`,\n args: [email],\n });\n rows = res.rows.map((r: any) => ({\n id: String(r.id),\n orgId: String(r.orgId ?? r.org_id),\n }));\n } catch (err) {\n // Template doesn't use the org module / tables not migrated yet.\n return { accepted: [], activeOrgId: null };\n }\n\n if (rows.length === 0) {\n return { accepted: [], activeOrgId: null };\n }\n\n const accepted: AcceptPendingResult[\"accepted\"] = [];\n for (const inv of rows) {\n const existing = await db.execute({\n sql: `SELECT 1 FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [inv.orgId, email],\n });\n if (existing.rows.length === 0) {\n await db.execute({\n sql: `INSERT INTO org_members (id, org_id, email, role, joined_at) VALUES (?, ?, ?, 'member', ?)`,\n args: [nanoid(), inv.orgId, email, Date.now()],\n });\n }\n await db.execute({\n sql: `UPDATE org_invitations SET status = 'accepted' WHERE id = ?`,\n args: [inv.id],\n });\n accepted.push({ invitationId: inv.id, orgId: inv.orgId });\n }\n\n // Set active-org-id to the most recent invite so the user lands in a\n // populated workspace on first load.\n const activeOrgId = accepted[0]?.orgId ?? null;\n if (activeOrgId) {\n try {\n await putUserSetting(email, \"active-org-id\", { orgId: activeOrgId });\n } catch {\n // user_settings table might not exist in a minimal template — not fatal.\n }\n }\n\n return { accepted, activeOrgId };\n}\n"]}
|
package/dist/org/context.d.ts
CHANGED
|
@@ -5,8 +5,6 @@ import type { OrgContext } from "./types.js";
|
|
|
5
5
|
*
|
|
6
6
|
* - For users in multiple orgs, honors their `active-org-id` user setting.
|
|
7
7
|
* - Falls back to the user's first membership.
|
|
8
|
-
* - `local@localhost` (dev / no-auth mode) is treated as a regular identity:
|
|
9
|
-
* it owns whatever orgs it has created locally.
|
|
10
8
|
* - When `AUTO_CREATE_DEFAULT_ORG` is set and the authenticated user has
|
|
11
9
|
* zero memberships, provisions a default org named after the user
|
|
12
10
|
* ({name}'s workspace, falling back to the email local-part). Opt-in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/org/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAKlC,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,YAAY,CAAC;AAatD
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/org/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAKlC,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,YAAY,CAAC;AAatD;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAkEvE;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqBxB;AAqLD;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAaxE;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAa3E;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAaxB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAepD"}
|
package/dist/org/context.js
CHANGED
|
@@ -15,8 +15,6 @@ const nanoid = () => globalThis.crypto?.randomUUID?.().replace(/-/g, "") ??
|
|
|
15
15
|
*
|
|
16
16
|
* - For users in multiple orgs, honors their `active-org-id` user setting.
|
|
17
17
|
* - Falls back to the user's first membership.
|
|
18
|
-
* - `local@localhost` (dev / no-auth mode) is treated as a regular identity:
|
|
19
|
-
* it owns whatever orgs it has created locally.
|
|
20
18
|
* - When `AUTO_CREATE_DEFAULT_ORG` is set and the authenticated user has
|
|
21
19
|
* zero memberships, provisions a default org named after the user
|
|
22
20
|
* ({name}'s workspace, falling back to the email local-part). Opt-in
|
|
@@ -27,9 +25,6 @@ const nanoid = () => globalThis.crypto?.randomUUID?.().replace(/-/g, "") ??
|
|
|
27
25
|
export async function getOrgContext(event) {
|
|
28
26
|
const session = await getSession(event);
|
|
29
27
|
const email = session?.email;
|
|
30
|
-
// No `?? "local@localhost"` fallback — if the session is genuinely
|
|
31
|
-
// missing (misconfigured prod, expired token mid-request) don't
|
|
32
|
-
// silently promote the caller to the shared dev identity.
|
|
33
28
|
if (!email)
|
|
34
29
|
return EMPTY_CONTEXT;
|
|
35
30
|
const exec = getDbExec();
|
package/dist/org/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/org/context.ts"],"names":[],"mappings":"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","sourcesContent":["import type { H3Event } from \"h3\";\nimport { getSession } from \"../server/auth.js\";\nimport { getUserSetting, putUserSetting } from \"../settings/user-settings.js\";\nimport { getDbExec } from \"../db/client.js\";\nimport { getSetting } from \"../settings/store.js\";\nimport type { OrgContext, OrgRole } from \"./types.js\";\n\nconst EMPTY_CONTEXT: OrgContext = {\n email: \"\",\n orgId: null,\n orgName: null,\n role: null,\n};\n\nconst nanoid = (): string =>\n globalThis.crypto?.randomUUID?.().replace(/-/g, \"\") ??\n Math.random().toString(36).slice(2) + Date.now().toString(36);\n\n/**\n * Resolve the current user's organization context from their session.\n *\n * - For users in multiple orgs, honors their `active-org-id` user setting.\n * - Falls back to the user's first membership.\n * - `local@localhost` (dev / no-auth mode) is treated as a regular identity:\n * it owns whatever orgs it has created locally.\n * - When `AUTO_CREATE_DEFAULT_ORG` is set and the authenticated user has\n * zero memberships, provisions a default org named after the user\n * ({name}'s workspace, falling back to the email local-part). Opt-in\n * per deployment so templates that don't use orgs don't accrue phantom\n * default orgs in their DB. The <RequireActiveOrg> client guard remains\n * the safety net for pre-existing accounts or provisioning failures.\n */\nexport async function getOrgContext(event: H3Event): Promise<OrgContext> {\n const session = await getSession(event);\n const email = session?.email;\n // No `?? \"local@localhost\"` fallback — if the session is genuinely\n // missing (misconfigured prod, expired token mid-request) don't\n // silently promote the caller to the shared dev identity.\n if (!email) return EMPTY_CONTEXT;\n\n const exec = getDbExec();\n\n let memberships: Array<{\n orgId: string;\n role: OrgRole;\n orgName: string;\n }> = [];\n try {\n const { rows } = await exec.execute({\n sql: `SELECT m.org_id AS \"orgId\", m.role AS role, o.name AS \"orgName\"\n FROM org_members m\n INNER JOIN organizations o ON m.org_id = o.id\n WHERE LOWER(m.email) = ?`,\n args: [email.toLowerCase()],\n });\n memberships = rows.map((r: any) => ({\n orgId: String(r.orgId ?? r.org_id),\n role: String(r.role) as OrgRole,\n orgName: String(r.orgName ?? r.org_name),\n }));\n } catch {\n // Tables may not exist yet on first boot before migrations finish.\n return { email, orgId: null, orgName: null, role: null };\n }\n\n if (memberships.length === 0 && process.env.AUTO_CREATE_DEFAULT_ORG) {\n const created = await tryCreateDefaultOrg(exec, email, session);\n if (created) return created;\n // Creation failed (race / DB error); fall through and let the\n // RequireActiveOrg client guard prompt the user.\n }\n\n if (memberships.length === 0) {\n return { email, orgId: null, orgName: null, role: null };\n }\n\n if (memberships.length > 1) {\n const activeOrgSetting = (await getUserSetting(email, \"active-org-id\")) as {\n orgId: string;\n } | null;\n if (activeOrgSetting?.orgId) {\n const active = memberships.find(\n (m) => m.orgId === activeOrgSetting.orgId,\n );\n if (active) {\n return {\n email,\n orgId: active.orgId,\n orgName: active.orgName,\n role: active.role,\n };\n }\n }\n }\n\n return {\n email,\n orgId: memberships[0].orgId,\n orgName: memberships[0].orgName,\n role: memberships[0].role,\n };\n}\n\n/**\n * Resolve the active org ID for a given email — for non-HTTP contexts like\n * the integration webhook handler where we have an email but no event/session.\n * Picks the user's active-org-id setting if set, otherwise the first membership.\n * Returns null if the user has no memberships.\n */\nexport async function resolveOrgIdForEmail(\n email: string,\n): Promise<string | null> {\n const exec = getDbExec();\n if (!exec) return null;\n try {\n const { rows } = await exec.execute({\n sql: `SELECT org_id FROM org_members WHERE LOWER(email) = ?`,\n args: [email.toLowerCase()],\n });\n if (rows.length === 0) return null;\n const ids = rows.map((r: any) => String(r.org_id));\n if (ids.length === 1) return ids[0];\n const activeOrgSetting = (await getUserSetting(email, \"active-org-id\")) as {\n orgId: string;\n } | null;\n if (activeOrgSetting?.orgId && ids.includes(activeOrgSetting.orgId)) {\n return activeOrgSetting.orgId;\n }\n return ids[0];\n } catch {\n return null;\n }\n}\n\nfunction defaultOrgName(\n email: string,\n session: { name?: string } | null,\n): string {\n const full = session?.name?.trim();\n if (full) return `${full}'s workspace`;\n const local = email.split(\"@\")[0] ?? email;\n const cleaned = local.replace(/[._-]+/g, \" \").trim();\n const titled =\n cleaned\n .split(\" \")\n .filter(Boolean)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\" \") || \"My\";\n return `${titled}'s workspace`;\n}\n\n/**\n * Check whether the user has a pending invitation. If so, auto-create\n * MUST be skipped — otherwise we'd provision a personal org for them\n * before they ever see the inviter's org in the RequireActiveOrg\n * accept-invite pane, and they'd never join the team that invited them.\n */\nasync function hasPendingInvitation(\n exec: ReturnType<typeof getDbExec>,\n email: string,\n): Promise<boolean> {\n try {\n const { rows } = await exec.execute({\n sql: `SELECT 1 FROM org_invitations WHERE LOWER(email) = ? AND status = 'pending' LIMIT 1`,\n args: [email.toLowerCase()],\n });\n return rows.length > 0;\n } catch {\n // If we can't tell, err on the side of NOT auto-creating — the\n // RequireActiveOrg client guard will surface the situation.\n return true;\n }\n}\n\nasync function hasDomainMatch(\n exec: ReturnType<typeof getDbExec>,\n email: string,\n): Promise<boolean> {\n try {\n const domain = email.split(\"@\")[1]?.toLowerCase();\n if (!domain) return false;\n const { rows } = await exec.execute({\n sql: `SELECT 1 FROM organizations WHERE LOWER(allowed_domain) = ? LIMIT 1`,\n args: [domain],\n });\n return rows.length > 0;\n } catch {\n return false;\n }\n}\n\n/** Stale-claim threshold. A claim row this old is treated as abandoned\n * (process crashed, DELETE failed, etc.) and a new caller may take it\n * over. Long enough that two genuine concurrent first-loads don't\n * trample each other (those settle in milliseconds), short enough that\n * a stuck user recovers on their next navigation. */\nconst CLAIM_TTL_MS = 5 * 60 * 1000;\n\n/**\n * Attempt to provision a default org + owner membership for a user with\n * zero memberships.\n *\n * Race protection: claims the user's auto-create slot via an atomic\n * INSERT into the framework `settings` table (PRIMARY KEY (key) — so\n * concurrent inserts for the same key throw uniqueness violations on\n * both SQLite and Postgres). Only the request that wins the claim\n * proceeds to create the org; losers bail. By the time a losing\n * request retries on a subsequent navigation, the winner's org is in\n * `org_members` and the auto-create branch is skipped entirely.\n *\n * Stuck-state recovery: a stale claim (held longer than CLAIM_TTL_MS)\n * is reclaimed automatically. So even if the DELETE on the failure\n * path fails (network blip, DB error), the user isn't stranded — the\n * next request after the TTL elapses retries cleanly.\n *\n * Returns null on any failure so the caller can fall back to the\n * empty-context / client-guard path.\n */\nasync function tryCreateDefaultOrg(\n exec: ReturnType<typeof getDbExec>,\n email: string,\n session: { name?: string } | null,\n): Promise<OrgContext | null> {\n // Make sure the framework `settings` table exists before we use it as\n // a claim primitive. getSetting() ensures the table on first call.\n await getSetting(\"__init\").catch(() => null);\n\n const claimKey = `u:${email.toLowerCase()}:auto-create-claim`;\n\n if (!(await acquireClaim(exec, claimKey))) return null;\n\n // Pending-invite check happens INSIDE the claim so the window where a\n // newly-arrived invitation can be missed is narrowed to a single SQL\n // round-trip. (A still-narrower window would require a transaction\n // spanning org_invitations and settings — out of scope.)\n if (await hasPendingInvitation(exec, email)) {\n await releaseClaim(exec, claimKey);\n return null;\n }\n\n if (await hasDomainMatch(exec, email)) {\n await releaseClaim(exec, claimKey);\n return null;\n }\n\n try {\n const orgId = nanoid();\n const orgName = defaultOrgName(email, session);\n const now = Date.now();\n\n await exec.execute({\n sql: `INSERT INTO organizations (id, name, created_by, created_at) VALUES (?, ?, ?, ?)`,\n args: [orgId, orgName, email, now],\n });\n await exec.execute({\n sql: `INSERT INTO org_members (id, org_id, email, role, joined_at) VALUES (?, ?, ?, ?, ?)`,\n args: [nanoid(), orgId, email, \"owner\", now],\n });\n\n await putUserSetting(email, \"active-org-id\", { orgId });\n\n return { email, orgId, orgName, role: \"owner\" };\n } catch {\n await releaseClaim(exec, claimKey);\n return null;\n }\n}\n\nasync function acquireClaim(\n exec: ReturnType<typeof getDbExec>,\n claimKey: string,\n): Promise<boolean> {\n const now = Date.now();\n try {\n await exec.execute({\n sql: `INSERT INTO settings (key, value, updated_at) VALUES (?, ?, ?)`,\n args: [claimKey, JSON.stringify({ at: now }), now],\n });\n return true;\n } catch {\n // Conflict — someone else's claim is already in the row. If it's\n // stale (older than CLAIM_TTL_MS) we take it over.\n //\n // CRITICAL: this MUST be a single atomic UPDATE guarded on\n // `updated_at <= staleThreshold`. A read-then-DELETE-then-INSERT\n // sequence lets two concurrent reclaimers each observe the stale\n // timestamp, delete each other's fresh claim, and both think they\n // won — duplicating org creation. The conditional UPDATE matches\n // each stale row at most once: only the first writer sees\n // rowsAffected === 1; the row's updated_at is now `now`, so any\n // subsequent UPDATE no longer satisfies `updated_at <= staleThreshold`\n // and matches zero rows.\n const staleThreshold = now - CLAIM_TTL_MS;\n const result = (await exec.execute({\n sql: `UPDATE settings SET value = ?, updated_at = ? WHERE key = ? AND updated_at <= ?`,\n args: [JSON.stringify({ at: now }), now, claimKey, staleThreshold],\n })) as { rowsAffected?: number };\n return (result.rowsAffected ?? 0) > 0;\n }\n}\n\nasync function releaseClaim(\n exec: ReturnType<typeof getDbExec>,\n claimKey: string,\n): Promise<void> {\n // Best-effort. If this fails (transient network/DB error), the\n // CLAIM_TTL_MS-based takeover in acquireClaim recovers automatically\n // on a future request — no permanent stuck state.\n await exec\n .execute({ sql: `DELETE FROM settings WHERE key = ?`, args: [claimKey] })\n .catch(() => {});\n}\n\n/**\n * Look up the `allowed_domain` for an org by its ID.\n * Used when making outbound A2A calls so the JWT includes the\n * caller's org domain for cross-app org resolution.\n */\nexport async function getOrgDomain(orgId: string): Promise<string | null> {\n try {\n const exec = getDbExec();\n const { rows } = await exec.execute({\n sql: `SELECT allowed_domain FROM organizations WHERE id = ? LIMIT 1`,\n args: [orgId],\n });\n if (!rows[0]) return null;\n const domain = String((rows[0] as any).allowed_domain || \"\");\n return domain || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Look up the org's A2A secret by org ID.\n * Used when making outbound A2A calls so the JWT is signed with the\n * org-specific secret rather than the global A2A_SECRET env var.\n */\nexport async function getOrgA2ASecret(orgId: string): Promise<string | null> {\n try {\n const exec = getDbExec();\n const { rows } = await exec.execute({\n sql: `SELECT a2a_secret FROM organizations WHERE id = ? LIMIT 1`,\n args: [orgId],\n });\n if (!rows[0]) return null;\n const secret = String((rows[0] as any).a2a_secret || \"\");\n return secret || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Look up an org's A2A secret by its `allowed_domain`.\n * Used on the A2A receiving side: the caller's JWT includes `org_domain`,\n * and the receiver looks up which local org matches that domain to find\n * the secret used to verify the JWT signature.\n */\nexport async function getA2ASecretByDomain(\n domain: string,\n): Promise<string | null> {\n try {\n const exec = getDbExec();\n const { rows } = await exec.execute({\n sql: `SELECT a2a_secret FROM organizations WHERE LOWER(allowed_domain) = ? LIMIT 1`,\n args: [domain.toLowerCase()],\n });\n if (!rows[0]) return null;\n const secret = String((rows[0] as any).a2a_secret || \"\");\n return secret || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve a local org by its `allowed_domain`.\n * Used on the A2A receiving side: the caller sends `org_domain` in the JWT,\n * and the receiver looks up which local org matches that domain.\n */\nexport async function resolveOrgByDomain(\n domain: string,\n): Promise<{ orgId: string; orgName: string } | null> {\n try {\n const exec = getDbExec();\n const { rows } = await exec.execute({\n sql: `SELECT id, name FROM organizations WHERE LOWER(allowed_domain) = ? LIMIT 1`,\n args: [domain.toLowerCase()],\n });\n if (!rows[0]) return null;\n return {\n orgId: String((rows[0] as any).id),\n orgName: String((rows[0] as any).name),\n };\n } catch {\n return null;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/org/context.ts"],"names":[],"mappings":"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","sourcesContent":["import type { H3Event } from \"h3\";\nimport { getSession } from \"../server/auth.js\";\nimport { getUserSetting, putUserSetting } from \"../settings/user-settings.js\";\nimport { getDbExec } from \"../db/client.js\";\nimport { getSetting } from \"../settings/store.js\";\nimport type { OrgContext, OrgRole } from \"./types.js\";\n\nconst EMPTY_CONTEXT: OrgContext = {\n email: \"\",\n orgId: null,\n orgName: null,\n role: null,\n};\n\nconst nanoid = (): string =>\n globalThis.crypto?.randomUUID?.().replace(/-/g, \"\") ??\n Math.random().toString(36).slice(2) + Date.now().toString(36);\n\n/**\n * Resolve the current user's organization context from their session.\n *\n * - For users in multiple orgs, honors their `active-org-id` user setting.\n * - Falls back to the user's first membership.\n * - When `AUTO_CREATE_DEFAULT_ORG` is set and the authenticated user has\n * zero memberships, provisions a default org named after the user\n * ({name}'s workspace, falling back to the email local-part). Opt-in\n * per deployment so templates that don't use orgs don't accrue phantom\n * default orgs in their DB. The <RequireActiveOrg> client guard remains\n * the safety net for pre-existing accounts or provisioning failures.\n */\nexport async function getOrgContext(event: H3Event): Promise<OrgContext> {\n const session = await getSession(event);\n const email = session?.email;\n if (!email) return EMPTY_CONTEXT;\n\n const exec = getDbExec();\n\n let memberships: Array<{\n orgId: string;\n role: OrgRole;\n orgName: string;\n }> = [];\n try {\n const { rows } = await exec.execute({\n sql: `SELECT m.org_id AS \"orgId\", m.role AS role, o.name AS \"orgName\"\n FROM org_members m\n INNER JOIN organizations o ON m.org_id = o.id\n WHERE LOWER(m.email) = ?`,\n args: [email.toLowerCase()],\n });\n memberships = rows.map((r: any) => ({\n orgId: String(r.orgId ?? r.org_id),\n role: String(r.role) as OrgRole,\n orgName: String(r.orgName ?? r.org_name),\n }));\n } catch {\n // Tables may not exist yet on first boot before migrations finish.\n return { email, orgId: null, orgName: null, role: null };\n }\n\n if (memberships.length === 0 && process.env.AUTO_CREATE_DEFAULT_ORG) {\n const created = await tryCreateDefaultOrg(exec, email, session);\n if (created) return created;\n // Creation failed (race / DB error); fall through and let the\n // RequireActiveOrg client guard prompt the user.\n }\n\n if (memberships.length === 0) {\n return { email, orgId: null, orgName: null, role: null };\n }\n\n if (memberships.length > 1) {\n const activeOrgSetting = (await getUserSetting(email, \"active-org-id\")) as {\n orgId: string;\n } | null;\n if (activeOrgSetting?.orgId) {\n const active = memberships.find(\n (m) => m.orgId === activeOrgSetting.orgId,\n );\n if (active) {\n return {\n email,\n orgId: active.orgId,\n orgName: active.orgName,\n role: active.role,\n };\n }\n }\n }\n\n return {\n email,\n orgId: memberships[0].orgId,\n orgName: memberships[0].orgName,\n role: memberships[0].role,\n };\n}\n\n/**\n * Resolve the active org ID for a given email — for non-HTTP contexts like\n * the integration webhook handler where we have an email but no event/session.\n * Picks the user's active-org-id setting if set, otherwise the first membership.\n * Returns null if the user has no memberships.\n */\nexport async function resolveOrgIdForEmail(\n email: string,\n): Promise<string | null> {\n const exec = getDbExec();\n if (!exec) return null;\n try {\n const { rows } = await exec.execute({\n sql: `SELECT org_id FROM org_members WHERE LOWER(email) = ?`,\n args: [email.toLowerCase()],\n });\n if (rows.length === 0) return null;\n const ids = rows.map((r: any) => String(r.org_id));\n if (ids.length === 1) return ids[0];\n const activeOrgSetting = (await getUserSetting(email, \"active-org-id\")) as {\n orgId: string;\n } | null;\n if (activeOrgSetting?.orgId && ids.includes(activeOrgSetting.orgId)) {\n return activeOrgSetting.orgId;\n }\n return ids[0];\n } catch {\n return null;\n }\n}\n\nfunction defaultOrgName(\n email: string,\n session: { name?: string } | null,\n): string {\n const full = session?.name?.trim();\n if (full) return `${full}'s workspace`;\n const local = email.split(\"@\")[0] ?? email;\n const cleaned = local.replace(/[._-]+/g, \" \").trim();\n const titled =\n cleaned\n .split(\" \")\n .filter(Boolean)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\" \") || \"My\";\n return `${titled}'s workspace`;\n}\n\n/**\n * Check whether the user has a pending invitation. If so, auto-create\n * MUST be skipped — otherwise we'd provision a personal org for them\n * before they ever see the inviter's org in the RequireActiveOrg\n * accept-invite pane, and they'd never join the team that invited them.\n */\nasync function hasPendingInvitation(\n exec: ReturnType<typeof getDbExec>,\n email: string,\n): Promise<boolean> {\n try {\n const { rows } = await exec.execute({\n sql: `SELECT 1 FROM org_invitations WHERE LOWER(email) = ? AND status = 'pending' LIMIT 1`,\n args: [email.toLowerCase()],\n });\n return rows.length > 0;\n } catch {\n // If we can't tell, err on the side of NOT auto-creating — the\n // RequireActiveOrg client guard will surface the situation.\n return true;\n }\n}\n\nasync function hasDomainMatch(\n exec: ReturnType<typeof getDbExec>,\n email: string,\n): Promise<boolean> {\n try {\n const domain = email.split(\"@\")[1]?.toLowerCase();\n if (!domain) return false;\n const { rows } = await exec.execute({\n sql: `SELECT 1 FROM organizations WHERE LOWER(allowed_domain) = ? LIMIT 1`,\n args: [domain],\n });\n return rows.length > 0;\n } catch {\n return false;\n }\n}\n\n/** Stale-claim threshold. A claim row this old is treated as abandoned\n * (process crashed, DELETE failed, etc.) and a new caller may take it\n * over. Long enough that two genuine concurrent first-loads don't\n * trample each other (those settle in milliseconds), short enough that\n * a stuck user recovers on their next navigation. */\nconst CLAIM_TTL_MS = 5 * 60 * 1000;\n\n/**\n * Attempt to provision a default org + owner membership for a user with\n * zero memberships.\n *\n * Race protection: claims the user's auto-create slot via an atomic\n * INSERT into the framework `settings` table (PRIMARY KEY (key) — so\n * concurrent inserts for the same key throw uniqueness violations on\n * both SQLite and Postgres). Only the request that wins the claim\n * proceeds to create the org; losers bail. By the time a losing\n * request retries on a subsequent navigation, the winner's org is in\n * `org_members` and the auto-create branch is skipped entirely.\n *\n * Stuck-state recovery: a stale claim (held longer than CLAIM_TTL_MS)\n * is reclaimed automatically. So even if the DELETE on the failure\n * path fails (network blip, DB error), the user isn't stranded — the\n * next request after the TTL elapses retries cleanly.\n *\n * Returns null on any failure so the caller can fall back to the\n * empty-context / client-guard path.\n */\nasync function tryCreateDefaultOrg(\n exec: ReturnType<typeof getDbExec>,\n email: string,\n session: { name?: string } | null,\n): Promise<OrgContext | null> {\n // Make sure the framework `settings` table exists before we use it as\n // a claim primitive. getSetting() ensures the table on first call.\n await getSetting(\"__init\").catch(() => null);\n\n const claimKey = `u:${email.toLowerCase()}:auto-create-claim`;\n\n if (!(await acquireClaim(exec, claimKey))) return null;\n\n // Pending-invite check happens INSIDE the claim so the window where a\n // newly-arrived invitation can be missed is narrowed to a single SQL\n // round-trip. (A still-narrower window would require a transaction\n // spanning org_invitations and settings — out of scope.)\n if (await hasPendingInvitation(exec, email)) {\n await releaseClaim(exec, claimKey);\n return null;\n }\n\n if (await hasDomainMatch(exec, email)) {\n await releaseClaim(exec, claimKey);\n return null;\n }\n\n try {\n const orgId = nanoid();\n const orgName = defaultOrgName(email, session);\n const now = Date.now();\n\n await exec.execute({\n sql: `INSERT INTO organizations (id, name, created_by, created_at) VALUES (?, ?, ?, ?)`,\n args: [orgId, orgName, email, now],\n });\n await exec.execute({\n sql: `INSERT INTO org_members (id, org_id, email, role, joined_at) VALUES (?, ?, ?, ?, ?)`,\n args: [nanoid(), orgId, email, \"owner\", now],\n });\n\n await putUserSetting(email, \"active-org-id\", { orgId });\n\n return { email, orgId, orgName, role: \"owner\" };\n } catch {\n await releaseClaim(exec, claimKey);\n return null;\n }\n}\n\nasync function acquireClaim(\n exec: ReturnType<typeof getDbExec>,\n claimKey: string,\n): Promise<boolean> {\n const now = Date.now();\n try {\n await exec.execute({\n sql: `INSERT INTO settings (key, value, updated_at) VALUES (?, ?, ?)`,\n args: [claimKey, JSON.stringify({ at: now }), now],\n });\n return true;\n } catch {\n // Conflict — someone else's claim is already in the row. If it's\n // stale (older than CLAIM_TTL_MS) we take it over.\n //\n // CRITICAL: this MUST be a single atomic UPDATE guarded on\n // `updated_at <= staleThreshold`. A read-then-DELETE-then-INSERT\n // sequence lets two concurrent reclaimers each observe the stale\n // timestamp, delete each other's fresh claim, and both think they\n // won — duplicating org creation. The conditional UPDATE matches\n // each stale row at most once: only the first writer sees\n // rowsAffected === 1; the row's updated_at is now `now`, so any\n // subsequent UPDATE no longer satisfies `updated_at <= staleThreshold`\n // and matches zero rows.\n const staleThreshold = now - CLAIM_TTL_MS;\n const result = (await exec.execute({\n sql: `UPDATE settings SET value = ?, updated_at = ? WHERE key = ? AND updated_at <= ?`,\n args: [JSON.stringify({ at: now }), now, claimKey, staleThreshold],\n })) as { rowsAffected?: number };\n return (result.rowsAffected ?? 0) > 0;\n }\n}\n\nasync function releaseClaim(\n exec: ReturnType<typeof getDbExec>,\n claimKey: string,\n): Promise<void> {\n // Best-effort. If this fails (transient network/DB error), the\n // CLAIM_TTL_MS-based takeover in acquireClaim recovers automatically\n // on a future request — no permanent stuck state.\n await exec\n .execute({ sql: `DELETE FROM settings WHERE key = ?`, args: [claimKey] })\n .catch(() => {});\n}\n\n/**\n * Look up the `allowed_domain` for an org by its ID.\n * Used when making outbound A2A calls so the JWT includes the\n * caller's org domain for cross-app org resolution.\n */\nexport async function getOrgDomain(orgId: string): Promise<string | null> {\n try {\n const exec = getDbExec();\n const { rows } = await exec.execute({\n sql: `SELECT allowed_domain FROM organizations WHERE id = ? LIMIT 1`,\n args: [orgId],\n });\n if (!rows[0]) return null;\n const domain = String((rows[0] as any).allowed_domain || \"\");\n return domain || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Look up the org's A2A secret by org ID.\n * Used when making outbound A2A calls so the JWT is signed with the\n * org-specific secret rather than the global A2A_SECRET env var.\n */\nexport async function getOrgA2ASecret(orgId: string): Promise<string | null> {\n try {\n const exec = getDbExec();\n const { rows } = await exec.execute({\n sql: `SELECT a2a_secret FROM organizations WHERE id = ? LIMIT 1`,\n args: [orgId],\n });\n if (!rows[0]) return null;\n const secret = String((rows[0] as any).a2a_secret || \"\");\n return secret || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Look up an org's A2A secret by its `allowed_domain`.\n * Used on the A2A receiving side: the caller's JWT includes `org_domain`,\n * and the receiver looks up which local org matches that domain to find\n * the secret used to verify the JWT signature.\n */\nexport async function getA2ASecretByDomain(\n domain: string,\n): Promise<string | null> {\n try {\n const exec = getDbExec();\n const { rows } = await exec.execute({\n sql: `SELECT a2a_secret FROM organizations WHERE LOWER(allowed_domain) = ? LIMIT 1`,\n args: [domain.toLowerCase()],\n });\n if (!rows[0]) return null;\n const secret = String((rows[0] as any).a2a_secret || \"\");\n return secret || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve a local org by its `allowed_domain`.\n * Used on the A2A receiving side: the caller sends `org_domain` in the JWT,\n * and the receiver looks up which local org matches that domain.\n */\nexport async function resolveOrgByDomain(\n domain: string,\n): Promise<{ orgId: string; orgName: string } | null> {\n try {\n const exec = getDbExec();\n const { rows } = await exec.execute({\n sql: `SELECT id, name FROM organizations WHERE LOWER(allowed_domain) = ? LIMIT 1`,\n args: [domain.toLowerCase()],\n });\n if (!rows[0]) return null;\n return {\n orgId: String((rows[0] as any).id),\n orgName: String((rows[0] as any).name),\n };\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Resource helpers for use in scripts.
|
|
3
3
|
*
|
|
4
|
-
* Scripts run
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* "local@localhost" for backward compatibility in dev mode.
|
|
4
|
+
* Scripts run inside an authenticated request context (set by the agent
|
|
5
|
+
* runtime) or — in CLI-only contexts — read AGENT_USER_EMAIL. Both paths
|
|
6
|
+
* require a real identity; there is no dev-mode fallback.
|
|
8
7
|
*/
|
|
9
8
|
import { type ResourceMeta } from "./store.js";
|
|
10
9
|
export declare function readResource(path: string, options?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-helpers.d.ts","sourceRoot":"","sources":["../../src/resources/script-helpers.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"script-helpers.d.ts","sourceRoot":"","sources":["../../src/resources/script-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAOL,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAcpB,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED,wBAAsB,aAAa,CACjC,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,OAAO,CAAC,YAAY,EAAE,CAAC,CAGzB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,EAAE,CAAC,CAGzB"}
|
|
@@ -1,29 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Resource helpers for use in scripts.
|
|
3
3
|
*
|
|
4
|
-
* Scripts run
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* "local@localhost" for backward compatibility in dev mode.
|
|
4
|
+
* Scripts run inside an authenticated request context (set by the agent
|
|
5
|
+
* runtime) or — in CLI-only contexts — read AGENT_USER_EMAIL. Both paths
|
|
6
|
+
* require a real identity; there is no dev-mode fallback.
|
|
8
7
|
*/
|
|
9
8
|
import { SHARED_OWNER, resourceGetByPath, resourcePut, resourceDeleteByPath, resourceList, resourceListAccessible, } from "./store.js";
|
|
10
|
-
import { getRequestUserEmail
|
|
11
|
-
// Dev-mode fallback identity. Scripts run as standalone CLI processes
|
|
12
|
-
// without HTTP context — when no AGENT_USER_EMAIL is set we fall back to
|
|
13
|
-
// the dev-mode user so a developer running `pnpm action` locally without
|
|
14
|
-
// signing in still gets a usable scope. Production multi-user deployments
|
|
15
|
-
// always set AGENT_USER_EMAIL via the agent runtime.
|
|
16
|
-
import { DEV_MODE_USER_EMAIL } from "../server/auth.js";
|
|
9
|
+
import { getRequestUserEmail } from "../server/request-context.js";
|
|
17
10
|
function getOwner(shared) {
|
|
18
11
|
if (shared)
|
|
19
12
|
return SHARED_OWNER;
|
|
20
13
|
const userEmail = getRequestUserEmail();
|
|
21
14
|
if (userEmail)
|
|
22
15
|
return userEmail;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
const cliEmail = process.env.AGENT_USER_EMAIL;
|
|
17
|
+
if (cliEmail)
|
|
18
|
+
return cliEmail;
|
|
19
|
+
throw new Error("Resource access requires an authenticated request context or AGENT_USER_EMAIL env var");
|
|
27
20
|
}
|
|
28
21
|
export async function readResource(path, options) {
|
|
29
22
|
const owner = getOwner(options?.shared);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-helpers.js","sourceRoot":"","sources":["../../src/resources/script-helpers.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"script-helpers.js","sourceRoot":"","sources":["../../src/resources/script-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,sBAAsB,GAEvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,SAAS,QAAQ,CAAC,MAAgB;IAChC,IAAI,MAAM;QAAE,OAAO,YAAY,CAAC;IAChC,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;IACxC,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC9C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,OAA8B;IAE9B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACtD,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAY,EACZ,OAAe,EACf,OAAiD;IAEjD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,OAA8B;IAE9B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAe,EACf,OAA8B;IAE9B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAe;IAEf,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,sBAAsB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC","sourcesContent":["/**\n * Resource helpers for use in scripts.\n *\n * Scripts run inside an authenticated request context (set by the agent\n * runtime) or — in CLI-only contexts — read AGENT_USER_EMAIL. Both paths\n * require a real identity; there is no dev-mode fallback.\n */\n\nimport {\n SHARED_OWNER,\n resourceGetByPath,\n resourcePut,\n resourceDeleteByPath,\n resourceList,\n resourceListAccessible,\n type ResourceMeta,\n} from \"./store.js\";\nimport { getRequestUserEmail } from \"../server/request-context.js\";\n\nfunction getOwner(shared?: boolean): string {\n if (shared) return SHARED_OWNER;\n const userEmail = getRequestUserEmail();\n if (userEmail) return userEmail;\n const cliEmail = process.env.AGENT_USER_EMAIL;\n if (cliEmail) return cliEmail;\n throw new Error(\n \"Resource access requires an authenticated request context or AGENT_USER_EMAIL env var\",\n );\n}\n\nexport async function readResource(\n path: string,\n options?: { shared?: boolean },\n): Promise<string | null> {\n const owner = getOwner(options?.shared);\n const resource = await resourceGetByPath(owner, path);\n return resource ? resource.content : null;\n}\n\nexport async function writeResource(\n path: string,\n content: string,\n options?: { shared?: boolean; mimeType?: string },\n): Promise<void> {\n const owner = getOwner(options?.shared);\n await resourcePut(owner, path, content, options?.mimeType);\n}\n\nexport async function deleteResource(\n path: string,\n options?: { shared?: boolean },\n): Promise<boolean> {\n const owner = getOwner(options?.shared);\n return resourceDeleteByPath(owner, path);\n}\n\nexport async function listResources(\n prefix?: string,\n options?: { shared?: boolean },\n): Promise<ResourceMeta[]> {\n const owner = getOwner(options?.shared);\n return resourceList(owner, prefix);\n}\n\nexport async function listAllResources(\n prefix?: string,\n): Promise<ResourceMeta[]> {\n const userEmail = getOwner(false);\n return resourceListAccessible(userEmail, prefix);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-chats.d.ts","sourceRoot":"","sources":["../../../src/scripts/chat/search-chats.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"search-chats.d.ts","sourceRoot":"","sources":["../../../src/scripts/chat/search-chats.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH,wBAA8B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EvE"}
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
import { parseArgs, fail } from "../utils.js";
|
|
10
10
|
import { searchThreads, listThreads } from "../../chat-threads/store.js";
|
|
11
11
|
import { getRequestUserEmail } from "../../server/request-context.js";
|
|
12
|
-
import { DEV_MODE_USER_EMAIL } from "../../server/auth.js";
|
|
13
12
|
function getOwnerEmail() {
|
|
14
|
-
const email = getRequestUserEmail();
|
|
15
|
-
if (!email
|
|
16
|
-
|
|
13
|
+
const email = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;
|
|
14
|
+
if (!email) {
|
|
15
|
+
fail("search-chats requires an authenticated user (request context or AGENT_USER_EMAIL env var).");
|
|
16
|
+
}
|
|
17
17
|
return email;
|
|
18
18
|
}
|
|
19
19
|
function formatTime(ts) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-chats.js","sourceRoot":"","sources":["../../../src/scripts/chat/search-chats.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"search-chats.js","sourceRoot":"","sources":["../../../src/scripts/chat/search-chats.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: search-chats\n *\n * Search or list past agent chat threads.\n *\n * Usage:\n * pnpm action search-chats [--query \"search term\"] [--limit N] [--format json]\n */\n\nimport { parseArgs, fail } from \"../utils.js\";\nimport { searchThreads, listThreads } from \"../../chat-threads/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\n\nfunction getOwnerEmail(): string {\n const email = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;\n if (!email) {\n fail(\n \"search-chats requires an authenticated user (request context or AGENT_USER_EMAIL env var).\",\n );\n }\n return email;\n}\n\nfunction formatTime(ts: number): string {\n const d = new Date(ts);\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffDays = Math.floor(diffMs / 86400000);\n if (diffDays === 0)\n return d.toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" });\n if (diffDays === 1) return \"Yesterday\";\n if (diffDays < 7) return d.toLocaleDateString([], { weekday: \"short\" });\n return d.toLocaleDateString([], { month: \"short\", day: \"numeric\" });\n}\n\nexport default async function searchChats(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action search-chats [options]\n\nOptions:\n --query <text> Search chats by title, preview, or content\n --limit N Max results (default: 20)\n --format json Output as JSON\n --help Show this help message\n\nExamples:\n pnpm action search-chats --query \"email setup\"\n pnpm action search-chats --limit 5\n pnpm action search-chats --format json`);\n return;\n }\n\n const owner = getOwnerEmail();\n const limit = parsed.limit ? parseInt(parsed.limit, 10) : 20;\n if (isNaN(limit) || limit < 1) fail(\"--limit must be a positive integer\");\n\n const query = parsed.query;\n const threads = query\n ? await searchThreads(owner, query, limit)\n : await listThreads(owner, limit, 0);\n\n if (parsed.format === \"json\") {\n console.log(\n JSON.stringify(\n {\n query: query ?? null,\n threads: threads.map((t) => ({\n id: t.id,\n title: t.title,\n preview: t.preview,\n messageCount: t.messageCount,\n updatedAt: t.updatedAt,\n })),\n count: threads.length,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n if (threads.length === 0) {\n console.log(query ? `No chats matching \"${query}\"` : \"No chat history\");\n return;\n }\n\n console.log(\n query\n ? `Chats matching \"${query}\" (${threads.length}):`\n : `Recent chats (${threads.length}):`,\n );\n console.log();\n\n for (const t of threads) {\n const title = t.title || t.preview || \"(untitled)\";\n const msgs = t.messageCount === 1 ? \"1 msg\" : `${t.messageCount} msgs`;\n const time = formatTime(t.updatedAt);\n console.log(` ${title}`);\n console.log(` ID: ${t.id} | ${msgs} | ${time}`);\n if (t.preview && t.title && t.preview !== t.title) {\n console.log(\n ` ${t.preview.slice(0, 80)}${t.preview.length > 80 ? \"...\" : \"\"}`,\n );\n }\n console.log();\n }\n}\n"]}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { canUpdateAgentLoopSettings, readAgentLoopSettings, resetAgentLoopSettings, validateMaxIterationsInput, writeAgentLoopSettings, } from "../agent/loop-settings.js";
|
|
5
5
|
import { getRequestOrgId, getRequestUserEmail, } from "../server/request-context.js";
|
|
6
6
|
export const tool = {
|
|
7
|
-
description: 'Manage the
|
|
7
|
+
description: 'Manage the internal agent loop iteration chunk size before the agent silently continues. Pass action="get" to inspect, action="set" with maxIterations to update the active org/user setting, or action="reset" to return to default.',
|
|
8
8
|
parameters: {
|
|
9
9
|
type: "object",
|
|
10
10
|
properties: {
|
|
@@ -15,7 +15,7 @@ export const tool = {
|
|
|
15
15
|
},
|
|
16
16
|
maxIterations: {
|
|
17
17
|
type: "string",
|
|
18
|
-
description: "(set) Integer step
|
|
18
|
+
description: "(set) Integer internal step chunk size. Applies to the active organization when one is selected; otherwise applies to the current user.",
|
|
19
19
|
},
|
|
20
20
|
},
|
|
21
21
|
required: ["action"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manage-agent-loop-settings.js","sourceRoot":"","sources":["../../src/scripts/manage-agent-loop-settings.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,eAAe,EACf,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,CAAC,MAAM,IAAI,GAAe;IAC9B,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"manage-agent-loop-settings.js","sourceRoot":"","sources":["../../src/scripts/manage-agent-loop-settings.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * manage-agent-loop-settings — inspect or update the agent loop step limit.\n */\n\nimport type { ActionTool } from \"../agent/types.js\";\nimport {\n canUpdateAgentLoopSettings,\n readAgentLoopSettings,\n resetAgentLoopSettings,\n validateMaxIterationsInput,\n writeAgentLoopSettings,\n} from \"../agent/loop-settings.js\";\nimport {\n getRequestOrgId,\n getRequestUserEmail,\n} from \"../server/request-context.js\";\n\nexport const tool: ActionTool = {\n description:\n 'Manage the internal agent loop iteration chunk size before the agent silently continues. Pass action=\"get\" to inspect, action=\"set\" with maxIterations to update the active org/user setting, or action=\"reset\" to return to default.',\n parameters: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n enum: [\"get\", \"set\", \"reset\"],\n description:\n '\"get\" — show the current limit. \"set\" — update maxIterations. \"reset\" — clear the saved override.',\n },\n maxIterations: {\n type: \"string\",\n description:\n \"(set) Integer internal step chunk size. Applies to the active organization when one is selected; otherwise applies to the current user.\",\n },\n },\n required: [\"action\"],\n },\n};\n\nexport async function run(args: Record<string, string>): Promise<string> {\n const action = args.action || \"get\";\n const userEmail = getRequestUserEmail();\n if (!userEmail) {\n return JSON.stringify({ error: \"Authentication required\" });\n }\n\n const orgId = getRequestOrgId() ?? null;\n const ctx = { userEmail, orgId };\n\n if (action === \"get\") {\n const [settings, canUpdate] = await Promise.all([\n readAgentLoopSettings(ctx),\n canUpdateAgentLoopSettings(userEmail, orgId),\n ]);\n return JSON.stringify({ ...settings, canUpdate, orgId }, null, 2);\n }\n\n const canUpdate = await canUpdateAgentLoopSettings(userEmail, orgId);\n if (!canUpdate) {\n return JSON.stringify({\n error: orgId\n ? \"Only organization owners and admins can change the agent step limit.\"\n : \"You cannot change the agent step limit.\",\n });\n }\n\n if (action === \"set\") {\n const validation = validateMaxIterationsInput(args.maxIterations);\n if (validation.ok !== true) {\n return JSON.stringify({ error: validation.error });\n }\n const settings = await writeAgentLoopSettings(ctx, validation.value);\n return JSON.stringify({ ...settings, canUpdate, orgId }, null, 2);\n }\n\n if (action === \"reset\") {\n const settings = await resetAgentLoopSettings(ctx);\n return JSON.stringify({ ...settings, canUpdate, orgId }, null, 2);\n }\n\n return JSON.stringify({\n error: `Unknown action \"${action}\". Must be one of: get, set, reset.`,\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-memory.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/delete-memory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"delete-memory.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/delete-memory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,wBAA8B,kBAAkB,CAC9C,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CAkDf"}
|
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
import { parseArgs, fail } from "../utils.js";
|
|
7
7
|
import { resourcePut, resourceGetByPath, resourceDeleteByPath, } from "../../resources/store.js";
|
|
8
8
|
import { getRequestUserEmail } from "../../server/request-context.js";
|
|
9
|
-
import { DEV_MODE_USER_EMAIL } from "../../server/auth.js";
|
|
10
9
|
export default async function deleteMemoryScript(args) {
|
|
11
10
|
const parsed = parseArgs(args);
|
|
12
11
|
const name = parsed.name;
|
|
13
12
|
if (!name)
|
|
14
13
|
fail("--name is required (e.g. 'coding-style')");
|
|
15
|
-
const owner = getRequestUserEmail() ??
|
|
14
|
+
const owner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;
|
|
15
|
+
if (!owner) {
|
|
16
|
+
fail("delete-memory requires an authenticated user (request context or AGENT_USER_EMAIL env var).");
|
|
17
|
+
}
|
|
16
18
|
const memoryPath = `memory/${name}.md`;
|
|
17
19
|
const indexPath = "memory/MEMORY.md";
|
|
18
20
|
// Delete the memory file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-memory.js","sourceRoot":"","sources":["../../../src/scripts/resources/delete-memory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"delete-memory.js","sourceRoot":"","sources":["../../../src/scripts/resources/delete-memory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,kBAAkB,CAC9C,IAAc;IAEd,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAE/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,IAAI,CAAC,IAAI;QAAE,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAE5D,MAAM,KAAK,GAAG,mBAAmB,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACpE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CACF,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,UAAU,IAAI,KAAK,CAAC;IACvC,MAAM,SAAS,GAAG,kBAAkB,CAAC;IAErC,yBAAyB;IACzB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC9C,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;IAED,oBAAoB;IACpB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC3D,IAAI,QAAQ,EAAE,OAAO,EAAE,CAAC;YACtB,MAAM,WAAW,GAAG,MAAM,IAAI,GAAG,CAAC;YAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;YACvE,IAAI,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gBACrC,MAAM,WAAW,CACf,KAAK,EACL,SAAS,EACT,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,EACpC,eAAe,CAChB,CAAC;gBACF,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,CAAC;IAC3C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,cAAc,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC","sourcesContent":["/**\n * Core script: delete-memory\n *\n * Delete a memory entry and remove it from the index.\n */\n\nimport { parseArgs, fail } from \"../utils.js\";\nimport {\n resourcePut,\n resourceGetByPath,\n resourceDeleteByPath,\n} from \"../../resources/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\n\nexport default async function deleteMemoryScript(\n args: string[],\n): Promise<void> {\n const parsed = parseArgs(args);\n\n const name = parsed.name;\n if (!name) fail(\"--name is required (e.g. 'coding-style')\");\n\n const owner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;\n if (!owner) {\n fail(\n \"delete-memory requires an authenticated user (request context or AGENT_USER_EMAIL env var).\",\n );\n }\n const memoryPath = `memory/${name}.md`;\n const indexPath = \"memory/MEMORY.md\";\n\n // Delete the memory file\n let deleted = false;\n try {\n await resourceDeleteByPath(owner, memoryPath);\n deleted = true;\n } catch {\n // May not exist\n }\n\n // Remove from index\n try {\n const existing = await resourceGetByPath(owner, indexPath);\n if (existing?.content) {\n const entryPrefix = `- [${name}]`;\n const lines = existing.content.split(\"\\n\");\n const filtered = lines.filter((line) => !line.startsWith(entryPrefix));\n if (filtered.length !== lines.length) {\n await resourcePut(\n owner,\n indexPath,\n filtered.join(\"\\n\").trimEnd() + \"\\n\",\n \"text/markdown\",\n );\n deleted = true;\n }\n }\n } catch {\n // Index may not exist\n }\n\n if (deleted) {\n console.log(`Deleted memory \"${name}\".`);\n } else {\n console.log(`Memory \"${name}\" not found.`);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/delete.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/delete.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,wBAA8B,oBAAoB,CAChD,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CAsCf"}
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
import { parseArgs, fail } from "../utils.js";
|
|
10
10
|
import { resourceDeleteByPath, SHARED_OWNER } from "../../resources/store.js";
|
|
11
11
|
import { getRequestUserEmail } from "../../server/request-context.js";
|
|
12
|
-
import { DEV_MODE_USER_EMAIL } from "../../server/auth.js";
|
|
13
12
|
export default async function resourceDeleteScript(args) {
|
|
14
13
|
const parsed = parseArgs(args);
|
|
15
14
|
if (parsed.help === "true") {
|
|
@@ -26,9 +25,17 @@ Options:
|
|
|
26
25
|
fail("--path is required. Example: --path notes/todo.md");
|
|
27
26
|
}
|
|
28
27
|
const scope = parsed.scope ?? "personal";
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
let owner;
|
|
29
|
+
if (scope === "shared") {
|
|
30
|
+
owner = SHARED_OWNER;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const personalOwner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;
|
|
34
|
+
if (!personalOwner) {
|
|
35
|
+
fail("resource-delete --scope=personal requires an authenticated user (request context or AGENT_USER_EMAIL env var).");
|
|
36
|
+
}
|
|
37
|
+
owner = personalOwner;
|
|
38
|
+
}
|
|
32
39
|
const deleted = await resourceDeleteByPath(owner, resourcePath);
|
|
33
40
|
if (deleted) {
|
|
34
41
|
console.log(`Deleted resource: ${resourcePath}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/scripts/resources/delete.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/scripts/resources/delete.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,oBAAoB,CAChD,IAAc;IAEd,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAE/B,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC;;;;;kDAKkC,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC;IACjC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,IAAI,CAAC,mDAAmD,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,UAAU,CAAC;IACzC,IAAI,KAAa,CAAC;IAClB,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,KAAK,GAAG,YAAY,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,MAAM,aAAa,GAAG,mBAAmB,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QAC5E,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,IAAI,CACF,gHAAgH,CACjH,CAAC;QACJ,CAAC;QACD,KAAK,GAAG,aAAa,CAAC;IACxB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAChE,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,qBAAqB,YAAY,EAAE,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC","sourcesContent":["/**\n * Core script: resource-delete\n *\n * Delete a resource from the SQL store.\n *\n * Usage:\n * pnpm action resource-delete --path <path> [--scope personal|shared]\n */\n\nimport { parseArgs, fail } from \"../utils.js\";\nimport { resourceDeleteByPath, SHARED_OWNER } from \"../../resources/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\n\nexport default async function resourceDeleteScript(\n args: string[],\n): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action resource-delete --path <path> [options]\n\nOptions:\n --path <path> Resource path (required)\n --scope personal|shared Scope to delete from (default: personal)\n --help Show this help message`);\n return;\n }\n\n const resourcePath = parsed.path;\n if (!resourcePath) {\n fail(\"--path is required. Example: --path notes/todo.md\");\n }\n\n const scope = parsed.scope ?? \"personal\";\n let owner: string;\n if (scope === \"shared\") {\n owner = SHARED_OWNER;\n } else {\n const personalOwner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;\n if (!personalOwner) {\n fail(\n \"resource-delete --scope=personal requires an authenticated user (request context or AGENT_USER_EMAIL env var).\",\n );\n }\n owner = personalOwner;\n }\n\n const deleted = await resourceDeleteByPath(owner, resourcePath);\n if (deleted) {\n console.log(`Deleted resource: ${resourcePath}`);\n } else {\n console.log(`Resource not found: ${resourcePath}`);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/list.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/list.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,wBAA8B,kBAAkB,CAC9C,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CAwDf"}
|