@agent-native/core 0.7.80 → 0.7.82

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.
Files changed (244) hide show
  1. package/dist/action.d.ts +8 -0
  2. package/dist/action.d.ts.map +1 -1
  3. package/dist/action.js +4 -0
  4. package/dist/action.js.map +1 -1
  5. package/dist/agent/production-agent.d.ts +12 -2
  6. package/dist/agent/production-agent.d.ts.map +1 -1
  7. package/dist/agent/production-agent.js +58 -20
  8. package/dist/agent/production-agent.js.map +1 -1
  9. package/dist/agent/run-manager.d.ts +8 -1
  10. package/dist/agent/run-manager.d.ts.map +1 -1
  11. package/dist/agent/run-manager.js +11 -12
  12. package/dist/agent/run-manager.js.map +1 -1
  13. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  14. package/dist/agent/thread-data-builder.js +13 -17
  15. package/dist/agent/thread-data-builder.js.map +1 -1
  16. package/dist/agent/types.d.ts +4 -0
  17. package/dist/agent/types.d.ts.map +1 -1
  18. package/dist/agent/types.js.map +1 -1
  19. package/dist/application-state/handlers.d.ts.map +1 -1
  20. package/dist/application-state/handlers.js +3 -8
  21. package/dist/application-state/handlers.js.map +1 -1
  22. package/dist/application-state/script-helpers.d.ts +2 -4
  23. package/dist/application-state/script-helpers.d.ts.map +1 -1
  24. package/dist/application-state/script-helpers.js +10 -47
  25. package/dist/application-state/script-helpers.js.map +1 -1
  26. package/dist/cli/workspace-dev.js +78 -15
  27. package/dist/cli/workspace-dev.js.map +1 -1
  28. package/dist/client/AgentPanel.d.ts.map +1 -1
  29. package/dist/client/AgentPanel.js +6 -2
  30. package/dist/client/AgentPanel.js.map +1 -1
  31. package/dist/client/AssistantChat.d.ts +0 -15
  32. package/dist/client/AssistantChat.d.ts.map +1 -1
  33. package/dist/client/AssistantChat.js +69 -57
  34. package/dist/client/AssistantChat.js.map +1 -1
  35. package/dist/client/ConnectBuilderCard.d.ts +7 -1
  36. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  37. package/dist/client/ConnectBuilderCard.js +46 -5
  38. package/dist/client/ConnectBuilderCard.js.map +1 -1
  39. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  40. package/dist/client/ErrorBoundary.js +20 -5
  41. package/dist/client/ErrorBoundary.js.map +1 -1
  42. package/dist/client/FeedbackButton.d.ts.map +1 -1
  43. package/dist/client/FeedbackButton.js +5 -1
  44. package/dist/client/FeedbackButton.js.map +1 -1
  45. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  46. package/dist/client/agent-chat-adapter.js +303 -169
  47. package/dist/client/agent-chat-adapter.js.map +1 -1
  48. package/dist/client/builder-frame.d.ts +25 -0
  49. package/dist/client/builder-frame.d.ts.map +1 -1
  50. package/dist/client/builder-frame.js +40 -0
  51. package/dist/client/builder-frame.js.map +1 -1
  52. package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
  53. package/dist/client/composer/ComposerPlusMenu.js +7 -2
  54. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  55. package/dist/client/composer/PastedTextChip.d.ts +9 -0
  56. package/dist/client/composer/PastedTextChip.d.ts.map +1 -0
  57. package/dist/client/composer/PastedTextChip.js +47 -0
  58. package/dist/client/composer/PastedTextChip.js.map +1 -0
  59. package/dist/client/composer/PromptComposer.d.ts +2 -2
  60. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  61. package/dist/client/composer/PromptComposer.js +32 -4
  62. package/dist/client/composer/PromptComposer.js.map +1 -1
  63. package/dist/client/composer/TiptapComposer.d.ts +11 -1
  64. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  65. package/dist/client/composer/TiptapComposer.js +49 -16
  66. package/dist/client/composer/TiptapComposer.js.map +1 -1
  67. package/dist/client/composer/VoiceButton.d.ts.map +1 -1
  68. package/dist/client/composer/VoiceButton.js +5 -1
  69. package/dist/client/composer/VoiceButton.js.map +1 -1
  70. package/dist/client/composer/pasted-text.d.ts +6 -0
  71. package/dist/client/composer/pasted-text.d.ts.map +1 -0
  72. package/dist/client/composer/pasted-text.js +49 -0
  73. package/dist/client/composer/pasted-text.js.map +1 -0
  74. package/dist/client/composer/useVoiceDictation.d.ts +1 -0
  75. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  76. package/dist/client/composer/useVoiceDictation.js +18 -0
  77. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  78. package/dist/client/index.d.ts +0 -1
  79. package/dist/client/index.d.ts.map +1 -1
  80. package/dist/client/index.js +0 -1
  81. package/dist/client/index.js.map +1 -1
  82. package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
  83. package/dist/client/integrations/IntegrationCard.js +14 -2
  84. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  85. package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
  86. package/dist/client/integrations/IntegrationsPanel.js +19 -3
  87. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  88. package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
  89. package/dist/client/notifications/NotificationsBell.js +4 -42
  90. package/dist/client/notifications/NotificationsBell.js.map +1 -1
  91. package/dist/client/org/OrgSwitcher.d.ts +4 -6
  92. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  93. package/dist/client/org/OrgSwitcher.js +84 -74
  94. package/dist/client/org/OrgSwitcher.js.map +1 -1
  95. package/dist/client/org/TeamPage.d.ts.map +1 -1
  96. package/dist/client/org/TeamPage.js +3 -154
  97. package/dist/client/org/TeamPage.js.map +1 -1
  98. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  99. package/dist/client/resources/ResourcesPanel.js +13 -35
  100. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  101. package/dist/client/settings/SettingsPanel.js +1 -1
  102. package/dist/client/settings/SettingsPanel.js.map +1 -1
  103. package/dist/client/settings/useBuilderStatus.d.ts +6 -0
  104. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  105. package/dist/client/settings/useBuilderStatus.js +3 -0
  106. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  107. package/dist/client/sse-event-processor.d.ts +15 -1
  108. package/dist/client/sse-event-processor.d.ts.map +1 -1
  109. package/dist/client/sse-event-processor.js +58 -54
  110. package/dist/client/sse-event-processor.js.map +1 -1
  111. package/dist/client/tools/ToolEditor.d.ts.map +1 -1
  112. package/dist/client/tools/ToolEditor.js +34 -4
  113. package/dist/client/tools/ToolEditor.js.map +1 -1
  114. package/dist/client/tools/ToolViewer.d.ts.map +1 -1
  115. package/dist/client/tools/ToolViewer.js +20 -1
  116. package/dist/client/tools/ToolViewer.js.map +1 -1
  117. package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
  118. package/dist/client/tools/ToolsListPage.js +2 -1
  119. package/dist/client/tools/ToolsListPage.js.map +1 -1
  120. package/dist/client/transcription/BuilderTranscriptionCta.js +1 -1
  121. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
  122. package/dist/client/use-chat-threads.d.ts.map +1 -1
  123. package/dist/client/use-chat-threads.js +7 -2
  124. package/dist/client/use-chat-threads.js.map +1 -1
  125. package/dist/collab/client.d.ts.map +1 -1
  126. package/dist/collab/client.js +26 -7
  127. package/dist/collab/client.js.map +1 -1
  128. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  129. package/dist/integrations/a2a-continuations-store.js +20 -19
  130. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  131. package/dist/jobs/scheduler.js +0 -4
  132. package/dist/jobs/scheduler.js.map +1 -1
  133. package/dist/oauth-tokens/store.d.ts +0 -4
  134. package/dist/oauth-tokens/store.d.ts.map +1 -1
  135. package/dist/oauth-tokens/store.js +3 -24
  136. package/dist/oauth-tokens/store.js.map +1 -1
  137. package/dist/observability/routes.d.ts.map +1 -1
  138. package/dist/observability/routes.js +1 -9
  139. package/dist/observability/routes.js.map +1 -1
  140. package/dist/onboarding/default-steps.js +1 -1
  141. package/dist/onboarding/default-steps.js.map +1 -1
  142. package/dist/onboarding/plugin.d.ts.map +1 -1
  143. package/dist/onboarding/plugin.js +1 -8
  144. package/dist/onboarding/plugin.js.map +1 -1
  145. package/dist/org/accept-pending.d.ts.map +1 -1
  146. package/dist/org/accept-pending.js +1 -2
  147. package/dist/org/accept-pending.js.map +1 -1
  148. package/dist/org/context.d.ts +0 -2
  149. package/dist/org/context.d.ts.map +1 -1
  150. package/dist/org/context.js +0 -5
  151. package/dist/org/context.js.map +1 -1
  152. package/dist/resources/script-helpers.d.ts +3 -4
  153. package/dist/resources/script-helpers.d.ts.map +1 -1
  154. package/dist/resources/script-helpers.js +8 -15
  155. package/dist/resources/script-helpers.js.map +1 -1
  156. package/dist/scripts/chat/search-chats.d.ts.map +1 -1
  157. package/dist/scripts/chat/search-chats.js +4 -4
  158. package/dist/scripts/chat/search-chats.js.map +1 -1
  159. package/dist/scripts/manage-agent-loop-settings.js +2 -2
  160. package/dist/scripts/manage-agent-loop-settings.js.map +1 -1
  161. package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
  162. package/dist/scripts/resources/delete-memory.js +4 -2
  163. package/dist/scripts/resources/delete-memory.js.map +1 -1
  164. package/dist/scripts/resources/delete.d.ts.map +1 -1
  165. package/dist/scripts/resources/delete.js +11 -4
  166. package/dist/scripts/resources/delete.js.map +1 -1
  167. package/dist/scripts/resources/list.d.ts.map +1 -1
  168. package/dist/scripts/resources/list.js +5 -3
  169. package/dist/scripts/resources/list.js.map +1 -1
  170. package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
  171. package/dist/scripts/resources/migrate-learnings.js +5 -2
  172. package/dist/scripts/resources/migrate-learnings.js.map +1 -1
  173. package/dist/scripts/resources/read.d.ts.map +1 -1
  174. package/dist/scripts/resources/read.js +4 -2
  175. package/dist/scripts/resources/read.js.map +1 -1
  176. package/dist/scripts/resources/save-memory.d.ts.map +1 -1
  177. package/dist/scripts/resources/save-memory.js +4 -2
  178. package/dist/scripts/resources/save-memory.js.map +1 -1
  179. package/dist/scripts/resources/write.d.ts.map +1 -1
  180. package/dist/scripts/resources/write.js +11 -4
  181. package/dist/scripts/resources/write.js.map +1 -1
  182. package/dist/secrets/onboarding.d.ts.map +1 -1
  183. package/dist/secrets/onboarding.js +1 -9
  184. package/dist/secrets/onboarding.js.map +1 -1
  185. package/dist/secrets/routes.d.ts.map +1 -1
  186. package/dist/secrets/routes.js +2 -7
  187. package/dist/secrets/routes.js.map +1 -1
  188. package/dist/server/action-discovery.d.ts.map +1 -1
  189. package/dist/server/action-discovery.js +4 -0
  190. package/dist/server/action-discovery.js.map +1 -1
  191. package/dist/server/agent-chat-plugin.d.ts +5 -0
  192. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  193. package/dist/server/agent-chat-plugin.js +81 -20
  194. package/dist/server/agent-chat-plugin.js.map +1 -1
  195. package/dist/server/agent-discovery.d.ts.map +1 -1
  196. package/dist/server/agent-discovery.js +5 -7
  197. package/dist/server/agent-discovery.js.map +1 -1
  198. package/dist/server/auth.d.ts +16 -21
  199. package/dist/server/auth.d.ts.map +1 -1
  200. package/dist/server/auth.js +45 -315
  201. package/dist/server/auth.js.map +1 -1
  202. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  203. package/dist/server/core-routes-plugin.js +22 -13
  204. package/dist/server/core-routes-plugin.js.map +1 -1
  205. package/dist/server/credential-provider.d.ts.map +1 -1
  206. package/dist/server/credential-provider.js +1 -2
  207. package/dist/server/credential-provider.js.map +1 -1
  208. package/dist/server/google-oauth.d.ts +14 -2
  209. package/dist/server/google-oauth.d.ts.map +1 -1
  210. package/dist/server/google-oauth.js +17 -7
  211. package/dist/server/google-oauth.js.map +1 -1
  212. package/dist/server/index.d.ts +1 -1
  213. package/dist/server/index.d.ts.map +1 -1
  214. package/dist/server/index.js +1 -1
  215. package/dist/server/index.js.map +1 -1
  216. package/dist/server/oauth-helpers.d.ts +2 -4
  217. package/dist/server/oauth-helpers.d.ts.map +1 -1
  218. package/dist/server/oauth-helpers.js +2 -4
  219. package/dist/server/oauth-helpers.js.map +1 -1
  220. package/dist/server/transcribe-voice.d.ts.map +1 -1
  221. package/dist/server/transcribe-voice.js +2 -4
  222. package/dist/server/transcribe-voice.js.map +1 -1
  223. package/dist/triggers/dispatcher.d.ts.map +1 -1
  224. package/dist/triggers/dispatcher.js +0 -3
  225. package/dist/triggers/dispatcher.js.map +1 -1
  226. package/dist/vite/client.d.ts.map +1 -1
  227. package/dist/vite/client.js +6 -0
  228. package/dist/vite/client.js.map +1 -1
  229. package/docs/content/actions.md +1 -0
  230. package/docs/content/authentication.md +3 -20
  231. package/docs/content/creating-templates.md +1 -1
  232. package/docs/content/deployment.md +0 -1
  233. package/docs/content/security.md +0 -1
  234. package/docs/content/template-content.md +1 -1
  235. package/docs/content/template-starter.md +1 -1
  236. package/package.json +1 -1
  237. package/dist/client/dev-mode.d.ts +0 -14
  238. package/dist/client/dev-mode.d.ts.map +0 -1
  239. package/dist/client/dev-mode.js +0 -14
  240. package/dist/client/dev-mode.js.map +0 -1
  241. package/dist/server/local-migration.d.ts +0 -41
  242. package/dist/server/local-migration.d.ts.map +0 -1
  243. package/dist/server/local-migration.js +0 -235
  244. package/dist/server/local-migration.js.map +0 -1
@@ -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 as standalone processes without HTTP context.
5
- * The owner is resolved from the AGENT_USER_EMAIL env var
6
- * (set by the agent runtime for multi-user apps), defaulting to
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;;;;;;;GAOG;AAEH,OAAO,EAOL,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAyBpB,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
+ {"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 as standalone processes without HTTP context.
5
- * The owner is resolved from the AGENT_USER_EMAIL env var
6
- * (set by the agent runtime for multi-user apps), defaulting to
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, hasRequestContext, } from "../server/request-context.js";
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
- if (hasRequestContext()) {
24
- throw new Error("Resource access requires an authenticated request context");
25
- }
26
- return DEV_MODE_USER_EMAIL;
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;;;;;;;GAOG;AAEH,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,sBAAsB,GAEvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AAEtC,sEAAsE;AACtE,yEAAyE;AACzE,yEAAyE;AACzE,0EAA0E;AAC1E,qDAAqD;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,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,IAAI,iBAAiB,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IACD,OAAO,mBAAmB,CAAC;AAC7B,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 as standalone processes without HTTP context.\n * The owner is resolved from the AGENT_USER_EMAIL env var\n * (set by the agent runtime for multi-user apps), defaulting to\n * \"local@localhost\" for backward compatibility in dev mode.\n */\n\nimport {\n SHARED_OWNER,\n resourceGetByPath,\n resourcePut,\n resourceDeleteByPath,\n resourceList,\n resourceListAccessible,\n type ResourceMeta,\n} from \"./store.js\";\nimport {\n getRequestUserEmail,\n hasRequestContext,\n} from \"../server/request-context.js\";\n\n// Dev-mode fallback identity. Scripts run as standalone CLI processes\n// without HTTP context — when no AGENT_USER_EMAIL is set we fall back to\n// the dev-mode user so a developer running `pnpm action` locally without\n// signing in still gets a usable scope. Production multi-user deployments\n// always set AGENT_USER_EMAIL via the agent runtime.\nimport { DEV_MODE_USER_EMAIL } from \"../server/auth.js\";\n\nfunction getOwner(shared?: boolean): string {\n if (shared) return SHARED_OWNER;\n const userEmail = getRequestUserEmail();\n if (userEmail) return userEmail;\n if (hasRequestContext()) {\n throw new Error(\n \"Resource access requires an authenticated request context\",\n );\n }\n return DEV_MODE_USER_EMAIL;\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
+ {"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;AAyBH,wBAA8B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EvE"}
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 || email === DEV_MODE_USER_EMAIL)
16
- return DEV_MODE_USER_EMAIL;
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":"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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\";\nimport { DEV_MODE_USER_EMAIL } from \"../../server/auth.js\";\n\nfunction getOwnerEmail(): string {\n const email = getRequestUserEmail();\n if (!email || email === DEV_MODE_USER_EMAIL) return DEV_MODE_USER_EMAIL;\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"]}
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 maximum number of agent loop iterations before the agent pauses and asks whether to keep going. Pass action="get" to inspect, action="set" with maxIterations to update the active org/user setting, or action="reset" to return to default.',
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 limit. Applies to the active organization when one is selected; otherwise applies to the current user.",
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":"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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 maximum number of agent loop iterations before the agent pauses and asks whether to keep going. 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 step limit. 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
+ {"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;AAWH,wBAA8B,kBAAkB,CAC9C,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CA6Cf"}
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() ?? DEV_MODE_USER_EMAIL;
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;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,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,mBAAmB,CAAC;IAC3D,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\";\nimport { DEV_MODE_USER_EMAIL } from \"../../server/auth.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() ?? DEV_MODE_USER_EMAIL;\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
+ {"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;AAOH,wBAA8B,oBAAoB,CAChD,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
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
- const owner = scope === "shared"
30
- ? SHARED_OWNER
31
- : (getRequestUserEmail() ?? DEV_MODE_USER_EMAIL);
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;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,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,MAAM,KAAK,GACT,KAAK,KAAK,QAAQ;QAChB,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,CAAC,mBAAmB,EAAE,IAAI,mBAAmB,CAAC,CAAC;IAErD,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\";\nimport { DEV_MODE_USER_EMAIL } from \"../../server/auth.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 const owner =\n scope === \"shared\"\n ? SHARED_OWNER\n : (getRequestUserEmail() ?? DEV_MODE_USER_EMAIL);\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
+ {"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;AAYH,wBAA8B,kBAAkB,CAC9C,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CAmDf"}
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"}
@@ -6,10 +6,9 @@
6
6
  * Usage:
7
7
  * pnpm action resource-list [--prefix <path>] [--scope personal|shared|all] [--format json|text]
8
8
  */
9
- import { parseArgs } from "../utils.js";
9
+ import { parseArgs, fail } from "../utils.js";
10
10
  import { resourceList, resourceListAccessible, ensurePersonalDefaults, 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 resourceListScript(args) {
14
13
  const parsed = parseArgs(args);
15
14
  if (parsed.help === "true") {
@@ -25,7 +24,10 @@ Options:
25
24
  const prefix = parsed.prefix;
26
25
  const scope = parsed.scope ?? "all";
27
26
  const format = parsed.format ?? "text";
28
- const owner = getRequestUserEmail() ?? DEV_MODE_USER_EMAIL;
27
+ const owner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;
28
+ if (!owner) {
29
+ fail("resource-list requires an authenticated user (request context or AGENT_USER_EMAIL env var).");
30
+ }
29
31
  // Seed personal AGENTS.md + LEARNINGS.md on first access
30
32
  if (scope !== "shared") {
31
33
  await ensurePersonalDefaults(owner);
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/scripts/resources/list.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,EACtB,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,kBAAkB,CAC9C,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;;;;;;sDAMsC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;IACvC,MAAM,KAAK,GAAG,mBAAmB,EAAE,IAAI,mBAAmB,CAAC;IAE3D,yDAAyD;IACzD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,SAAS,CAAC;IACd,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,SAAS,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,SAAS,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,MAAM,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IAED,wBAAwB;IACxB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,cAAc,SAAS,CAAC,MAAM,IAAI,CAAC,CAAC;IAEhD,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC;QAC1E,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,UAAU,GAAG,SAAS,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;AACH,CAAC","sourcesContent":["/**\n * Core script: resource-list\n *\n * List resources stored in the SQL resource store.\n *\n * Usage:\n * pnpm action resource-list [--prefix <path>] [--scope personal|shared|all] [--format json|text]\n */\n\nimport { parseArgs } from \"../utils.js\";\nimport {\n resourceList,\n resourceListAccessible,\n ensurePersonalDefaults,\n SHARED_OWNER,\n} from \"../../resources/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\nimport { DEV_MODE_USER_EMAIL } from \"../../server/auth.js\";\n\nexport default async function resourceListScript(\n args: string[],\n): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action resource-list [options]\n\nOptions:\n --prefix <path> Filter by path prefix\n --scope personal|shared|all Scope to list (default: all)\n --format json|text Output format (default: text)\n --help Show this help message`);\n return;\n }\n\n const prefix = parsed.prefix;\n const scope = parsed.scope ?? \"all\";\n const format = parsed.format ?? \"text\";\n const owner = getRequestUserEmail() ?? DEV_MODE_USER_EMAIL;\n\n // Seed personal AGENTS.md + LEARNINGS.md on first access\n if (scope !== \"shared\") {\n await ensurePersonalDefaults(owner);\n }\n\n let resources;\n if (scope === \"personal\") {\n resources = await resourceList(owner, prefix);\n } else if (scope === \"shared\") {\n resources = await resourceList(SHARED_OWNER, prefix);\n } else {\n resources = await resourceListAccessible(owner, prefix);\n }\n\n if (format === \"json\") {\n console.log(JSON.stringify(resources, null, 2));\n return;\n }\n\n // Human-readable output\n if (resources.length === 0) {\n console.log(\"No resources found.\");\n return;\n }\n\n console.log(`Resources: ${resources.length}\\n`);\n\n for (const r of resources) {\n const ownerLabel = r.owner === SHARED_OWNER ? \"[shared]\" : `[${r.owner}]`;\n const sizeLabel = r.size != null ? ` (${r.size} bytes)` : \"\";\n console.log(` ${r.path} ${ownerLabel}${sizeLabel} ${r.mimeType}`);\n }\n}\n"]}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/scripts/resources/list.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,EACtB,YAAY,GACb,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,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC;;;;;;sDAMsC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;IACvC,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;IAED,yDAAyD;IACzD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,SAAS,CAAC;IACd,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,SAAS,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,SAAS,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,MAAM,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IAED,wBAAwB;IACxB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,cAAc,SAAS,CAAC,MAAM,IAAI,CAAC,CAAC;IAEhD,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC;QAC1E,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,UAAU,GAAG,SAAS,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;AACH,CAAC","sourcesContent":["/**\n * Core script: resource-list\n *\n * List resources stored in the SQL resource store.\n *\n * Usage:\n * pnpm action resource-list [--prefix <path>] [--scope personal|shared|all] [--format json|text]\n */\n\nimport { parseArgs, fail } from \"../utils.js\";\nimport {\n resourceList,\n resourceListAccessible,\n ensurePersonalDefaults,\n SHARED_OWNER,\n} from \"../../resources/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\n\nexport default async function resourceListScript(\n args: string[],\n): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action resource-list [options]\n\nOptions:\n --prefix <path> Filter by path prefix\n --scope personal|shared|all Scope to list (default: all)\n --format json|text Output format (default: text)\n --help Show this help message`);\n return;\n }\n\n const prefix = parsed.prefix;\n const scope = parsed.scope ?? \"all\";\n const format = parsed.format ?? \"text\";\n const owner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;\n if (!owner) {\n fail(\n \"resource-list requires an authenticated user (request context or AGENT_USER_EMAIL env var).\",\n );\n }\n\n // Seed personal AGENTS.md + LEARNINGS.md on first access\n if (scope !== \"shared\") {\n await ensurePersonalDefaults(owner);\n }\n\n let resources;\n if (scope === \"personal\") {\n resources = await resourceList(owner, prefix);\n } else if (scope === \"shared\") {\n resources = await resourceList(SHARED_OWNER, prefix);\n } else {\n resources = await resourceListAccessible(owner, prefix);\n }\n\n if (format === \"json\") {\n console.log(JSON.stringify(resources, null, 2));\n return;\n }\n\n // Human-readable output\n if (resources.length === 0) {\n console.log(\"No resources found.\");\n return;\n }\n\n console.log(`Resources: ${resources.length}\\n`);\n\n for (const r of resources) {\n const ownerLabel = r.owner === SHARED_OWNER ? \"[shared]\" : `[${r.owner}]`;\n const sizeLabel = r.size != null ? ` (${r.size} bytes)` : \"\";\n console.log(` ${r.path} ${ownerLabel}${sizeLabel} ${r.mimeType}`);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-learnings.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/migrate-learnings.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,wBAA8B,sBAAsB,CAClD,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CAoBf"}
1
+ {"version":3,"file":"migrate-learnings.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/migrate-learnings.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,wBAA8B,sBAAsB,CAClD,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CAyBf"}
@@ -10,7 +10,7 @@ import fs from "fs";
10
10
  import path from "path";
11
11
  import { resourcePut } from "../../resources/store.js";
12
12
  import { getRequestUserEmail } from "../../server/request-context.js";
13
- import { DEV_MODE_USER_EMAIL } from "../../server/auth.js";
13
+ import { fail } from "../utils.js";
14
14
  export default async function migrateLearningsScript(args) {
15
15
  const filePath = path.resolve(process.cwd(), "learnings.md");
16
16
  if (!fs.existsSync(filePath)) {
@@ -18,7 +18,10 @@ export default async function migrateLearningsScript(args) {
18
18
  return;
19
19
  }
20
20
  const content = fs.readFileSync(filePath, "utf-8");
21
- const owner = getRequestUserEmail() ?? DEV_MODE_USER_EMAIL;
21
+ const owner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;
22
+ if (!owner) {
23
+ fail("migrate-learnings requires an authenticated user (request context or AGENT_USER_EMAIL env var).");
24
+ }
22
25
  const resource = await resourcePut(owner, "learnings.md", content, "text/markdown");
23
26
  console.log(`Migrated learnings.md to resource store (${resource.size} bytes)`);
24
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-learnings.js","sourceRoot":"","sources":["../../../src/scripts/resources/migrate-learnings.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,sBAAsB,CAClD,IAAc;IAEd,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAE7D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,mBAAmB,EAAE,IAAI,mBAAmB,CAAC;IAE3D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,KAAK,EACL,cAAc,EACd,OAAO,EACP,eAAe,CAChB,CAAC;IACF,OAAO,CAAC,GAAG,CACT,4CAA4C,QAAQ,CAAC,IAAI,SAAS,CACnE,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Core script: migrate-learnings\n *\n * Migrate a learnings.md file from the project root into the SQL resource store.\n *\n * Usage:\n * pnpm action migrate-learnings\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { resourcePut } from \"../../resources/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\nimport { DEV_MODE_USER_EMAIL } from \"../../server/auth.js\";\n\nexport default async function migrateLearningsScript(\n args: string[],\n): Promise<void> {\n const filePath = path.resolve(process.cwd(), \"learnings.md\");\n\n if (!fs.existsSync(filePath)) {\n console.log(\"No learnings.md found\");\n return;\n }\n\n const content = fs.readFileSync(filePath, \"utf-8\");\n const owner = getRequestUserEmail() ?? DEV_MODE_USER_EMAIL;\n\n const resource = await resourcePut(\n owner,\n \"learnings.md\",\n content,\n \"text/markdown\",\n );\n console.log(\n `Migrated learnings.md to resource store (${resource.size} bytes)`,\n );\n}\n"]}
1
+ {"version":3,"file":"migrate-learnings.js","sourceRoot":"","sources":["../../../src/scripts/resources/migrate-learnings.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,sBAAsB,CAClD,IAAc;IAEd,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAE7D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,mBAAmB,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACpE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CACF,iGAAiG,CAClG,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,KAAK,EACL,cAAc,EACd,OAAO,EACP,eAAe,CAChB,CAAC;IACF,OAAO,CAAC,GAAG,CACT,4CAA4C,QAAQ,CAAC,IAAI,SAAS,CACnE,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Core script: migrate-learnings\n *\n * Migrate a learnings.md file from the project root into the SQL resource store.\n *\n * Usage:\n * pnpm action migrate-learnings\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { resourcePut } from \"../../resources/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\nimport { fail } from \"../utils.js\";\n\nexport default async function migrateLearningsScript(\n args: string[],\n): Promise<void> {\n const filePath = path.resolve(process.cwd(), \"learnings.md\");\n\n if (!fs.existsSync(filePath)) {\n console.log(\"No learnings.md found\");\n return;\n }\n\n const content = fs.readFileSync(filePath, \"utf-8\");\n const owner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;\n if (!owner) {\n fail(\n \"migrate-learnings requires an authenticated user (request context or AGENT_USER_EMAIL env var).\",\n );\n }\n\n const resource = await resourcePut(\n owner,\n \"learnings.md\",\n content,\n \"text/markdown\",\n );\n console.log(\n `Migrated learnings.md to resource store (${resource.size} bytes)`,\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,wBAA8B,kBAAkB,CAC9C,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CA8Df"}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,wBAA8B,kBAAkB,CAC9C,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CAmEf"}
@@ -9,7 +9,6 @@
9
9
  import { parseArgs, fail } from "../utils.js";
10
10
  import { resourceGetByPath, ensurePersonalDefaults, 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 resourceReadScript(args) {
14
13
  const parsed = parseArgs(args);
15
14
  if (parsed.help === "true") {
@@ -26,7 +25,10 @@ Options:
26
25
  fail("--path is required. Example: --path LEARNINGS.md");
27
26
  }
28
27
  const scope = parsed.scope;
29
- const owner = getRequestUserEmail() ?? DEV_MODE_USER_EMAIL;
28
+ const owner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;
29
+ if (!owner) {
30
+ fail("resource-read requires an authenticated user (request context or AGENT_USER_EMAIL env var).");
31
+ }
30
32
  // Seed personal AGENTS.md + LEARNINGS.md on first access
31
33
  if (scope !== "shared") {
32
34
  await ensurePersonalDefaults(owner);
@@ -1 +1 @@
1
- {"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/scripts/resources/read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,kBAAkB,CAC9C,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,kDAAkD,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,MAAM,KAAK,GAAG,mBAAmB,EAAE,IAAI,mBAAmB,CAAC;IAE3D,yDAAyD;IACzD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACrE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CACT,uBAAuB,YAAY,0DAA0D,CAC9F,CAAC;YACF,OAAO;QACT,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,mDAAmD;IACnD,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC9D,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,4CAA4C;QAC5C,OAAO,CAAC,GAAG,CACT,uBAAuB,YAAY,4DAA4D,CAChG,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IACnE,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CACT,uBAAuB,YAAY,0CAA0C,CAC9E,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Core script: resource-read\n *\n * Read a resource and output its content to stdout.\n *\n * Usage:\n * pnpm action resource-read --path <path> [--scope personal|shared]\n */\n\nimport { parseArgs, fail } from \"../utils.js\";\nimport {\n resourceGetByPath,\n ensurePersonalDefaults,\n SHARED_OWNER,\n} from \"../../resources/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\nimport { DEV_MODE_USER_EMAIL } from \"../../server/auth.js\";\n\nexport default async function resourceReadScript(\n args: string[],\n): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action resource-read --path <path> [options]\n\nOptions:\n --path <path> Resource path (required)\n --scope personal|shared Scope to read from (default: personal, falls back to shared)\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 LEARNINGS.md\");\n }\n\n const scope = parsed.scope;\n const owner = getRequestUserEmail() ?? DEV_MODE_USER_EMAIL;\n\n // Seed personal AGENTS.md + LEARNINGS.md on first access\n if (scope !== \"shared\") {\n await ensurePersonalDefaults(owner);\n }\n\n if (scope === \"shared\") {\n const resource = await resourceGetByPath(SHARED_OWNER, resourcePath);\n if (!resource) {\n console.log(\n `Resource not found: ${resourcePath} (scope: shared). You can create it with resource-write.`,\n );\n return;\n }\n process.stdout.write(resource.content);\n return;\n }\n\n // Default: try personal first, fall back to shared\n const personal = await resourceGetByPath(owner, resourcePath);\n if (personal) {\n process.stdout.write(personal.content);\n return;\n }\n\n if (scope === \"personal\") {\n // Explicit personal scope — don't fall back\n console.log(\n `Resource not found: ${resourcePath} (scope: personal). You can create it with resource-write.`,\n );\n return;\n }\n\n const shared = await resourceGetByPath(SHARED_OWNER, resourcePath);\n if (shared) {\n process.stdout.write(shared.content);\n return;\n }\n\n console.log(\n `Resource not found: ${resourcePath}. You can create it with resource-write.`,\n );\n}\n"]}
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/scripts/resources/read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,YAAY,GACb,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,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,kDAAkD,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,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;IAED,yDAAyD;IACzD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACrE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CACT,uBAAuB,YAAY,0DAA0D,CAC9F,CAAC;YACF,OAAO;QACT,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,mDAAmD;IACnD,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC9D,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,4CAA4C;QAC5C,OAAO,CAAC,GAAG,CACT,uBAAuB,YAAY,4DAA4D,CAChG,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IACnE,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CACT,uBAAuB,YAAY,0CAA0C,CAC9E,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Core script: resource-read\n *\n * Read a resource and output its content to stdout.\n *\n * Usage:\n * pnpm action resource-read --path <path> [--scope personal|shared]\n */\n\nimport { parseArgs, fail } from \"../utils.js\";\nimport {\n resourceGetByPath,\n ensurePersonalDefaults,\n SHARED_OWNER,\n} from \"../../resources/store.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\n\nexport default async function resourceReadScript(\n args: string[],\n): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action resource-read --path <path> [options]\n\nOptions:\n --path <path> Resource path (required)\n --scope personal|shared Scope to read from (default: personal, falls back to shared)\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 LEARNINGS.md\");\n }\n\n const scope = parsed.scope;\n const owner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;\n if (!owner) {\n fail(\n \"resource-read requires an authenticated user (request context or AGENT_USER_EMAIL env var).\",\n );\n }\n\n // Seed personal AGENTS.md + LEARNINGS.md on first access\n if (scope !== \"shared\") {\n await ensurePersonalDefaults(owner);\n }\n\n if (scope === \"shared\") {\n const resource = await resourceGetByPath(SHARED_OWNER, resourcePath);\n if (!resource) {\n console.log(\n `Resource not found: ${resourcePath} (scope: shared). You can create it with resource-write.`,\n );\n return;\n }\n process.stdout.write(resource.content);\n return;\n }\n\n // Default: try personal first, fall back to shared\n const personal = await resourceGetByPath(owner, resourcePath);\n if (personal) {\n process.stdout.write(personal.content);\n return;\n }\n\n if (scope === \"personal\") {\n // Explicit personal scope — don't fall back\n console.log(\n `Resource not found: ${resourcePath} (scope: personal). You can create it with resource-write.`,\n );\n return;\n }\n\n const shared = await resourceGetByPath(SHARED_OWNER, resourcePath);\n if (shared) {\n process.stdout.write(shared.content);\n return;\n }\n\n console.log(\n `Resource not found: ${resourcePath}. You can create it with resource-write.`,\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"save-memory.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/save-memory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,wBAA8B,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA4E5E"}
1
+ {"version":3,"file":"save-memory.d.ts","sourceRoot":"","sources":["../../../src/scripts/resources/save-memory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,wBAA8B,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiF5E"}
@@ -8,7 +8,6 @@
8
8
  import { parseArgs, fail } from "../utils.js";
9
9
  import { resourcePut, resourceGetByPath } from "../../resources/store.js";
10
10
  import { getRequestUserEmail } from "../../server/request-context.js";
11
- import { DEV_MODE_USER_EMAIL } from "../../server/auth.js";
12
11
  const VALID_TYPES = ["user", "feedback", "project", "reference"];
13
12
  const EMPTY_INDEX = `# Memory Index
14
13
  `;
@@ -27,7 +26,10 @@ export default async function saveMemoryScript(args) {
27
26
  const content = parsed.content;
28
27
  if (!content)
29
28
  fail("--content is required");
30
- const owner = getRequestUserEmail() ?? DEV_MODE_USER_EMAIL;
29
+ const owner = getRequestUserEmail() ?? process.env.AGENT_USER_EMAIL;
30
+ if (!owner) {
31
+ fail("save-memory requires an authenticated user (request context or AGENT_USER_EMAIL env var).");
32
+ }
31
33
  const memoryPath = `memory/${name}.md`;
32
34
  const indexPath = "memory/MEMORY.md";
33
35
  const now = new Date().toISOString().slice(0, 10);