@agent-native/core 0.90.3 → 0.90.5

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 (256) hide show
  1. package/bin/agent-native.js +25 -3
  2. package/corpus/README.md +1 -1
  3. package/corpus/core/CHANGELOG.md +17 -0
  4. package/corpus/core/bin/agent-native.js +25 -3
  5. package/corpus/core/package.json +1 -1
  6. package/corpus/core/src/agent/durable-background.ts +18 -18
  7. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +8 -2
  8. package/corpus/core/src/agent/engine/anthropic-engine.ts +11 -1
  9. package/corpus/core/src/agent/engine/index.ts +1 -0
  10. package/corpus/core/src/agent/engine/registry.ts +63 -2
  11. package/corpus/core/src/agent/production-agent.ts +22 -11
  12. package/corpus/core/src/agent/run-manager.ts +17 -6
  13. package/corpus/core/src/agent/run-store.ts +16 -11
  14. package/corpus/core/src/cli/create.ts +35 -0
  15. package/corpus/core/src/cli/design-connect.ts +263 -1
  16. package/corpus/core/src/cli/index.ts +84 -7
  17. package/corpus/core/src/cli/workspacify.ts +34 -0
  18. package/corpus/core/src/client/KeepTabOpenNotice.tsx +20 -15
  19. package/corpus/core/src/client/RunStuckBanner.tsx +14 -13
  20. package/corpus/core/src/client/agent-chat-adapter.ts +28 -17
  21. package/corpus/core/src/client/history/VersionHistoryPanel.tsx +77 -47
  22. package/corpus/core/src/client/history/index.ts +3 -0
  23. package/corpus/core/src/client/history/use-history.ts +28 -0
  24. package/corpus/core/src/client/index.ts +8 -0
  25. package/corpus/core/src/client/review/index.ts +5 -0
  26. package/corpus/core/src/client/review/use-review.ts +40 -2
  27. package/corpus/core/src/client/use-run-stuck-detection.ts +8 -5
  28. package/corpus/core/src/history/actions/create-resource-version.ts +11 -8
  29. package/corpus/core/src/history/index.ts +0 -1
  30. package/corpus/core/src/history/registry.ts +24 -12
  31. package/corpus/core/src/history/store.ts +84 -53
  32. package/corpus/core/src/review/actions/consume-review-feedback.ts +15 -5
  33. package/corpus/core/src/review/actions/delete-review-comment.ts +15 -3
  34. package/corpus/core/src/review/actions/resolve-review-thread.ts +12 -5
  35. package/corpus/core/src/review/index.ts +0 -5
  36. package/corpus/core/src/review/registry.ts +24 -12
  37. package/corpus/core/src/review/store.ts +10 -7
  38. package/corpus/core/src/server/agent-chat-plugin.ts +6 -0
  39. package/corpus/core/src/server/credential-provider.ts +13 -3
  40. package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +11 -11
  41. package/corpus/templates/assets/actions/generate-image.ts +64 -28
  42. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +1 -1
  43. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +91 -74
  44. package/corpus/templates/assets/server/lib/generation.ts +29 -4
  45. package/corpus/templates/assets/server/lib/image-processing.ts +131 -0
  46. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +24 -2
  47. package/corpus/templates/calendar/AGENTS.md +3 -0
  48. package/corpus/templates/calendar/actions/create-event.ts +8 -34
  49. package/corpus/templates/calendar/actions/event-action-helpers.ts +52 -0
  50. package/corpus/templates/calendar/actions/manage-event-draft.ts +7 -34
  51. package/corpus/templates/calendar/actions/update-event.ts +10 -23
  52. package/corpus/templates/calendar/app/components/calendar/AttendeeAutocomplete.tsx +47 -0
  53. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +23 -0
  54. package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +59 -2
  55. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +40 -1
  56. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +34 -1
  57. package/corpus/templates/calendar/app/hooks/use-events.ts +6 -0
  58. package/corpus/templates/calendar/app/i18n/zh-TW.ts +4 -0
  59. package/corpus/templates/calendar/app/i18n-data.ts +40 -0
  60. package/corpus/templates/calendar/changelog/2026-07-07-you-can-mark-event-guests-as-optional-while-inviting-them-or.md +6 -0
  61. package/corpus/templates/calendar/server/handlers/events.ts +1 -0
  62. package/corpus/templates/calendar/server/lib/google-calendar.ts +4 -0
  63. package/corpus/templates/calendar/server/plugins/agent-chat.ts +1 -1
  64. package/corpus/templates/calendar/shared/api.ts +2 -0
  65. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +29 -3
  66. package/corpus/templates/clips/actions/generate-workflow.ts +19 -8
  67. package/corpus/templates/clips/actions/get-clips-ai-prefs.ts +36 -0
  68. package/corpus/templates/clips/actions/lib/clips-ai-prefs.ts +28 -0
  69. package/corpus/templates/clips/actions/regenerate-chapters.ts +21 -7
  70. package/corpus/templates/clips/actions/regenerate-summary.ts +26 -8
  71. package/corpus/templates/clips/actions/regenerate-title.ts +44 -7
  72. package/corpus/templates/clips/actions/update-clips-ai-prefs.ts +50 -0
  73. package/corpus/templates/clips/app/components/meetings/meeting-card.tsx +7 -2
  74. package/corpus/templates/clips/app/hooks/use-auto-title.ts +25 -10
  75. package/corpus/templates/clips/app/i18n/ar-SA.ts +28 -6
  76. package/corpus/templates/clips/app/i18n/de-DE.ts +28 -6
  77. package/corpus/templates/clips/app/i18n/en-US.ts +29 -6
  78. package/corpus/templates/clips/app/i18n/es-ES.ts +29 -6
  79. package/corpus/templates/clips/app/i18n/fr-FR.ts +30 -6
  80. package/corpus/templates/clips/app/i18n/hi-IN.ts +26 -6
  81. package/corpus/templates/clips/app/i18n/ja-JP.ts +27 -6
  82. package/corpus/templates/clips/app/i18n/ko-KR.ts +28 -6
  83. package/corpus/templates/clips/app/i18n/pt-BR.ts +28 -6
  84. package/corpus/templates/clips/app/i18n/zh-CN.ts +26 -6
  85. package/corpus/templates/clips/app/i18n/zh-TW.ts +25 -6
  86. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +73 -0
  87. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +1 -0
  88. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +70 -2
  89. package/corpus/templates/clips/changelog/2026-07-07-ai-tools-can-include-the-full-video-not-just-the-transcript-.md +6 -0
  90. package/corpus/templates/clips/changelog/2026-07-07-clips-desktop-now-surfaces-meetings-and-dictate-directly-in-.md +6 -0
  91. package/corpus/templates/clips/changelog/2026-07-07-meeting-notes-now-explain-exactly-how-to-start-granola-style.md +6 -0
  92. package/corpus/templates/clips/changelog/2026-07-07-meeting-start-alerts-now-include-separate-start-notes-and-jo.md +6 -0
  93. package/corpus/templates/clips/changelog/2026-07-07-recordings-start-more-predictably-and-newly-saved-clips-refr.md +6 -0
  94. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  95. package/corpus/templates/clips/desktop/src/app.tsx +435 -105
  96. package/corpus/templates/clips/desktop/src/lib/recorder.ts +27 -21
  97. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +23 -22
  98. package/corpus/templates/clips/desktop/src/styles.css +167 -2
  99. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
  100. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +3 -7
  101. package/corpus/templates/clips/desktop/src-tauri/src/tray_meetings.rs +5 -4
  102. package/corpus/templates/clips/server/routes/_agent-native/clips/user-prefs.put.ts +16 -8
  103. package/corpus/templates/clips/shared/clips-ai-prefs.ts +81 -0
  104. package/corpus/templates/content/AGENTS.md +1 -0
  105. package/corpus/templates/content/actions/_database-source-utils.ts +73 -8
  106. package/corpus/templates/content/actions/_database-utils.ts +2 -1
  107. package/corpus/templates/content/actions/prepare-builder-source-review.ts +20 -1
  108. package/corpus/templates/content/actions/stage-builder-source-bulk-update.ts +663 -0
  109. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +33 -7
  110. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +53 -4
  111. package/corpus/templates/content/app/components/editor/database/settings.tsx +24 -0
  112. package/corpus/templates/content/app/hooks/use-content-database.ts +70 -1
  113. package/corpus/templates/content/app/hooks/use-document-properties.ts +63 -5
  114. package/corpus/templates/content/app/i18n/zh-TW.ts +3 -0
  115. package/corpus/templates/content/app/i18n-data.ts +31 -0
  116. package/corpus/templates/content/changelog/2026-07-01-builder-source-rows-can-be-staged-in-bulk-with-a-reviewable.md +6 -0
  117. package/corpus/templates/content/changelog/2026-07-07-builder-backed-database-fields-now-edit-like-normal-content-fields.md +6 -0
  118. package/corpus/templates/content/parity/matrix.md +24 -24
  119. package/corpus/templates/content/parity/matrix.ts +2 -0
  120. package/corpus/templates/content/shared/api.ts +59 -4
  121. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +16 -1
  122. package/corpus/templates/design/actions/add-localhost-screens.ts +1 -0
  123. package/corpus/templates/design/actions/connect-localhost.ts +26 -3
  124. package/corpus/templates/design/actions/open-visual-edit.ts +4 -37
  125. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +362 -12
  126. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +89 -14
  127. package/corpus/templates/design/app/components/design/bridge-security.ts +7 -1
  128. package/corpus/templates/design/app/components/design/multi-screen/types.ts +1 -1
  129. package/corpus/templates/design/app/i18n/zh-TW.ts +3 -0
  130. package/corpus/templates/design/app/i18n-data.ts +41 -0
  131. package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-keeps-bridge-access-when-opening-previousl.md +6 -0
  132. package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-now-keeps-the-live-app-connection-authenti.md +6 -0
  133. package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-uses-live-app-iframes-for-click-to-edit-pr.md +6 -0
  134. package/dist/agent/durable-background.d.ts +12 -12
  135. package/dist/agent/durable-background.js +18 -18
  136. package/dist/agent/durable-background.js.map +1 -1
  137. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  138. package/dist/agent/engine/ai-sdk-engine.js +8 -2
  139. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  140. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  141. package/dist/agent/engine/anthropic-engine.js +11 -1
  142. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  143. package/dist/agent/engine/index.d.ts +1 -1
  144. package/dist/agent/engine/index.d.ts.map +1 -1
  145. package/dist/agent/engine/index.js +1 -1
  146. package/dist/agent/engine/index.js.map +1 -1
  147. package/dist/agent/engine/registry.d.ts +14 -0
  148. package/dist/agent/engine/registry.d.ts.map +1 -1
  149. package/dist/agent/engine/registry.js +56 -2
  150. package/dist/agent/engine/registry.js.map +1 -1
  151. package/dist/agent/production-agent.d.ts +2 -2
  152. package/dist/agent/production-agent.d.ts.map +1 -1
  153. package/dist/agent/production-agent.js +18 -11
  154. package/dist/agent/production-agent.js.map +1 -1
  155. package/dist/agent/run-manager.d.ts +7 -1
  156. package/dist/agent/run-manager.d.ts.map +1 -1
  157. package/dist/agent/run-manager.js +6 -1
  158. package/dist/agent/run-manager.js.map +1 -1
  159. package/dist/agent/run-store.d.ts +1 -1
  160. package/dist/agent/run-store.d.ts.map +1 -1
  161. package/dist/agent/run-store.js +15 -10
  162. package/dist/agent/run-store.js.map +1 -1
  163. package/dist/cli/create.d.ts.map +1 -1
  164. package/dist/cli/create.js +31 -0
  165. package/dist/cli/create.js.map +1 -1
  166. package/dist/cli/design-connect.d.ts.map +1 -1
  167. package/dist/cli/design-connect.js +197 -1
  168. package/dist/cli/design-connect.js.map +1 -1
  169. package/dist/cli/index.js +76 -9
  170. package/dist/cli/index.js.map +1 -1
  171. package/dist/cli/workspacify.d.ts.map +1 -1
  172. package/dist/cli/workspacify.js +30 -0
  173. package/dist/cli/workspacify.js.map +1 -1
  174. package/dist/client/KeepTabOpenNotice.d.ts +9 -10
  175. package/dist/client/KeepTabOpenNotice.d.ts.map +1 -1
  176. package/dist/client/KeepTabOpenNotice.js +8 -4
  177. package/dist/client/KeepTabOpenNotice.js.map +1 -1
  178. package/dist/client/RunStuckBanner.d.ts.map +1 -1
  179. package/dist/client/RunStuckBanner.js +14 -13
  180. package/dist/client/RunStuckBanner.js.map +1 -1
  181. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  182. package/dist/client/agent-chat-adapter.js +25 -17
  183. package/dist/client/agent-chat-adapter.js.map +1 -1
  184. package/dist/client/history/VersionHistoryPanel.d.ts +1 -1
  185. package/dist/client/history/VersionHistoryPanel.d.ts.map +1 -1
  186. package/dist/client/history/VersionHistoryPanel.js +12 -5
  187. package/dist/client/history/VersionHistoryPanel.js.map +1 -1
  188. package/dist/client/history/index.d.ts +1 -1
  189. package/dist/client/history/index.d.ts.map +1 -1
  190. package/dist/client/history/index.js +1 -1
  191. package/dist/client/history/index.js.map +1 -1
  192. package/dist/client/history/use-history.d.ts +12 -0
  193. package/dist/client/history/use-history.d.ts.map +1 -1
  194. package/dist/client/history/use-history.js +6 -0
  195. package/dist/client/history/use-history.js.map +1 -1
  196. package/dist/client/index.d.ts +2 -2
  197. package/dist/client/index.d.ts.map +1 -1
  198. package/dist/client/index.js +2 -2
  199. package/dist/client/index.js.map +1 -1
  200. package/dist/client/review/index.d.ts +1 -1
  201. package/dist/client/review/index.d.ts.map +1 -1
  202. package/dist/client/review/index.js +1 -1
  203. package/dist/client/review/index.js.map +1 -1
  204. package/dist/client/review/use-review.d.ts +23 -0
  205. package/dist/client/review/use-review.d.ts.map +1 -1
  206. package/dist/client/review/use-review.js +8 -0
  207. package/dist/client/review/use-review.js.map +1 -1
  208. package/dist/client/use-run-stuck-detection.d.ts +1 -1
  209. package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
  210. package/dist/client/use-run-stuck-detection.js +6 -4
  211. package/dist/client/use-run-stuck-detection.js.map +1 -1
  212. package/dist/collab/struct-routes.d.ts +1 -1
  213. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  214. package/dist/history/actions/create-resource-version.js +7 -4
  215. package/dist/history/actions/create-resource-version.js.map +1 -1
  216. package/dist/history/index.d.ts +1 -1
  217. package/dist/history/index.d.ts.map +1 -1
  218. package/dist/history/index.js +1 -1
  219. package/dist/history/index.js.map +1 -1
  220. package/dist/history/registry.d.ts.map +1 -1
  221. package/dist/history/registry.js +14 -12
  222. package/dist/history/registry.js.map +1 -1
  223. package/dist/history/store.d.ts.map +1 -1
  224. package/dist/history/store.js +74 -49
  225. package/dist/history/store.js.map +1 -1
  226. package/dist/notifications/routes.d.ts +1 -1
  227. package/dist/resources/handlers.d.ts +3 -3
  228. package/dist/review/actions/consume-review-feedback.d.ts +1 -0
  229. package/dist/review/actions/consume-review-feedback.js +8 -2
  230. package/dist/review/actions/consume-review-feedback.js.map +1 -1
  231. package/dist/review/actions/delete-review-comment.d.ts +2 -1
  232. package/dist/review/actions/delete-review-comment.js +11 -3
  233. package/dist/review/actions/delete-review-comment.js.map +1 -1
  234. package/dist/review/actions/resolve-review-thread.d.ts +2 -1
  235. package/dist/review/actions/resolve-review-thread.js +5 -2
  236. package/dist/review/actions/resolve-review-thread.js.map +1 -1
  237. package/dist/review/index.d.ts +1 -1
  238. package/dist/review/index.d.ts.map +1 -1
  239. package/dist/review/index.js +1 -1
  240. package/dist/review/index.js.map +1 -1
  241. package/dist/review/registry.d.ts.map +1 -1
  242. package/dist/review/registry.js +14 -12
  243. package/dist/review/registry.js.map +1 -1
  244. package/dist/review/store.d.ts +3 -3
  245. package/dist/review/store.d.ts.map +1 -1
  246. package/dist/review/store.js +7 -4
  247. package/dist/review/store.js.map +1 -1
  248. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  249. package/dist/server/agent-chat-plugin.js +5 -0
  250. package/dist/server/agent-chat-plugin.js.map +1 -1
  251. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  252. package/dist/server/credential-provider.d.ts +2 -0
  253. package/dist/server/credential-provider.d.ts.map +1 -1
  254. package/dist/server/credential-provider.js +13 -3
  255. package/dist/server/credential-provider.js.map +1 -1
  256. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/history/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { getDbExec, intType, isPostgres } from \"../db/client.js\";\nimport { ensureIndexExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport type { Visibility } from \"../sharing/schema.js\";\nimport type {\n HistoryActorKind,\n ResourceHistoryScope,\n ResourceVersion,\n} from \"./types.js\";\n\nlet historyTableInitPromise: Promise<void> | undefined;\n\nexport interface InsertResourceVersionInput {\n resourceType: string;\n resourceId: string;\n createdBy?: string | null;\n actorKind?: HistoryActorKind;\n ownerEmail?: string | null;\n orgId?: string | null;\n visibility?: Visibility | null;\n title?: string | null;\n summary?: string | null;\n snapshot: unknown;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface QueryResourceVersionsInput {\n resourceType: string;\n resourceId: string;\n scope: ResourceHistoryScope;\n bypassScope?: boolean;\n limit?: number;\n offset?: number;\n}\n\nexport async function ensureResourceVersionsTable(): Promise<void> {\n if (!historyTableInitPromise) {\n historyTableInitPromise = (async () => {\n const client = getDbExec();\n const createSql = `CREATE TABLE IF NOT EXISTS agent_resource_versions (\n id TEXT PRIMARY KEY,\n resource_type TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n version_number ${intType()} NOT NULL,\n created_at TEXT NOT NULL,\n created_by TEXT,\n actor_kind TEXT NOT NULL DEFAULT 'human',\n owner_email TEXT,\n org_id TEXT,\n visibility TEXT NOT NULL DEFAULT 'private',\n title TEXT,\n summary TEXT,\n snapshot_json TEXT NOT NULL,\n metadata_json TEXT\n )`;\n const indexes = [\n `CREATE INDEX IF NOT EXISTS idx_agent_resource_versions_resource\n ON agent_resource_versions (resource_type, resource_id, version_number)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_resource_versions_owner\n ON agent_resource_versions (owner_email, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_resource_versions_org\n ON agent_resource_versions (org_id, created_at)`,\n ];\n\n if (isPostgres()) {\n await ensureTableExists(\"agent_resource_versions\", createSql);\n await ensureIndexExists(\n \"idx_agent_resource_versions_resource\",\n indexes[0],\n );\n await ensureIndexExists(\n \"idx_agent_resource_versions_owner\",\n indexes[1],\n );\n await ensureIndexExists(\"idx_agent_resource_versions_org\", indexes[2]);\n } else {\n await client.execute(createSql);\n for (const indexSql of indexes) {\n await client.execute(indexSql);\n }\n }\n })();\n }\n\n await historyTableInitPromise;\n}\n\nexport async function insertResourceVersion(\n input: InsertResourceVersionInput,\n): Promise<ResourceVersion> {\n await ensureResourceVersionsTable();\n const client = getDbExec();\n const maxRows = await client.execute({\n sql: `SELECT MAX(version_number) as max_version\n FROM agent_resource_versions\n WHERE resource_type = ? AND resource_id = ?`,\n args: [input.resourceType, input.resourceId],\n });\n const versionNumber =\n Number(\n (maxRows.rows?.[0] as Record<string, unknown> | undefined)?.max_version ??\n 0,\n ) + 1;\n const id = createVersionId();\n const createdAt = new Date().toISOString();\n const version: ResourceVersion = {\n id,\n resourceType: input.resourceType,\n resourceId: input.resourceId,\n versionNumber,\n createdAt,\n createdBy: input.createdBy ?? null,\n actorKind: input.actorKind ?? \"human\",\n ownerEmail: input.ownerEmail ?? input.createdBy ?? null,\n orgId: input.orgId ?? null,\n visibility:\n input.visibility === \"org\" || input.visibility === \"public\"\n ? input.visibility\n : \"private\",\n title: input.title ?? null,\n summary: input.summary ?? null,\n snapshot: input.snapshot,\n metadata: input.metadata ?? null,\n };\n\n await client.execute({\n sql: `INSERT INTO agent_resource_versions (\n id,\n resource_type,\n resource_id,\n version_number,\n created_at,\n created_by,\n actor_kind,\n owner_email,\n org_id,\n visibility,\n title,\n summary,\n snapshot_json,\n metadata_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n version.id,\n version.resourceType,\n version.resourceId,\n version.versionNumber,\n version.createdAt,\n version.createdBy,\n version.actorKind,\n version.ownerEmail,\n version.orgId,\n version.visibility,\n version.title,\n version.summary,\n JSON.stringify(version.snapshot),\n stringifyOptionalJson(version.metadata),\n ],\n });\n\n return version;\n}\n\nexport async function queryResourceVersions(\n input: QueryResourceVersionsInput,\n): Promise<ResourceVersion[]> {\n await ensureResourceVersionsTable();\n const client = getDbExec();\n const { clause, params } = input.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedResourceClause(input.scope);\n const limit = clampLimit(input.limit);\n const offset = Math.max(0, Math.floor(input.offset ?? 0));\n const result = await client.execute({\n sql: `SELECT ${listColumns()}\n FROM agent_resource_versions\n WHERE resource_type = ? AND resource_id = ? AND ${clause}\n ORDER BY version_number DESC\n LIMIT ? OFFSET ?`,\n args: [input.resourceType, input.resourceId, ...params, limit, offset],\n });\n return (result.rows ?? []).map((row) => mapVersionRow(row, false));\n}\n\nexport async function getResourceVersionById(\n id: string,\n scope: ResourceHistoryScope,\n options: { bypassScope?: boolean } = {},\n): Promise<ResourceVersion | null> {\n await ensureResourceVersionsTable();\n const client = getDbExec();\n const { clause, params } = options.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedResourceClause(scope);\n const result = await client.execute({\n sql: `SELECT ${allColumns()}\n FROM agent_resource_versions\n WHERE id = ? AND ${clause}\n LIMIT 1`,\n args: [id, ...params],\n });\n const row = result.rows?.[0];\n return row ? mapVersionRow(row, true) : null;\n}\n\nexport async function getResourceVersionByNumber(\n resourceType: string,\n resourceId: string,\n versionNumber: number,\n scope: ResourceHistoryScope,\n options: { bypassScope?: boolean } = {},\n): Promise<ResourceVersion | null> {\n await ensureResourceVersionsTable();\n const client = getDbExec();\n const { clause, params } = options.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedResourceClause(scope);\n const result = await client.execute({\n sql: `SELECT ${allColumns()}\n FROM agent_resource_versions\n WHERE resource_type = ?\n AND resource_id = ?\n AND version_number = ?\n AND ${clause}\n LIMIT 1`,\n args: [resourceType, resourceId, versionNumber, ...params],\n });\n const row = result.rows?.[0];\n return row ? mapVersionRow(row, true) : null;\n}\n\nexport function __resetHistoryInitForTests(): void {\n historyTableInitPromise = undefined;\n}\n\nfunction listColumns(): string {\n return [\n \"id\",\n \"resource_type\",\n \"resource_id\",\n \"version_number\",\n \"created_at\",\n \"created_by\",\n \"actor_kind\",\n \"owner_email\",\n \"org_id\",\n \"visibility\",\n \"title\",\n \"summary\",\n \"metadata_json\",\n ].join(\", \");\n}\n\nfunction allColumns(): string {\n return `${listColumns()}, snapshot_json`;\n}\n\nfunction scopedResourceClause(scope: ResourceHistoryScope): {\n clause: string;\n params: unknown[];\n} {\n const parts: string[] = [];\n const params: unknown[] = [];\n\n if (scope.userEmail) {\n parts.push(\"owner_email = ?\");\n params.push(scope.userEmail);\n }\n if (scope.orgId) {\n parts.push(\"(visibility = 'org' AND org_id = ?)\");\n params.push(scope.orgId);\n }\n parts.push(\"visibility = 'public'\");\n\n if (parts.length === 0) {\n return { clause: \"visibility = 'public'\", params: [] };\n }\n\n return { clause: `(${parts.join(\" OR \")})`, params };\n}\n\nfunction mapVersionRow(\n row: Record<string, unknown>,\n includeSnapshot: boolean,\n): ResourceVersion {\n const version: ResourceVersion = {\n id: String(row.id),\n resourceType: String(row.resource_type),\n resourceId: String(row.resource_id),\n versionNumber: Number(row.version_number),\n createdAt: String(row.created_at),\n createdBy: nullableString(row.created_by),\n actorKind: normalizeActorKind(row.actor_kind),\n ownerEmail: nullableString(row.owner_email),\n orgId: nullableString(row.org_id),\n visibility: normalizeVisibility(row.visibility),\n title: nullableString(row.title),\n summary: nullableString(row.summary),\n metadata: parseOptionalJson(row.metadata_json),\n };\n if (includeSnapshot) {\n version.snapshot = parseRequiredJson(row.snapshot_json);\n }\n return version;\n}\n\nfunction createVersionId(): string {\n return `ver_${globalThis.crypto.randomUUID()}`;\n}\n\nfunction clampLimit(value: number | undefined): number {\n if (!Number.isFinite(value)) {\n return 50;\n }\n return Math.min(200, Math.max(1, Math.floor(value ?? 50)));\n}\n\nfunction nullableString(value: unknown): string | null {\n return value === null || value === undefined ? null : String(value);\n}\n\nfunction normalizeVisibility(value: unknown): Visibility {\n return value === \"org\" || value === \"public\" ? value : \"private\";\n}\n\nfunction normalizeActorKind(value: unknown): HistoryActorKind {\n return value === \"agent\" || value === \"system\" ? value : \"human\";\n}\n\nfunction stringifyOptionalJson(value: unknown): string | null {\n return value === null || value === undefined ? null : JSON.stringify(value);\n}\n\nfunction parseOptionalJson(value: unknown): Record<string, unknown> | null {\n if (value === null || value === undefined || value === \"\") {\n return null;\n }\n const parsed = parseRequiredJson(value);\n return typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n}\n\nfunction parseRequiredJson(value: unknown): unknown {\n if (typeof value !== \"string\") {\n return value;\n }\n return JSON.parse(value);\n}\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/history/store.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getDbExec,\n intType,\n isPostgres,\n isUniqueViolation,\n} from \"../db/client.js\";\nimport { ensureIndexExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport type { Visibility } from \"../sharing/schema.js\";\nimport type {\n HistoryActorKind,\n ResourceHistoryScope,\n ResourceVersion,\n} from \"./types.js\";\n\nlet historyTableInitPromise: Promise<void> | undefined;\n\nconst VERSION_INSERT_MAX_ATTEMPTS = 8;\n\nexport interface InsertResourceVersionInput {\n resourceType: string;\n resourceId: string;\n createdBy?: string | null;\n actorKind?: HistoryActorKind;\n ownerEmail?: string | null;\n orgId?: string | null;\n visibility?: Visibility | null;\n title?: string | null;\n summary?: string | null;\n snapshot: unknown;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface QueryResourceVersionsInput {\n resourceType: string;\n resourceId: string;\n scope: ResourceHistoryScope;\n bypassScope?: boolean;\n limit?: number;\n offset?: number;\n}\n\nexport async function ensureResourceVersionsTable(): Promise<void> {\n if (!historyTableInitPromise) {\n historyTableInitPromise = (async () => {\n const client = getDbExec();\n const createSql = `CREATE TABLE IF NOT EXISTS agent_resource_versions (\n id TEXT PRIMARY KEY,\n resource_type TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n version_number ${intType()} NOT NULL,\n created_at TEXT NOT NULL,\n created_by TEXT,\n actor_kind TEXT NOT NULL DEFAULT 'human',\n owner_email TEXT,\n org_id TEXT,\n visibility TEXT NOT NULL DEFAULT 'private',\n title TEXT,\n summary TEXT,\n snapshot_json TEXT NOT NULL,\n metadata_json TEXT\n )`;\n const indexes = [\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_resource_versions_resource_number\n ON agent_resource_versions (resource_type, resource_id, version_number)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_resource_versions_owner\n ON agent_resource_versions (owner_email, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_resource_versions_org\n ON agent_resource_versions (org_id, created_at)`,\n ];\n\n if (isPostgres()) {\n await ensureTableExists(\"agent_resource_versions\", createSql);\n await ensureIndexExists(\n \"idx_agent_resource_versions_resource_number\",\n indexes[0],\n );\n await ensureIndexExists(\n \"idx_agent_resource_versions_owner\",\n indexes[1],\n );\n await ensureIndexExists(\"idx_agent_resource_versions_org\", indexes[2]);\n } else {\n await client.execute(createSql);\n for (const indexSql of indexes) {\n await client.execute(indexSql);\n }\n }\n })();\n }\n\n await historyTableInitPromise;\n}\n\nexport async function insertResourceVersion(\n input: InsertResourceVersionInput,\n): Promise<ResourceVersion> {\n await ensureResourceVersionsTable();\n const client = getDbExec();\n const visibility =\n input.visibility === \"org\" || input.visibility === \"public\"\n ? input.visibility\n : \"private\";\n const actorKind = input.actorKind ?? \"human\";\n const createdBy = input.createdBy ?? null;\n const ownerEmail = input.ownerEmail ?? input.createdBy ?? null;\n const orgId = input.orgId ?? null;\n const title = input.title ?? null;\n const summary = input.summary ?? null;\n const metadata = input.metadata ?? null;\n const snapshotJson = JSON.stringify(input.snapshot);\n const metadataJson = stringifyOptionalJson(metadata);\n\n let lastError: unknown;\n for (let attempt = 0; attempt < VERSION_INSERT_MAX_ATTEMPTS; attempt++) {\n const maxRows = await client.execute({\n sql: `SELECT MAX(version_number) as max_version\n FROM agent_resource_versions\n WHERE resource_type = ? AND resource_id = ?`,\n args: [input.resourceType, input.resourceId],\n });\n const versionNumber =\n Number(\n (maxRows.rows?.[0] as Record<string, unknown> | undefined)\n ?.max_version ?? 0,\n ) + 1;\n const id = createVersionId();\n const createdAt = new Date().toISOString();\n const version: ResourceVersion = {\n id,\n resourceType: input.resourceType,\n resourceId: input.resourceId,\n versionNumber,\n createdAt,\n createdBy,\n actorKind,\n ownerEmail,\n orgId,\n visibility,\n title,\n summary,\n snapshot: input.snapshot,\n metadata,\n };\n\n try {\n await client.execute({\n sql: `INSERT INTO agent_resource_versions (\n id,\n resource_type,\n resource_id,\n version_number,\n created_at,\n created_by,\n actor_kind,\n owner_email,\n org_id,\n visibility,\n title,\n summary,\n snapshot_json,\n metadata_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n version.id,\n version.resourceType,\n version.resourceId,\n version.versionNumber,\n version.createdAt,\n version.createdBy,\n version.actorKind,\n version.ownerEmail,\n version.orgId,\n version.visibility,\n version.title,\n version.summary,\n snapshotJson,\n metadataJson,\n ],\n });\n return version;\n } catch (error) {\n lastError = error;\n if (!isUniqueViolation(error)) {\n throw error;\n }\n }\n }\n\n throw lastError instanceof Error\n ? lastError\n : new Error(\"Failed to allocate a unique resource version number\");\n}\n\nexport async function queryResourceVersions(\n input: QueryResourceVersionsInput,\n): Promise<ResourceVersion[]> {\n await ensureResourceVersionsTable();\n const client = getDbExec();\n const { clause, params } = input.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedResourceClause(input.scope);\n const limit = clampLimit(input.limit);\n const offset = Math.max(0, Math.floor(input.offset ?? 0));\n const result = await client.execute({\n sql: `SELECT ${listColumns()}\n FROM agent_resource_versions\n WHERE resource_type = ? AND resource_id = ? AND ${clause}\n ORDER BY version_number DESC\n LIMIT ? OFFSET ?`,\n args: [input.resourceType, input.resourceId, ...params, limit, offset],\n });\n return (result.rows ?? []).map((row) => mapVersionRow(row, false));\n}\n\nexport async function getResourceVersionById(\n id: string,\n scope: ResourceHistoryScope,\n options: { bypassScope?: boolean } = {},\n): Promise<ResourceVersion | null> {\n await ensureResourceVersionsTable();\n const client = getDbExec();\n const { clause, params } = options.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedResourceClause(scope);\n const result = await client.execute({\n sql: `SELECT ${allColumns()}\n FROM agent_resource_versions\n WHERE id = ? AND ${clause}\n LIMIT 1`,\n args: [id, ...params],\n });\n const row = result.rows?.[0];\n return row ? mapVersionRow(row, true) : null;\n}\n\nexport async function getResourceVersionByNumber(\n resourceType: string,\n resourceId: string,\n versionNumber: number,\n scope: ResourceHistoryScope,\n options: { bypassScope?: boolean } = {},\n): Promise<ResourceVersion | null> {\n await ensureResourceVersionsTable();\n const client = getDbExec();\n const { clause, params } = options.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedResourceClause(scope);\n const result = await client.execute({\n sql: `SELECT ${allColumns()}\n FROM agent_resource_versions\n WHERE resource_type = ?\n AND resource_id = ?\n AND version_number = ?\n AND ${clause}\n LIMIT 1`,\n args: [resourceType, resourceId, versionNumber, ...params],\n });\n const row = result.rows?.[0];\n return row ? mapVersionRow(row, true) : null;\n}\n\nexport function __resetHistoryInitForTests(): void {\n historyTableInitPromise = undefined;\n}\n\nfunction listColumns(): string {\n return [\n \"id\",\n \"resource_type\",\n \"resource_id\",\n \"version_number\",\n \"created_at\",\n \"created_by\",\n \"actor_kind\",\n \"owner_email\",\n \"org_id\",\n \"visibility\",\n \"title\",\n \"summary\",\n \"metadata_json\",\n ].join(\", \");\n}\n\nfunction allColumns(): string {\n return `${listColumns()}, snapshot_json`;\n}\n\nfunction scopedResourceClause(scope: ResourceHistoryScope): {\n clause: string;\n params: unknown[];\n} {\n const parts: string[] = [];\n const params: unknown[] = [];\n\n if (scope.userEmail) {\n parts.push(\"owner_email = ?\");\n params.push(scope.userEmail);\n }\n if (scope.orgId) {\n parts.push(\"(visibility = 'org' AND org_id = ?)\");\n params.push(scope.orgId);\n }\n parts.push(\"visibility = 'public'\");\n\n if (parts.length === 0) {\n return { clause: \"visibility = 'public'\", params: [] };\n }\n\n return { clause: `(${parts.join(\" OR \")})`, params };\n}\n\nfunction mapVersionRow(\n row: Record<string, unknown>,\n includeSnapshot: boolean,\n): ResourceVersion {\n const version: ResourceVersion = {\n id: String(row.id),\n resourceType: String(row.resource_type),\n resourceId: String(row.resource_id),\n versionNumber: Number(row.version_number),\n createdAt: String(row.created_at),\n createdBy: nullableString(row.created_by),\n actorKind: normalizeActorKind(row.actor_kind),\n ownerEmail: nullableString(row.owner_email),\n orgId: nullableString(row.org_id),\n visibility: normalizeVisibility(row.visibility),\n title: nullableString(row.title),\n summary: nullableString(row.summary),\n metadata: parseOptionalJson(row.metadata_json),\n };\n if (includeSnapshot) {\n version.snapshot = parseRequiredJson(row.snapshot_json);\n }\n return version;\n}\n\nfunction createVersionId(): string {\n return `ver_${globalThis.crypto.randomUUID()}`;\n}\n\nfunction clampLimit(value: number | undefined): number {\n if (!Number.isFinite(value)) {\n return 50;\n }\n return Math.min(200, Math.max(1, Math.floor(value ?? 50)));\n}\n\nfunction nullableString(value: unknown): string | null {\n return value === null || value === undefined ? null : String(value);\n}\n\nfunction normalizeVisibility(value: unknown): Visibility {\n return value === \"org\" || value === \"public\" ? value : \"private\";\n}\n\nfunction normalizeActorKind(value: unknown): HistoryActorKind {\n return value === \"agent\" || value === \"system\" ? value : \"human\";\n}\n\nfunction stringifyOptionalJson(value: unknown): string | null {\n return value === null || value === undefined ? null : JSON.stringify(value);\n}\n\nfunction parseOptionalJson(value: unknown): Record<string, unknown> | null {\n if (value === null || value === undefined || value === \"\") {\n return null;\n }\n const parsed = parseRequiredJson(value);\n return typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n}\n\nfunction parseRequiredJson(value: unknown): unknown {\n if (typeof value !== \"string\") {\n return value;\n }\n return JSON.parse(value);\n}\n"]}
@@ -28,7 +28,7 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
28
28
  } | {
29
29
  count?: undefined;
30
30
  updated?: undefined;
31
- ok: boolean;
32
31
  error?: undefined;
32
+ ok: boolean;
33
33
  }>>;
34
34
  //# sourceMappingURL=routes.d.ts.map
@@ -49,11 +49,11 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
49
49
  }>;
50
50
  /** DELETE /_agent-native/resources/:id — delete a resource */
51
51
  export declare function handleDeleteResource(event: any): Promise<{
52
- error: string;
53
52
  ok?: undefined;
53
+ error: string;
54
54
  } | {
55
- ok: boolean;
56
55
  error?: undefined;
56
+ ok: boolean;
57
57
  }>;
58
58
  /** POST /_agent-native/resources/upload — upload a file as a resource */
59
59
  export declare function handleUploadResource(event: any): Promise<import("./store.js").Resource | {
@@ -73,9 +73,9 @@ export declare function handleUploadResource(event: any): Promise<import("./stor
73
73
  runId: string | null;
74
74
  expiresAt: number | null;
75
75
  metadata: string | null;
76
+ error?: undefined;
76
77
  url: string;
77
78
  provider: string;
78
- error?: undefined;
79
79
  }>;
80
80
  export {};
81
81
  //# sourceMappingURL=handlers.d.ts.map
@@ -4,6 +4,7 @@ declare const _default: import("../../action.js").ActionDefinition<{
4
4
  commentIds: string[];
5
5
  }, {
6
6
  consumedCommentIds: string[];
7
+ updatedCount: number;
7
8
  }>;
8
9
  export default _default;
9
10
  //# sourceMappingURL=consume-review-feedback.d.ts.map
@@ -13,11 +13,17 @@ export default defineAction({
13
13
  run: async (args, ctx) => {
14
14
  const actionCtx = ctx;
15
15
  await assertReviewableResourceAccess(args.resourceType, args.resourceId, actionCtx, "editor");
16
- await consumeReviewFeedback(args.commentIds, undefined, {
16
+ const updatedCount = await consumeReviewFeedback(args.commentIds, undefined, {
17
17
  resourceType: args.resourceType,
18
18
  resourceId: args.resourceId,
19
19
  });
20
- return { consumedCommentIds: args.commentIds };
20
+ if (updatedCount < 1) {
21
+ throw new Error("No matching review comments to consume");
22
+ }
23
+ return {
24
+ consumedCommentIds: args.commentIds,
25
+ updatedCount,
26
+ };
21
27
  },
22
28
  audit: {
23
29
  target: (args) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"consume-review-feedback.js","sourceRoot":"","sources":["../../../src/review/actions/consume-review-feedback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC9C,CAAC,CAAC;AAEH,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,qEAAqE;IACvE,MAAM;IACN,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,GAAwC,CAAC;QAC3D,MAAM,8BAA8B,CAClC,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,UAAU,EACf,SAAS,EACT,QAAQ,CACT,CAAC;QACF,MAAM,qBAAqB,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE;YACtD,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;QACH,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;IACjD,CAAC;IACD,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjB,IAAI,EAAE,IAAI,CAAC,YAAY;YACvB,EAAE,EAAE,IAAI,CAAC,UAAU;SACpB,CAAC;KACH;CACF,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport { assertReviewableResourceAccess } from \"../registry.js\";\nimport { consumeReviewFeedback } from \"../store.js\";\nimport type { ReviewResourceContext } from \"../types.js\";\n\nconst schema = z.object({\n resourceType: z.string().min(1),\n resourceId: z.string().min(1),\n commentIds: z.array(z.string().min(1)).min(1),\n});\n\nexport default defineAction({\n description:\n \"Mark review feedback as consumed by the agent or reviewer workflow.\",\n schema,\n run: async (args, ctx) => {\n const actionCtx = ctx as ReviewResourceContext | undefined;\n await assertReviewableResourceAccess(\n args.resourceType,\n args.resourceId,\n actionCtx,\n \"editor\",\n );\n await consumeReviewFeedback(args.commentIds, undefined, {\n resourceType: args.resourceType,\n resourceId: args.resourceId,\n });\n return { consumedCommentIds: args.commentIds };\n },\n audit: {\n target: (args) => ({\n type: args.resourceType,\n id: args.resourceId,\n }),\n },\n});\n"]}
1
+ {"version":3,"file":"consume-review-feedback.js","sourceRoot":"","sources":["../../../src/review/actions/consume-review-feedback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC9C,CAAC,CAAC;AAEH,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,qEAAqE;IACvE,MAAM;IACN,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,GAAwC,CAAC;QAC3D,MAAM,8BAA8B,CAClC,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,UAAU,EACf,SAAS,EACT,QAAQ,CACT,CAAC;QACF,MAAM,YAAY,GAAG,MAAM,qBAAqB,CAC9C,IAAI,CAAC,UAAU,EACf,SAAS,EACT;YACE,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CACF,CAAC;QACF,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO;YACL,kBAAkB,EAAE,IAAI,CAAC,UAAU;YACnC,YAAY;SACb,CAAC;IACJ,CAAC;IACD,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjB,IAAI,EAAE,IAAI,CAAC,YAAY;YACvB,EAAE,EAAE,IAAI,CAAC,UAAU;SACpB,CAAC;KACH;CACF,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport { assertReviewableResourceAccess } from \"../registry.js\";\nimport { consumeReviewFeedback } from \"../store.js\";\nimport type { ReviewResourceContext } from \"../types.js\";\n\nconst schema = z.object({\n resourceType: z.string().min(1),\n resourceId: z.string().min(1),\n commentIds: z.array(z.string().min(1)).min(1),\n});\n\nexport default defineAction({\n description:\n \"Mark review feedback as consumed by the agent or reviewer workflow.\",\n schema,\n run: async (args, ctx) => {\n const actionCtx = ctx as ReviewResourceContext | undefined;\n await assertReviewableResourceAccess(\n args.resourceType,\n args.resourceId,\n actionCtx,\n \"editor\",\n );\n const updatedCount = await consumeReviewFeedback(\n args.commentIds,\n undefined,\n {\n resourceType: args.resourceType,\n resourceId: args.resourceId,\n },\n );\n if (updatedCount < 1) {\n throw new Error(\"No matching review comments to consume\");\n }\n return {\n consumedCommentIds: args.commentIds,\n updatedCount,\n };\n },\n audit: {\n target: (args) => ({\n type: args.resourceType,\n id: args.resourceId,\n }),\n },\n});\n"]}
@@ -4,7 +4,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
4
4
  commentId: string;
5
5
  }, {
6
6
  commentId: string;
7
- deleted: boolean;
7
+ deleted: true;
8
+ updatedCount: number;
8
9
  }>;
9
10
  export default _default;
10
11
  //# sourceMappingURL=delete-review-comment.d.ts.map
@@ -28,12 +28,16 @@ export default defineAction({
28
28
  throw new Error("Review comment not found");
29
29
  }
30
30
  const isAuthor = Boolean(actionCtx?.userEmail) &&
31
- comment.authorEmail === actionCtx?.userEmail;
31
+ normalizeEmail(comment.authorEmail) ===
32
+ normalizeEmail(actionCtx?.userEmail);
32
33
  if (!isAuthor && (!access || !roleSatisfies(access.role, "editor"))) {
33
34
  throw new ForbiddenError("Not allowed to delete this review comment");
34
35
  }
35
- await deleteReviewComment(comment.id, actionCtx?.userEmail ?? null);
36
- return { commentId: comment.id, deleted: true };
36
+ const updatedCount = await deleteReviewComment(comment.id, actionCtx?.userEmail ?? null);
37
+ if (updatedCount < 1) {
38
+ throw new Error("Review comment not found");
39
+ }
40
+ return { commentId: comment.id, deleted: true, updatedCount };
37
41
  },
38
42
  audit: {
39
43
  target: (args) => ({
@@ -42,4 +46,8 @@ export default defineAction({
42
46
  }),
43
47
  },
44
48
  });
49
+ function normalizeEmail(email) {
50
+ const normalized = email?.trim().toLowerCase();
51
+ return normalized || null;
52
+ }
45
53
  //# sourceMappingURL=delete-review-comment.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete-review-comment.js","sourceRoot":"","sources":["../../../src/review/actions/delete-review-comment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxE,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC7B,CAAC,CAAC;AAEH,eAAe,YAAY,CAAC;IAC1B,WAAW,EAAE,+BAA+B;IAC5C,MAAM;IACN,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,GAAwC,CAAC;QAC3D,MAAM,KAAK,GAAG;YACZ,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI;YACvC,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,IAAI;SAChC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,+BAA+B,CAClD,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,UAAU,EACf,SAAS,CACV,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE;YAChE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC;SAC7B,CAAC,CAAC;QACH,IACE,CAAC,OAAO;YACR,OAAO,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY;YAC1C,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,EACtC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,QAAQ,GACZ,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;YAC7B,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,SAAS,CAAC;QAC/C,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YACpE,MAAM,IAAI,cAAc,CAAC,2CAA2C,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,mBAAmB,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,CAAC,CAAC;QACpE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAClD,CAAC;IACD,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjB,IAAI,EAAE,IAAI,CAAC,YAAY;YACvB,EAAE,EAAE,IAAI,CAAC,UAAU;SACpB,CAAC;KACH;CACF,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport { ForbiddenError } from \"../../sharing/access.js\";\nimport { roleSatisfies } from \"../../sharing/schema.js\";\nimport { resolveReviewableResourceAccess } from \"../registry.js\";\nimport { deleteReviewComment, getReviewCommentById } from \"../store.js\";\nimport type { ReviewResourceContext } from \"../types.js\";\n\nconst schema = z.object({\n resourceType: z.string().min(1),\n resourceId: z.string().min(1),\n commentId: z.string().min(1),\n});\n\nexport default defineAction({\n description: \"Soft-delete a review comment.\",\n schema,\n run: async (args, ctx) => {\n const actionCtx = ctx as ReviewResourceContext | undefined;\n const scope = {\n userEmail: actionCtx?.userEmail ?? null,\n orgId: actionCtx?.orgId ?? null,\n };\n const access = await resolveReviewableResourceAccess(\n args.resourceType,\n args.resourceId,\n actionCtx,\n );\n const comment = await getReviewCommentById(args.commentId, scope, {\n bypassScope: Boolean(access),\n });\n if (\n !comment ||\n comment.resourceType !== args.resourceType ||\n comment.resourceId !== args.resourceId\n ) {\n throw new Error(\"Review comment not found\");\n }\n const isAuthor =\n Boolean(actionCtx?.userEmail) &&\n comment.authorEmail === actionCtx?.userEmail;\n if (!isAuthor && (!access || !roleSatisfies(access.role, \"editor\"))) {\n throw new ForbiddenError(\"Not allowed to delete this review comment\");\n }\n await deleteReviewComment(comment.id, actionCtx?.userEmail ?? null);\n return { commentId: comment.id, deleted: true };\n },\n audit: {\n target: (args) => ({\n type: args.resourceType,\n id: args.resourceId,\n }),\n },\n});\n"]}
1
+ {"version":3,"file":"delete-review-comment.js","sourceRoot":"","sources":["../../../src/review/actions/delete-review-comment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxE,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC7B,CAAC,CAAC;AAEH,eAAe,YAAY,CAAC;IAC1B,WAAW,EAAE,+BAA+B;IAC5C,MAAM;IACN,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,GAAwC,CAAC;QAC3D,MAAM,KAAK,GAAG;YACZ,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI;YACvC,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,IAAI;SAChC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,+BAA+B,CAClD,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,UAAU,EACf,SAAS,CACV,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE;YAChE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC;SAC7B,CAAC,CAAC;QACH,IACE,CAAC,OAAO;YACR,OAAO,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY;YAC1C,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,EACtC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,QAAQ,GACZ,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;YAC7B,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC;gBACjC,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YACpE,MAAM,IAAI,cAAc,CAAC,2CAA2C,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAC5C,OAAO,CAAC,EAAE,EACV,SAAS,EAAE,SAAS,IAAI,IAAI,CAC7B,CAAC;QACF,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAa,EAAE,YAAY,EAAE,CAAC;IACzE,CAAC;IACD,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjB,IAAI,EAAE,IAAI,CAAC,YAAY;YACvB,EAAE,EAAE,IAAI,CAAC,UAAU;SACpB,CAAC;KACH;CACF,CAAC,CAAC;AAEH,SAAS,cAAc,CAAC,KAAgC;IACtD,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,OAAO,UAAU,IAAI,IAAI,CAAC;AAC5B,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport { ForbiddenError } from \"../../sharing/access.js\";\nimport { roleSatisfies } from \"../../sharing/schema.js\";\nimport { resolveReviewableResourceAccess } from \"../registry.js\";\nimport { deleteReviewComment, getReviewCommentById } from \"../store.js\";\nimport type { ReviewResourceContext } from \"../types.js\";\n\nconst schema = z.object({\n resourceType: z.string().min(1),\n resourceId: z.string().min(1),\n commentId: z.string().min(1),\n});\n\nexport default defineAction({\n description: \"Soft-delete a review comment.\",\n schema,\n run: async (args, ctx) => {\n const actionCtx = ctx as ReviewResourceContext | undefined;\n const scope = {\n userEmail: actionCtx?.userEmail ?? null,\n orgId: actionCtx?.orgId ?? null,\n };\n const access = await resolveReviewableResourceAccess(\n args.resourceType,\n args.resourceId,\n actionCtx,\n );\n const comment = await getReviewCommentById(args.commentId, scope, {\n bypassScope: Boolean(access),\n });\n if (\n !comment ||\n comment.resourceType !== args.resourceType ||\n comment.resourceId !== args.resourceId\n ) {\n throw new Error(\"Review comment not found\");\n }\n const isAuthor =\n Boolean(actionCtx?.userEmail) &&\n normalizeEmail(comment.authorEmail) ===\n normalizeEmail(actionCtx?.userEmail);\n if (!isAuthor && (!access || !roleSatisfies(access.role, \"editor\"))) {\n throw new ForbiddenError(\"Not allowed to delete this review comment\");\n }\n const updatedCount = await deleteReviewComment(\n comment.id,\n actionCtx?.userEmail ?? null,\n );\n if (updatedCount < 1) {\n throw new Error(\"Review comment not found\");\n }\n return { commentId: comment.id, deleted: true as const, updatedCount };\n },\n audit: {\n target: (args) => ({\n type: args.resourceType,\n id: args.resourceId,\n }),\n },\n});\n\nfunction normalizeEmail(email: string | null | undefined): string | null {\n const normalized = email?.trim().toLowerCase();\n return normalized || null;\n}\n"]}
@@ -5,7 +5,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
5
5
  commentId?: string;
6
6
  }, {
7
7
  threadId: string;
8
- resolved: boolean;
8
+ resolved: true;
9
+ updatedCount: number;
9
10
  }>;
10
11
  export default _default;
11
12
  //# sourceMappingURL=resolve-review-thread.d.ts.map
@@ -30,11 +30,14 @@ export default defineAction({
30
30
  if (!threadId) {
31
31
  throw new Error("Provide threadId or commentId");
32
32
  }
33
- await resolveReviewThread(threadId, actionCtx?.userEmail ?? null, {
33
+ const updatedCount = await resolveReviewThread(threadId, actionCtx?.userEmail ?? null, {
34
34
  resourceType: args.resourceType,
35
35
  resourceId: args.resourceId,
36
36
  });
37
- return { threadId, resolved: true };
37
+ if (updatedCount < 1) {
38
+ throw new Error("Review thread not found");
39
+ }
40
+ return { threadId, resolved: true, updatedCount };
38
41
  },
39
42
  audit: {
40
43
  target: (args) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-review-thread.js","sourceRoot":"","sources":["../../../src/review/actions/resolve-review-thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGxE,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC;AAEH,eAAe,YAAY,CAAC;IAC1B,WAAW,EAAE,6CAA6C;IAC1D,MAAM;IACN,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,GAAwC,CAAC;QAC3D,MAAM,8BAA8B,CAClC,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,UAAU,EACf,SAAS,EACT,QAAQ,CACT,CAAC;QACF,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC7B,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,MAAM,oBAAoB,CACxC,IAAI,CAAC,SAAS,EACd;gBACE,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI;gBACvC,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,IAAI;aAChC,EACD,EAAE,WAAW,EAAE,IAAI,EAAE,CACtB,CAAC;YACF,IACE,CAAC,OAAO;gBACR,OAAO,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY;gBAC1C,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,EACtC,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC9C,CAAC;YACD,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,mBAAmB,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,EAAE;YAChE,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;QACH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACtC,CAAC;IACD,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjB,IAAI,EAAE,IAAI,CAAC,YAAY;YACvB,EAAE,EAAE,IAAI,CAAC,UAAU;SACpB,CAAC;KACH;CACF,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport { assertReviewableResourceAccess } from \"../registry.js\";\nimport { getReviewCommentById, resolveReviewThread } from \"../store.js\";\nimport type { ReviewResourceContext } from \"../types.js\";\n\nconst schema = z.object({\n resourceType: z.string().min(1),\n resourceId: z.string().min(1),\n threadId: z.string().optional(),\n commentId: z.string().optional(),\n});\n\nexport default defineAction({\n description: \"Resolve an inline comment or review thread.\",\n schema,\n run: async (args, ctx) => {\n const actionCtx = ctx as ReviewResourceContext | undefined;\n await assertReviewableResourceAccess(\n args.resourceType,\n args.resourceId,\n actionCtx,\n \"editor\",\n );\n let threadId = args.threadId;\n if (!threadId && args.commentId) {\n const comment = await getReviewCommentById(\n args.commentId,\n {\n userEmail: actionCtx?.userEmail ?? null,\n orgId: actionCtx?.orgId ?? null,\n },\n { bypassScope: true },\n );\n if (\n !comment ||\n comment.resourceType !== args.resourceType ||\n comment.resourceId !== args.resourceId\n ) {\n throw new Error(\"Review comment not found\");\n }\n threadId = comment.threadId;\n }\n if (!threadId) {\n throw new Error(\"Provide threadId or commentId\");\n }\n await resolveReviewThread(threadId, actionCtx?.userEmail ?? null, {\n resourceType: args.resourceType,\n resourceId: args.resourceId,\n });\n return { threadId, resolved: true };\n },\n audit: {\n target: (args) => ({\n type: args.resourceType,\n id: args.resourceId,\n }),\n },\n});\n"]}
1
+ {"version":3,"file":"resolve-review-thread.js","sourceRoot":"","sources":["../../../src/review/actions/resolve-review-thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGxE,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC;AAEH,eAAe,YAAY,CAAC;IAC1B,WAAW,EAAE,6CAA6C;IAC1D,MAAM;IACN,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,GAAwC,CAAC;QAC3D,MAAM,8BAA8B,CAClC,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,UAAU,EACf,SAAS,EACT,QAAQ,CACT,CAAC;QACF,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC7B,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,MAAM,oBAAoB,CACxC,IAAI,CAAC,SAAS,EACd;gBACE,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI;gBACvC,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,IAAI;aAChC,EACD,EAAE,WAAW,EAAE,IAAI,EAAE,CACtB,CAAC;YACF,IACE,CAAC,OAAO;gBACR,OAAO,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY;gBAC1C,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,EACtC,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC9C,CAAC;YACD,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAC5C,QAAQ,EACR,SAAS,EAAE,SAAS,IAAI,IAAI,EAC5B;YACE,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CACF,CAAC;QACF,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAa,EAAE,YAAY,EAAE,CAAC;IAC7D,CAAC;IACD,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjB,IAAI,EAAE,IAAI,CAAC,YAAY;YACvB,EAAE,EAAE,IAAI,CAAC,UAAU;SACpB,CAAC;KACH;CACF,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport { assertReviewableResourceAccess } from \"../registry.js\";\nimport { getReviewCommentById, resolveReviewThread } from \"../store.js\";\nimport type { ReviewResourceContext } from \"../types.js\";\n\nconst schema = z.object({\n resourceType: z.string().min(1),\n resourceId: z.string().min(1),\n threadId: z.string().optional(),\n commentId: z.string().optional(),\n});\n\nexport default defineAction({\n description: \"Resolve an inline comment or review thread.\",\n schema,\n run: async (args, ctx) => {\n const actionCtx = ctx as ReviewResourceContext | undefined;\n await assertReviewableResourceAccess(\n args.resourceType,\n args.resourceId,\n actionCtx,\n \"editor\",\n );\n let threadId = args.threadId;\n if (!threadId && args.commentId) {\n const comment = await getReviewCommentById(\n args.commentId,\n {\n userEmail: actionCtx?.userEmail ?? null,\n orgId: actionCtx?.orgId ?? null,\n },\n { bypassScope: true },\n );\n if (\n !comment ||\n comment.resourceType !== args.resourceType ||\n comment.resourceId !== args.resourceId\n ) {\n throw new Error(\"Review comment not found\");\n }\n threadId = comment.threadId;\n }\n if (!threadId) {\n throw new Error(\"Provide threadId or commentId\");\n }\n const updatedCount = await resolveReviewThread(\n threadId,\n actionCtx?.userEmail ?? null,\n {\n resourceType: args.resourceType,\n resourceId: args.resourceId,\n },\n );\n if (updatedCount < 1) {\n throw new Error(\"Review thread not found\");\n }\n return { threadId, resolved: true as const, updatedCount };\n },\n audit: {\n target: (args) => ({\n type: args.resourceType,\n id: args.resourceId,\n }),\n },\n});\n"]}
@@ -1,5 +1,5 @@
1
1
  export type { ReviewActorKind, ReviewComment, ReviewCommentKind, ReviewCommentStatus, ReviewMention, ReviewResolutionTarget, ReviewResourceAccess, ReviewResourceContext, ReviewResourceRole, ReviewScope, ReviewStatus, ReviewStatusEntry, ReviewableResourceRegistration, } from "./types.js";
2
2
  export { extractReviewMentions, normalizeReviewMentions } from "./mentions.js";
3
3
  export { __resetReviewableResourcesForTests, assertReviewableResourceAccess, getReviewableResource, listReviewableResources, registerReviewableResource, resolveReviewableResourceAccess, } from "./registry.js";
4
- export { __resetReviewInitForTests, consumeReviewFeedback, deleteReviewComment, ensureReviewTables, getReviewCommentById, getReviewStatus, insertReviewComment, queryReviewComments, resolveReviewThread, upsertReviewStatus, } from "./store.js";
4
+ export { __resetReviewInitForTests, ensureReviewTables, getReviewCommentById, getReviewStatus, queryReviewComments, } from "./store.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EACL,kCAAkC,EAClC,8BAA8B,EAC9B,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,+BAA+B,GAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EACL,kCAAkC,EAClC,8BAA8B,EAC9B,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,+BAA+B,GAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
@@ -1,4 +1,4 @@
1
1
  export { extractReviewMentions, normalizeReviewMentions } from "./mentions.js";
2
2
  export { __resetReviewableResourcesForTests, assertReviewableResourceAccess, getReviewableResource, listReviewableResources, registerReviewableResource, resolveReviewableResourceAccess, } from "./registry.js";
3
- export { __resetReviewInitForTests, consumeReviewFeedback, deleteReviewComment, ensureReviewTables, getReviewCommentById, getReviewStatus, insertReviewComment, queryReviewComments, resolveReviewThread, upsertReviewStatus, } from "./store.js";
3
+ export { __resetReviewInitForTests, ensureReviewTables, getReviewCommentById, getReviewStatus, queryReviewComments, } from "./store.js";
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EACL,kCAAkC,EAClC,8BAA8B,EAC9B,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,+BAA+B,GAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAC","sourcesContent":["export type {\n ReviewActorKind,\n ReviewComment,\n ReviewCommentKind,\n ReviewCommentStatus,\n ReviewMention,\n ReviewResolutionTarget,\n ReviewResourceAccess,\n ReviewResourceContext,\n ReviewResourceRole,\n ReviewScope,\n ReviewStatus,\n ReviewStatusEntry,\n ReviewableResourceRegistration,\n} from \"./types.js\";\nexport { extractReviewMentions, normalizeReviewMentions } from \"./mentions.js\";\nexport {\n __resetReviewableResourcesForTests,\n assertReviewableResourceAccess,\n getReviewableResource,\n listReviewableResources,\n registerReviewableResource,\n resolveReviewableResourceAccess,\n} from \"./registry.js\";\nexport {\n __resetReviewInitForTests,\n consumeReviewFeedback,\n deleteReviewComment,\n ensureReviewTables,\n getReviewCommentById,\n getReviewStatus,\n insertReviewComment,\n queryReviewComments,\n resolveReviewThread,\n upsertReviewStatus,\n} from \"./store.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EACL,kCAAkC,EAClC,8BAA8B,EAC9B,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,+BAA+B,GAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACpB,MAAM,YAAY,CAAC","sourcesContent":["export type {\n ReviewActorKind,\n ReviewComment,\n ReviewCommentKind,\n ReviewCommentStatus,\n ReviewMention,\n ReviewResolutionTarget,\n ReviewResourceAccess,\n ReviewResourceContext,\n ReviewResourceRole,\n ReviewScope,\n ReviewStatus,\n ReviewStatusEntry,\n ReviewableResourceRegistration,\n} from \"./types.js\";\nexport { extractReviewMentions, normalizeReviewMentions } from \"./mentions.js\";\nexport {\n __resetReviewableResourcesForTests,\n assertReviewableResourceAccess,\n getReviewableResource,\n listReviewableResources,\n registerReviewableResource,\n resolveReviewableResourceAccess,\n} from \"./registry.js\";\nexport {\n __resetReviewInitForTests,\n ensureReviewTables,\n getReviewCommentById,\n getReviewStatus,\n queryReviewComments,\n} from \"./store.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/review/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,8BAA8B,EAC/B,MAAM,YAAY,CAAC;AAIpB,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,8BAA8B,GAC3C,IAAI,CAON;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,GACX,8BAA8B,GAAG,SAAS,CAE5C;AAED,wBAAgB,uBAAuB,IAAI,8BAA8B,EAAE,CAE1E;AAED,wBAAsB,+BAA+B,CACnD,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,qBAAqB,GAC1B,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CA8BtC;AAED,wBAAsB,8BAA8B,CAClD,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,qBAAqB,GAAG,SAAS,EACtC,WAAW,EAAE,kBAAkB,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CAY/B;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GACxC,UAAU,CAIZ;AAED,wBAAgB,kCAAkC,IAAI,IAAI,CAEzD"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/review/registry.ts"],"names":[],"mappings":"AAMA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,8BAA8B,EAC/B,MAAM,YAAY,CAAC;AAIpB,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,8BAA8B,GAC3C,IAAI,CAON;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,GACX,8BAA8B,GAAG,SAAS,CAE5C;AAED,wBAAgB,uBAAuB,IAAI,8BAA8B,EAAE,CAE1E;AAYD,wBAAsB,+BAA+B,CACnD,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,qBAAqB,GAC1B,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CA4BtC;AAED,wBAAsB,8BAA8B,CAClD,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,qBAAqB,GAAG,SAAS,EACtC,WAAW,EAAE,kBAAkB,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CAY/B;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GACxC,UAAU,CAIZ;AAED,wBAAgB,kCAAkC,IAAI,IAAI,CAEzD"}
@@ -1,4 +1,4 @@
1
- import { ForbiddenError, resolveAccess } from "../sharing/access.js";
1
+ import { ForbiddenError, resolveAccess, } from "../sharing/access.js";
2
2
  import { getShareableResource } from "../sharing/registry.js";
3
3
  import { roleSatisfies } from "../sharing/schema.js";
4
4
  const registrations = new Map();
@@ -14,13 +14,21 @@ export function getReviewableResource(type) {
14
14
  export function listReviewableResources() {
15
15
  return Array.from(registrations.values());
16
16
  }
17
+ function accessContextFrom(ctx) {
18
+ if (!ctx)
19
+ return undefined;
20
+ return {
21
+ userEmail: ctx.userEmail ?? undefined,
22
+ orgId: ctx.orgId ?? undefined,
23
+ };
24
+ }
17
25
  export async function resolveReviewableResourceAccess(resourceType, resourceId, ctx) {
18
26
  const registration = getReviewableResource(resourceType);
19
27
  if (registration?.resolveAccess) {
20
28
  return registration.resolveAccess(resourceId, ctx);
21
29
  }
22
30
  if (getShareableResource(resourceType)) {
23
- const access = await resolveAccess(resourceType, resourceId);
31
+ const access = await resolveAccess(resourceType, resourceId, accessContextFrom(ctx));
24
32
  if (!access) {
25
33
  return null;
26
34
  }
@@ -32,16 +40,10 @@ export async function resolveReviewableResourceAccess(resourceType, resourceId,
32
40
  resource: access.resource,
33
41
  };
34
42
  }
35
- const userEmail = ctx?.userEmail ?? null;
36
- if (!userEmail) {
37
- return null;
38
- }
39
- return {
40
- role: "owner",
41
- ownerEmail: userEmail,
42
- orgId: ctx?.orgId ?? null,
43
- visibility: "private",
44
- };
43
+ // Fail closed: unregistered types, and registered types without an access
44
+ // resolver that aren't shareable, never invent ownership. bypassScope on
45
+ // review queries is only safe after a real resource ACL.
46
+ return null;
45
47
  }
46
48
  export async function assertReviewableResourceAccess(resourceType, resourceId, ctx, minimumRole) {
47
49
  const access = await resolveReviewableResourceAccess(resourceType, resourceId, ctx);
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/review/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAmB,MAAM,sBAAsB,CAAC;AAQtE,MAAM,aAAa,GAAG,IAAI,GAAG,EAA0C,CAAC;AAExE,MAAM,UAAU,0BAA0B,CACxC,YAA4C;IAE5C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;IACJ,CAAC;IACD,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,IAAY;IAEZ,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,YAAoB,EACpB,UAAkB,EAClB,GAA2B;IAE3B,MAAM,YAAY,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;IACzD,IAAI,YAAY,EAAE,aAAa,EAAE,CAAC;QAChC,OAAO,YAAY,CAAC,aAAa,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,oBAAoB,CAAC,YAAY,CAAC,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAA0B;YACvC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,IAAI,IAAI;YAC9C,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI;YACpC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU;YACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,EAAE,SAAS,IAAI,IAAI,CAAC;IACzC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,IAAI;QACzB,UAAU,EAAE,SAAS;KACtB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,YAAoB,EACpB,UAAkB,EAClB,GAAsC,EACtC,WAA+B;IAE/B,MAAM,MAAM,GAAG,MAAM,+BAA+B,CAClD,YAAY,EACZ,UAAU,EACV,GAAG,CACJ,CAAC;IACF,IAAI,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,cAAc,CACtB,yBAAyB,YAAY,IAAI,UAAU,EAAE,CACtD,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,UAAyC;IAEzC,OAAO,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,QAAQ;QACpD,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,kCAAkC;IAChD,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC","sourcesContent":["import { ForbiddenError, resolveAccess } from \"../sharing/access.js\";\nimport { getShareableResource } from \"../sharing/registry.js\";\nimport { roleSatisfies, type Visibility } from \"../sharing/schema.js\";\nimport type {\n ReviewResourceAccess,\n ReviewResourceContext,\n ReviewResourceRole,\n ReviewableResourceRegistration,\n} from \"./types.js\";\n\nconst registrations = new Map<string, ReviewableResourceRegistration>();\n\nexport function registerReviewableResource(\n registration: ReviewableResourceRegistration,\n): void {\n if (!registration.type.trim()) {\n throw new Error(\n \"registerReviewableResource requires a non-empty resource type\",\n );\n }\n registrations.set(registration.type, registration);\n}\n\nexport function getReviewableResource(\n type: string,\n): ReviewableResourceRegistration | undefined {\n return registrations.get(type);\n}\n\nexport function listReviewableResources(): ReviewableResourceRegistration[] {\n return Array.from(registrations.values());\n}\n\nexport async function resolveReviewableResourceAccess(\n resourceType: string,\n resourceId: string,\n ctx?: ReviewResourceContext,\n): Promise<ReviewResourceAccess | null> {\n const registration = getReviewableResource(resourceType);\n if (registration?.resolveAccess) {\n return registration.resolveAccess(resourceId, ctx);\n }\n\n if (getShareableResource(resourceType)) {\n const access = await resolveAccess(resourceType, resourceId);\n if (!access) {\n return null;\n }\n return {\n role: access.role as ReviewResourceRole,\n ownerEmail: access.resource.ownerEmail ?? null,\n orgId: access.resource.orgId ?? null,\n visibility: access.resource.visibility,\n resource: access.resource,\n };\n }\n\n const userEmail = ctx?.userEmail ?? null;\n if (!userEmail) {\n return null;\n }\n return {\n role: \"owner\",\n ownerEmail: userEmail,\n orgId: ctx?.orgId ?? null,\n visibility: \"private\",\n };\n}\n\nexport async function assertReviewableResourceAccess(\n resourceType: string,\n resourceId: string,\n ctx: ReviewResourceContext | undefined,\n minimumRole: ReviewResourceRole,\n): Promise<ReviewResourceAccess> {\n const access = await resolveReviewableResourceAccess(\n resourceType,\n resourceId,\n ctx,\n );\n if (!access || !roleSatisfies(access.role, minimumRole)) {\n throw new ForbiddenError(\n `Not allowed to access ${resourceType}:${resourceId}`,\n );\n }\n return access;\n}\n\nexport function normalizeReviewVisibility(\n visibility: Visibility | null | undefined,\n): Visibility {\n return visibility === \"org\" || visibility === \"public\"\n ? visibility\n : \"private\";\n}\n\nexport function __resetReviewableResourcesForTests(): void {\n registrations.clear();\n}\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/review/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ForbiddenError,\n resolveAccess,\n type AccessContext,\n} from \"../sharing/access.js\";\nimport { getShareableResource } from \"../sharing/registry.js\";\nimport { roleSatisfies, type Visibility } from \"../sharing/schema.js\";\nimport type {\n ReviewResourceAccess,\n ReviewResourceContext,\n ReviewResourceRole,\n ReviewableResourceRegistration,\n} from \"./types.js\";\n\nconst registrations = new Map<string, ReviewableResourceRegistration>();\n\nexport function registerReviewableResource(\n registration: ReviewableResourceRegistration,\n): void {\n if (!registration.type.trim()) {\n throw new Error(\n \"registerReviewableResource requires a non-empty resource type\",\n );\n }\n registrations.set(registration.type, registration);\n}\n\nexport function getReviewableResource(\n type: string,\n): ReviewableResourceRegistration | undefined {\n return registrations.get(type);\n}\n\nexport function listReviewableResources(): ReviewableResourceRegistration[] {\n return Array.from(registrations.values());\n}\n\nfunction accessContextFrom(\n ctx?: ReviewResourceContext,\n): AccessContext | undefined {\n if (!ctx) return undefined;\n return {\n userEmail: ctx.userEmail ?? undefined,\n orgId: ctx.orgId ?? undefined,\n };\n}\n\nexport async function resolveReviewableResourceAccess(\n resourceType: string,\n resourceId: string,\n ctx?: ReviewResourceContext,\n): Promise<ReviewResourceAccess | null> {\n const registration = getReviewableResource(resourceType);\n if (registration?.resolveAccess) {\n return registration.resolveAccess(resourceId, ctx);\n }\n\n if (getShareableResource(resourceType)) {\n const access = await resolveAccess(\n resourceType,\n resourceId,\n accessContextFrom(ctx),\n );\n if (!access) {\n return null;\n }\n return {\n role: access.role as ReviewResourceRole,\n ownerEmail: access.resource.ownerEmail ?? null,\n orgId: access.resource.orgId ?? null,\n visibility: access.resource.visibility,\n resource: access.resource,\n };\n }\n\n // Fail closed: unregistered types, and registered types without an access\n // resolver that aren't shareable, never invent ownership. bypassScope on\n // review queries is only safe after a real resource ACL.\n return null;\n}\n\nexport async function assertReviewableResourceAccess(\n resourceType: string,\n resourceId: string,\n ctx: ReviewResourceContext | undefined,\n minimumRole: ReviewResourceRole,\n): Promise<ReviewResourceAccess> {\n const access = await resolveReviewableResourceAccess(\n resourceType,\n resourceId,\n ctx,\n );\n if (!access || !roleSatisfies(access.role, minimumRole)) {\n throw new ForbiddenError(\n `Not allowed to access ${resourceType}:${resourceId}`,\n );\n }\n return access;\n}\n\nexport function normalizeReviewVisibility(\n visibility: Visibility | null | undefined,\n): Visibility {\n return visibility === \"org\" || visibility === \"public\"\n ? visibility\n : \"private\";\n}\n\nexport function __resetReviewableResourcesForTests(): void {\n registrations.clear();\n}\n"]}
@@ -49,12 +49,12 @@ export declare function getReviewCommentById(id: string, scope: ReviewScope, opt
49
49
  export declare function resolveReviewThread(threadId: string, resolvedBy?: string | null, resource?: {
50
50
  resourceType: string;
51
51
  resourceId: string;
52
- }): Promise<void>;
53
- export declare function deleteReviewComment(id: string, deletedBy?: string | null): Promise<void>;
52
+ }): Promise<number>;
53
+ export declare function deleteReviewComment(id: string, deletedBy?: string | null): Promise<number>;
54
54
  export declare function consumeReviewFeedback(ids: string[], consumedAt?: string, resource?: {
55
55
  resourceType: string;
56
56
  resourceId: string;
57
- }): Promise<void>;
57
+ }): Promise<number>;
58
58
  export declare function upsertReviewStatus(input: UpsertReviewStatusInput): Promise<ReviewStatusEntry>;
59
59
  export declare function getReviewStatus(resourceType: string, resourceId: string, scope: ReviewScope, options?: {
60
60
  bypassScope?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/review/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/review/store.ts"],"names":[],"mappings":"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"}
@@ -233,7 +233,7 @@ export async function resolveReviewThread(threadId, resolvedBy, resource) {
233
233
  const resourceClause = resource
234
234
  ? "AND resource_type = ? AND resource_id = ?"
235
235
  : "";
236
- await getDbExec().execute({
236
+ const result = await getDbExec().execute({
237
237
  sql: `UPDATE agent_review_comments
238
238
  SET status = 'resolved',
239
239
  resolved_by = ?,
@@ -248,11 +248,12 @@ export async function resolveReviewThread(threadId, resolvedBy, resource) {
248
248
  ...(resource ? [resource.resourceType, resource.resourceId] : []),
249
249
  ],
250
250
  });
251
+ return result.rowsAffected ?? 0;
251
252
  }
252
253
  export async function deleteReviewComment(id, deletedBy) {
253
254
  await ensureReviewTables();
254
255
  const now = new Date().toISOString();
255
- await getDbExec().execute({
256
+ const result = await getDbExec().execute({
256
257
  sql: `UPDATE agent_review_comments
257
258
  SET status = 'deleted',
258
259
  deleted_by = ?,
@@ -261,17 +262,18 @@ export async function deleteReviewComment(id, deletedBy) {
261
262
  WHERE id = ?`,
262
263
  args: [deletedBy ?? null, now, now, id],
263
264
  });
265
+ return result.rowsAffected ?? 0;
264
266
  }
265
267
  export async function consumeReviewFeedback(ids, consumedAt = new Date().toISOString(), resource) {
266
268
  if (!ids.length) {
267
- return;
269
+ return 0;
268
270
  }
269
271
  await ensureReviewTables();
270
272
  const placeholders = ids.map(() => "?").join(", ");
271
273
  const resourceClause = resource
272
274
  ? "AND resource_type = ? AND resource_id = ?"
273
275
  : "";
274
- await getDbExec().execute({
276
+ const result = await getDbExec().execute({
275
277
  sql: `UPDATE agent_review_comments
276
278
  SET consumed_at = ?,
277
279
  updated_at = ?
@@ -283,6 +285,7 @@ export async function consumeReviewFeedback(ids, consumedAt = new Date().toISOSt
283
285
  ...(resource ? [resource.resourceType, resource.resourceId] : []),
284
286
  ],
285
287
  });
288
+ return result.rowsAffected ?? 0;
286
289
  }
287
290
  export async function upsertReviewStatus(input) {
288
291
  await ensureReviewTables();