@agent-native/core 0.100.2 → 0.101.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +83 -0
- package/corpus/core/docs/content/locales/ar-SA/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/de-DE/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/es-ES/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +14 -0
- package/corpus/core/docs/content/locales/fr-FR/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/hi-IN/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/ja-JP/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/ko-KR/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/pt-BR/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +14 -0
- package/corpus/core/docs/content/locales/zh-CN/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +7 -0
- package/corpus/core/docs/content/locales/zh-TW/pr-visual-recap.mdx +48 -30
- package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +7 -0
- package/corpus/core/docs/content/pr-visual-recap.mdx +50 -32
- package/corpus/core/docs/content/template-plan.mdx +14 -0
- package/corpus/core/docs/content/toolkit-comments-review.mdx +16 -2
- package/corpus/core/package.json +4 -1
- package/corpus/core/src/a2a/index.ts +2 -1
- package/corpus/core/src/a2a/server.ts +34 -9
- package/corpus/core/src/agent/production-agent.ts +56 -10
- package/corpus/core/src/cli/create.ts +47 -19
- package/corpus/core/src/cli/pr-visual-recap-workflow.ts +2 -3
- package/corpus/core/src/cli/recap.ts +3 -4932
- package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +6 -4
- package/corpus/core/src/cli/skills-content/visual-recap-skill.ts +7 -1
- package/corpus/core/src/client/AgentPanel.tsx +19 -17
- package/corpus/core/src/client/analytics.ts +8 -1
- package/corpus/core/src/client/chat/markdown-renderer.tsx +54 -8
- package/corpus/core/src/client/chat/message-components.tsx +8 -2
- package/corpus/core/src/client/clipboard.ts +28 -1
- package/corpus/core/src/client/guided-questions.tsx +4 -0
- package/corpus/core/src/client/i18n.tsx +2 -1
- package/corpus/core/src/client/index.ts +4 -0
- package/corpus/core/src/client/review/ReviewCommentComposer.tsx +108 -0
- package/corpus/core/src/client/review/ReviewThreadPanel.tsx +482 -150
- package/corpus/core/src/client/review/index.ts +8 -0
- package/corpus/core/src/client/review/use-review.ts +35 -1
- package/corpus/core/src/client/use-agent-chat-context.ts +3 -2
- package/corpus/core/src/credentials/index.ts +41 -8
- package/corpus/core/src/extensions/fetch-tool.ts +33 -3
- package/corpus/core/src/notifications/channels.ts +20 -6
- package/corpus/core/src/review/actions/create-review-comment.ts +2 -1
- package/corpus/core/src/review/actions/get-review-feedback.ts +6 -11
- package/corpus/core/src/review/actions/list-review-comments.ts +38 -4
- package/corpus/core/src/review/actions/reply-review-comment.ts +33 -22
- package/corpus/core/src/review/actions/resolve-review-thread.ts +29 -2
- package/corpus/core/src/review/actions/send-review-thread-to-agent.ts +62 -0
- package/corpus/core/src/review/identity.ts +101 -0
- package/corpus/core/src/review/index.ts +14 -0
- package/corpus/core/src/review/store.ts +315 -8
- package/corpus/core/src/review/types.ts +4 -0
- package/corpus/core/src/secrets/crypto.ts +26 -10
- package/corpus/core/src/secrets/storage.ts +16 -3
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/action-routes.ts +125 -4
- package/corpus/core/src/server/agent-chat/plugin-options.ts +16 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +61 -7
- package/corpus/core/src/server/derived-secret.ts +5 -1
- package/corpus/core/src/server/index.ts +8 -0
- package/corpus/core/src/vite/action-types-plugin.ts +4 -0
- package/corpus/templates/analytics/changelog/2026-07-14-daily-dashboard-email-captures-authenticate-with-a-sessi.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-14-long-running-cross-app-analyses-now-continue-reliably-in-the.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +156 -3
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +8 -4
- package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +402 -142
- package/corpus/templates/assets/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/assets/app/i18n-data.ts +1 -0
- package/corpus/templates/assets/app/routes/library.tsx +187 -48
- package/corpus/templates/assets/changelog/2026-07-13-merged-the-candidates-panel-into-the-library-as-a-drafts-tab.md +6 -0
- package/corpus/templates/chat/app/lib/agent-page.tsx +40 -0
- package/corpus/templates/chat/app/routes/agent.tsx +5 -3
- package/corpus/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +5 -0
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/get-feature-flags.ts +30 -0
- package/corpus/templates/clips/actions/lib/transcript-preview.ts +48 -0
- package/corpus/templates/clips/actions/request-transcript.ts +41 -1
- package/corpus/templates/clips/actions/view-screen.ts +5 -9
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +44 -81
- package/corpus/templates/clips/app/components/player/video-player.tsx +39 -1
- package/corpus/templates/clips/app/hooks/use-desktop-promo.ts +6 -12
- package/corpus/templates/clips/app/hooks/use-mse-video-source.ts +146 -0
- package/corpus/templates/clips/app/i18n/ar-SA.ts +0 -8
- package/corpus/templates/clips/app/i18n/de-DE.ts +0 -9
- package/corpus/templates/clips/app/i18n/en-US.ts +0 -8
- package/corpus/templates/clips/app/i18n/es-ES.ts +0 -9
- package/corpus/templates/clips/app/i18n/fr-FR.ts +0 -9
- package/corpus/templates/clips/app/i18n/hi-IN.ts +0 -8
- package/corpus/templates/clips/app/i18n/ja-JP.ts +0 -9
- package/corpus/templates/clips/app/i18n/ko-KR.ts +0 -9
- package/corpus/templates/clips/app/i18n/pt-BR.ts +0 -9
- package/corpus/templates/clips/app/i18n/zh-CN.ts +0 -7
- package/corpus/templates/clips/app/i18n/zh-TW.ts +0 -7
- package/corpus/templates/clips/app/lib/capture-install-options.ts +21 -0
- package/corpus/templates/clips/app/lib/fmp4.ts +271 -0
- package/corpus/templates/clips/app/lib/mse-video-loader.ts +585 -0
- package/corpus/templates/clips/app/routes/_app.dictate.tsx +0 -4
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +5 -13
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +2 -37
- package/corpus/templates/clips/app/routes/download.tsx +3 -2
- package/corpus/templates/clips/changelog/2026-07-10-shared-clips-now-start-playing-instantly-instead-of-showing-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-14-clips-now-distinguishes-transcript-previews-from-incomplete-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-14-desktop-app-prompts-stay-hidden-after-you-download-the-insta.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-14-share-dialogs-show-separate-links-for-people-and-agents.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +5 -0
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +10 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +2518 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +353 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +558 -67
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +11 -1
- package/corpus/templates/clips/desktop/src-tauri/src/remote_flags.rs +188 -0
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +1 -1
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +1 -0
- package/corpus/templates/clips/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +5 -1
- package/corpus/templates/clips/shared/feature-flags.ts +41 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +3 -0
- package/corpus/templates/design/.agents/skills/design-review-feedback/SKILL.md +42 -0
- package/corpus/templates/design/AGENTS.md +6 -0
- package/corpus/templates/design/README.md +1 -0
- package/corpus/templates/design/actions/navigate.ts +4 -4
- package/corpus/templates/design/actions/view-screen.ts +116 -2
- package/corpus/templates/design/agent-native.app-skill.json +5 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +52 -59
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +13 -9
- package/corpus/templates/design/app/components/design/EditPanel.tsx +79 -11
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +78 -65
- package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +161 -0
- package/corpus/templates/design/app/components/design/ReviewStatusControl.tsx +96 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +166 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +1 -0
- package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +1077 -0
- package/corpus/templates/design/app/components/visual-editor/index.ts +1 -0
- package/corpus/templates/design/app/components/visual-editor/review-canvas-state.ts +42 -0
- package/corpus/templates/design/app/hooks/use-design-systems.ts +2 -2
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +9 -6
- package/corpus/templates/design/app/hooks/use-question-flow.ts +7 -1
- package/corpus/templates/design/app/i18n/ar-SA.ts +56 -1
- package/corpus/templates/design/app/i18n/de-DE.ts +57 -1
- package/corpus/templates/design/app/i18n/en-US.ts +56 -1
- package/corpus/templates/design/app/i18n/es-ES.ts +56 -1
- package/corpus/templates/design/app/i18n/fr-FR.ts +57 -1
- package/corpus/templates/design/app/i18n/hi-IN.ts +56 -1
- package/corpus/templates/design/app/i18n/ja-JP.ts +56 -1
- package/corpus/templates/design/app/i18n/ko-KR.ts +56 -1
- package/corpus/templates/design/app/i18n/pt-BR.ts +57 -1
- package/corpus/templates/design/app/i18n/zh-CN.ts +56 -1
- package/corpus/templates/design/app/i18n/zh-TW.ts +51 -0
- package/corpus/templates/design/app/pages/Present.tsx +172 -14
- package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +23 -0
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +10 -0
- package/corpus/templates/design/app/pages/present-review-state.ts +18 -0
- package/corpus/templates/design/app/public-routes.ts +8 -0
- package/corpus/templates/design/app/root.tsx +7 -6
- package/corpus/templates/design/changelog/2026-07-13-dragged-design-assets-now-appear-at-the-visible-drop-locatio.md +6 -0
- package/corpus/templates/design/changelog/2026-07-13-reviewers-can-pin-comments-on-shared-designs-and-apply-verif.md +6 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +10 -0
- package/corpus/templates/design/server/plugins/auth.ts +7 -5
- package/corpus/templates/design/server/plugins/review.ts +9 -0
- package/corpus/templates/design/shared/review-anchor.ts +83 -0
- package/corpus/templates/design/shared/review-summary.ts +25 -0
- package/corpus/templates/dispatch/changelog/2026-07-14-dispatch-now-distinguishes-connected-agents-from-locally-mou.md +6 -0
- package/corpus/templates/forms/.agents/skills/form-publishing/SKILL.md +2 -0
- package/corpus/templates/forms/AGENTS.md +4 -0
- package/corpus/templates/forms/actions/create-form.ts +2 -1
- package/corpus/templates/forms/actions/update-form.ts +5 -2
- package/corpus/templates/forms/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/forms/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/forms/app/i18n/en-US.ts +3 -0
- package/corpus/templates/forms/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/forms/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/forms/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/forms/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/forms/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/forms/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/forms/app/i18n/zh-CN.ts +3 -0
- package/corpus/templates/forms/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +19 -0
- package/corpus/templates/forms/changelog/2026-07-14-fixed-the-ask-forms-loading-input-appearing-above-the-welcom.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-14-form-social-previews-now-show-the-form-title-description-and.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-14-forms-can-email-the-form-owner-when-new-responses-arrive.md +6 -0
- package/corpus/templates/forms/server/handlers/submissions.ts +17 -0
- package/corpus/templates/forms/server/lib/form-og-image.ts +64 -6
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +6 -2
- package/corpus/templates/forms/server/lib/response-email.ts +65 -0
- package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/forms/server/routes/api/forms/og/[...slug]/og.png.get.ts +184 -0
- package/corpus/templates/forms/shared/types.ts +2 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +6 -4
- package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +7 -1
- package/dist/a2a/index.d.ts +2 -1
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/server.d.ts +25 -0
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +30 -6
- package/dist/a2a/server.js.map +1 -1
- package/dist/agent/production-agent.d.ts +2 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +37 -12
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/create.d.ts +5 -3
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +44 -19
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts +2 -2
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.js +2 -2
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/cli/recap.d.ts +3 -562
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +3 -3875
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.js +6 -4
- package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
- package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/visual-recap-skill.js +7 -1
- package/dist/cli/skills-content/visual-recap-skill.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +3 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/analytics.d.ts +5 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +3 -1
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/markdown-renderer.d.ts +1 -0
- package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
- package/dist/client/chat/markdown-renderer.js +36 -1
- package/dist/client/chat/markdown-renderer.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +5 -2
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/clipboard.d.ts +3 -1
- package/dist/client/clipboard.d.ts.map +1 -1
- package/dist/client/clipboard.js +24 -1
- package/dist/client/clipboard.js.map +1 -1
- package/dist/client/guided-questions.d.ts +3 -1
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +2 -1
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/client/i18n.d.ts.map +1 -1
- package/dist/client/i18n.js +3 -1
- package/dist/client/i18n.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/review/ReviewCommentComposer.d.ts +18 -0
- package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -0
- package/dist/client/review/ReviewCommentComposer.js +30 -0
- package/dist/client/review/ReviewCommentComposer.js.map +1 -0
- package/dist/client/review/ReviewThreadPanel.d.ts +28 -1
- package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -1
- package/dist/client/review/ReviewThreadPanel.js +151 -39
- package/dist/client/review/ReviewThreadPanel.js.map +1 -1
- package/dist/client/review/index.d.ts +3 -2
- package/dist/client/review/index.d.ts.map +1 -1
- package/dist/client/review/index.js +2 -1
- package/dist/client/review/index.js.map +1 -1
- package/dist/client/review/use-review.d.ts +23 -0
- package/dist/client/review/use-review.d.ts.map +1 -1
- package/dist/client/review/use-review.js +3 -0
- package/dist/client/review/use-review.js.map +1 -1
- package/dist/client/use-agent-chat-context.d.ts +1 -1
- package/dist/client/use-agent-chat-context.d.ts.map +1 -1
- package/dist/client/use-agent-chat-context.js +4 -2
- package/dist/client/use-agent-chat-context.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/credentials/index.d.ts +12 -7
- package/dist/credentials/index.d.ts.map +1 -1
- package/dist/credentials/index.js +33 -8
- package/dist/credentials/index.js.map +1 -1
- package/dist/extensions/fetch-tool.d.ts +13 -1
- package/dist/extensions/fetch-tool.d.ts.map +1 -1
- package/dist/extensions/fetch-tool.js +9 -2
- package/dist/extensions/fetch-tool.js.map +1 -1
- package/dist/notifications/channels.js +20 -4
- package/dist/notifications/channels.js.map +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/review/actions/create-review-comment.js +2 -1
- package/dist/review/actions/create-review-comment.js.map +1 -1
- package/dist/review/actions/get-review-feedback.js +6 -11
- package/dist/review/actions/get-review-feedback.js.map +1 -1
- package/dist/review/actions/list-review-comments.d.ts +1 -0
- package/dist/review/actions/list-review-comments.js +25 -4
- package/dist/review/actions/list-review-comments.js.map +1 -1
- package/dist/review/actions/reply-review-comment.js +12 -5
- package/dist/review/actions/reply-review-comment.js.map +1 -1
- package/dist/review/actions/resolve-review-thread.d.ts +3 -0
- package/dist/review/actions/resolve-review-thread.js +20 -3
- package/dist/review/actions/resolve-review-thread.js.map +1 -1
- package/dist/review/actions/send-review-thread-to-agent.d.ts +17 -0
- package/dist/review/actions/send-review-thread-to-agent.d.ts.map +1 -0
- package/dist/review/actions/send-review-thread-to-agent.js +49 -0
- package/dist/review/actions/send-review-thread-to-agent.js.map +1 -0
- package/dist/review/identity.d.ts +6 -0
- package/dist/review/identity.d.ts.map +1 -0
- package/dist/review/identity.js +68 -0
- package/dist/review/identity.js.map +1 -0
- package/dist/review/index.d.ts +3 -1
- package/dist/review/index.d.ts.map +1 -1
- package/dist/review/index.js +2 -1
- package/dist/review/index.js.map +1 -1
- package/dist/review/store.d.ts +36 -0
- package/dist/review/store.d.ts.map +1 -1
- package/dist/review/store.js +223 -8
- package/dist/review/store.js.map +1 -1
- package/dist/review/types.d.ts +4 -0
- package/dist/review/types.d.ts.map +1 -1
- package/dist/review/types.js.map +1 -1
- package/dist/secrets/crypto.d.ts +15 -7
- package/dist/secrets/crypto.d.ts.map +1 -1
- package/dist/secrets/crypto.js +23 -10
- package/dist/secrets/crypto.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +16 -3
- package/dist/secrets/storage.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts +45 -0
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +71 -5
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat/plugin-options.d.ts +16 -0
- package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
- package/dist/server/agent-chat/plugin-options.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +20 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +39 -4
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/derived-secret.d.ts +1 -1
- package/dist/server/derived-secret.d.ts.map +1 -1
- package/dist/server/derived-secret.js.map +1 -1
- package/dist/server/index.d.ts +3 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +4 -0
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/docs/content/locales/ar-SA/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/ar-SA/template-plan.mdx +7 -0
- package/docs/content/locales/de-DE/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/de-DE/template-plan.mdx +7 -0
- package/docs/content/locales/es-ES/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/es-ES/template-plan.mdx +14 -0
- package/docs/content/locales/fr-FR/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/fr-FR/template-plan.mdx +7 -0
- package/docs/content/locales/hi-IN/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/hi-IN/template-plan.mdx +7 -0
- package/docs/content/locales/ja-JP/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/ja-JP/template-plan.mdx +7 -0
- package/docs/content/locales/ko-KR/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/ko-KR/template-plan.mdx +7 -0
- package/docs/content/locales/pt-BR/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/pt-BR/template-plan.mdx +14 -0
- package/docs/content/locales/zh-CN/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/zh-CN/template-plan.mdx +7 -0
- package/docs/content/locales/zh-TW/pr-visual-recap.mdx +48 -30
- package/docs/content/locales/zh-TW/template-plan.mdx +7 -0
- package/docs/content/pr-visual-recap.mdx +50 -32
- package/docs/content/template-plan.mdx +14 -0
- package/docs/content/toolkit-comments-review.mdx +16 -2
- package/package.json +4 -1
- package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +0 -68
- package/corpus/templates/forms/server/routes/api/forms/og/[slug]/og.png.get.ts +0 -45
package/dist/review/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/review/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { getDbExec, isPostgres } from \"../db/client.js\";\nimport { ensureIndexExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport type { Visibility } from \"../sharing/schema.js\";\nimport type {\n ReviewActorKind,\n ReviewComment,\n ReviewCommentKind,\n ReviewCommentStatus,\n ReviewMention,\n ReviewResolutionTarget,\n ReviewScope,\n ReviewStatus,\n ReviewStatusEntry,\n} from \"./types.js\";\n\nlet reviewTablesInitPromise: Promise<void> | undefined;\n\nexport interface InsertReviewCommentInput {\n resourceType: string;\n resourceId: string;\n threadId?: string | null;\n parentCommentId?: string | null;\n targetId?: string | null;\n kind?: ReviewCommentKind;\n anchor?: unknown | null;\n body: string;\n authorEmail?: string | null;\n authorName?: string | null;\n createdBy?: ReviewActorKind;\n resolutionTarget?: ReviewResolutionTarget | null;\n mentions?: ReviewMention[];\n ownerEmail?: string | null;\n orgId?: string | null;\n visibility?: Visibility | null;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface QueryReviewCommentsInput {\n resourceType: string;\n resourceId: string;\n scope: ReviewScope;\n bypassScope?: boolean;\n includeResolved?: boolean;\n includeDeleted?: boolean;\n targetId?: string | null;\n limit?: number;\n}\n\nexport interface UpsertReviewStatusInput {\n resourceType: string;\n resourceId: string;\n status: ReviewStatus;\n note?: string | null;\n updatedBy?: string | null;\n ownerEmail?: string | null;\n orgId?: string | null;\n visibility?: Visibility | null;\n metadata?: Record<string, unknown> | null;\n}\n\nexport async function ensureReviewTables(): Promise<void> {\n if (!reviewTablesInitPromise) {\n reviewTablesInitPromise = (async () => {\n const client = getDbExec();\n const createCommentsSql = `CREATE TABLE IF NOT EXISTS agent_review_comments (\n id TEXT PRIMARY KEY,\n resource_type TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n thread_id TEXT NOT NULL,\n parent_comment_id TEXT,\n target_id TEXT,\n kind TEXT NOT NULL DEFAULT 'comment',\n status TEXT NOT NULL DEFAULT 'open',\n anchor_json TEXT,\n body TEXT NOT NULL,\n author_email TEXT,\n author_name TEXT,\n created_by TEXT NOT NULL DEFAULT 'human',\n resolution_target TEXT,\n mentions_json TEXT,\n owner_email TEXT,\n org_id TEXT,\n visibility TEXT NOT NULL DEFAULT 'private',\n resolved_by TEXT,\n resolved_at TEXT,\n consumed_at TEXT,\n deleted_by TEXT,\n deleted_at TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n metadata_json TEXT\n )`;\n const createStatusesSql = `CREATE TABLE IF NOT EXISTS agent_review_statuses (\n id TEXT PRIMARY KEY,\n resource_type TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n status TEXT NOT NULL,\n note TEXT,\n updated_by TEXT,\n updated_at TEXT NOT NULL,\n owner_email TEXT,\n org_id TEXT,\n visibility TEXT NOT NULL DEFAULT 'private',\n metadata_json TEXT\n )`;\n const indexes = [\n `CREATE INDEX IF NOT EXISTS idx_agent_review_comments_resource\n ON agent_review_comments (resource_type, resource_id, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_review_comments_thread\n ON agent_review_comments (thread_id, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_review_comments_owner\n ON agent_review_comments (owner_email, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_review_comments_org\n ON agent_review_comments (org_id, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_review_statuses_resource\n ON agent_review_statuses (resource_type, resource_id)`,\n ];\n\n if (isPostgres()) {\n await ensureTableExists(\"agent_review_comments\", createCommentsSql);\n await ensureTableExists(\"agent_review_statuses\", createStatusesSql);\n await ensureIndexExists(\n \"idx_agent_review_comments_resource\",\n indexes[0],\n );\n await ensureIndexExists(\"idx_agent_review_comments_thread\", indexes[1]);\n await ensureIndexExists(\"idx_agent_review_comments_owner\", indexes[2]);\n await ensureIndexExists(\"idx_agent_review_comments_org\", indexes[3]);\n await ensureIndexExists(\n \"idx_agent_review_statuses_resource\",\n indexes[4],\n );\n } else {\n await client.execute(createCommentsSql);\n await client.execute(createStatusesSql);\n for (const indexSql of indexes) {\n await client.execute(indexSql);\n }\n }\n })();\n }\n\n await reviewTablesInitPromise;\n}\n\nexport async function insertReviewComment(\n input: InsertReviewCommentInput,\n): Promise<ReviewComment> {\n await ensureReviewTables();\n const client = getDbExec();\n const id = createReviewId(\"comment\");\n const now = new Date().toISOString();\n const comment: ReviewComment = {\n id,\n resourceType: input.resourceType,\n resourceId: input.resourceId,\n threadId: input.threadId ?? id,\n parentCommentId: input.parentCommentId ?? null,\n targetId: input.targetId ?? null,\n kind: input.kind ?? \"comment\",\n status: \"open\",\n anchor: input.anchor ?? null,\n body: input.body,\n authorEmail: input.authorEmail ?? null,\n authorName: input.authorName ?? null,\n createdBy: input.createdBy ?? \"human\",\n resolutionTarget: input.resolutionTarget ?? null,\n mentions: input.mentions ?? [],\n ownerEmail: input.ownerEmail ?? input.authorEmail ?? null,\n orgId: input.orgId ?? null,\n visibility:\n input.visibility === \"org\" || input.visibility === \"public\"\n ? input.visibility\n : \"private\",\n resolvedBy: null,\n resolvedAt: null,\n consumedAt: null,\n deletedBy: null,\n deletedAt: null,\n createdAt: now,\n updatedAt: now,\n metadata: input.metadata ?? null,\n };\n\n await client.execute({\n sql: `INSERT INTO agent_review_comments (\n id,\n resource_type,\n resource_id,\n thread_id,\n parent_comment_id,\n target_id,\n kind,\n status,\n anchor_json,\n body,\n author_email,\n author_name,\n created_by,\n resolution_target,\n mentions_json,\n owner_email,\n org_id,\n visibility,\n resolved_by,\n resolved_at,\n consumed_at,\n deleted_by,\n deleted_at,\n created_at,\n updated_at,\n metadata_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n comment.id,\n comment.resourceType,\n comment.resourceId,\n comment.threadId,\n comment.parentCommentId,\n comment.targetId,\n comment.kind,\n comment.status,\n stringifyOptionalJson(comment.anchor),\n comment.body,\n comment.authorEmail,\n comment.authorName,\n comment.createdBy,\n comment.resolutionTarget,\n stringifyOptionalJson(comment.mentions),\n comment.ownerEmail,\n comment.orgId,\n comment.visibility,\n comment.resolvedBy,\n comment.resolvedAt,\n comment.consumedAt,\n comment.deletedBy,\n comment.deletedAt,\n comment.createdAt,\n comment.updatedAt,\n stringifyOptionalJson(comment.metadata),\n ],\n });\n\n return comment;\n}\n\nexport async function queryReviewComments(\n input: QueryReviewCommentsInput,\n): Promise<ReviewComment[]> {\n await ensureReviewTables();\n const client = getDbExec();\n const { clause, params } = input.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedReviewClause(input.scope);\n const filters = [\"resource_type = ?\", \"resource_id = ?\", clause];\n const filterParams: unknown[] = [\n input.resourceType,\n input.resourceId,\n ...params,\n ];\n if (!input.includeDeleted) {\n filters.push(\"deleted_at IS NULL\");\n filters.push(\"status <> 'deleted'\");\n }\n if (!input.includeResolved) {\n filters.push(\"status <> 'resolved'\");\n }\n if (input.targetId !== undefined) {\n if (input.targetId === null) {\n filters.push(\"target_id IS NULL\");\n } else {\n filters.push(\"target_id = ?\");\n filterParams.push(input.targetId);\n }\n }\n\n const result = await client.execute({\n sql: `SELECT ${commentColumns()}\n FROM agent_review_comments\n WHERE ${filters.join(\" AND \")}\n ORDER BY created_at ASC\n LIMIT ?`,\n args: [...filterParams, clampLimit(input.limit)],\n });\n return (result.rows ?? []).map(mapCommentRow);\n}\n\nexport async function getReviewCommentById(\n id: string,\n scope: ReviewScope,\n options: { bypassScope?: boolean } = {},\n): Promise<ReviewComment | null> {\n await ensureReviewTables();\n const client = getDbExec();\n const { clause, params } = options.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedReviewClause(scope);\n const result = await client.execute({\n sql: `SELECT ${commentColumns()}\n FROM agent_review_comments\n WHERE id = ? AND ${clause}\n LIMIT 1`,\n args: [id, ...params],\n });\n const row = result.rows?.[0];\n return row ? mapCommentRow(row) : null;\n}\n\nexport async function resolveReviewThread(\n threadId: string,\n resolvedBy?: string | null,\n resource?: { resourceType: string; resourceId: string },\n): Promise<number> {\n await ensureReviewTables();\n const now = new Date().toISOString();\n const resourceClause = resource\n ? \"AND resource_type = ? AND resource_id = ?\"\n : \"\";\n const result = await getDbExec().execute({\n sql: `UPDATE agent_review_comments\n SET status = 'resolved',\n resolved_by = ?,\n resolved_at = ?,\n updated_at = ?\n WHERE thread_id = ? AND deleted_at IS NULL ${resourceClause}`,\n args: [\n resolvedBy ?? null,\n now,\n now,\n threadId,\n ...(resource ? [resource.resourceType, resource.resourceId] : []),\n ],\n });\n return result.rowsAffected ?? 0;\n}\n\nexport async function deleteReviewComment(\n id: string,\n deletedBy?: string | null,\n): Promise<number> {\n await ensureReviewTables();\n const now = new Date().toISOString();\n const result = await getDbExec().execute({\n sql: `UPDATE agent_review_comments\n SET status = 'deleted',\n deleted_by = ?,\n deleted_at = ?,\n updated_at = ?\n WHERE id = ?`,\n args: [deletedBy ?? null, now, now, id],\n });\n return result.rowsAffected ?? 0;\n}\n\nexport async function consumeReviewFeedback(\n ids: string[],\n consumedAt = new Date().toISOString(),\n resource?: { resourceType: string; resourceId: string },\n): Promise<number> {\n if (!ids.length) {\n return 0;\n }\n await ensureReviewTables();\n const placeholders = ids.map(() => \"?\").join(\", \");\n const resourceClause = resource\n ? \"AND resource_type = ? AND resource_id = ?\"\n : \"\";\n const result = await getDbExec().execute({\n sql: `UPDATE agent_review_comments\n SET consumed_at = ?,\n updated_at = ?\n WHERE id IN (${placeholders}) ${resourceClause}`,\n args: [\n consumedAt,\n consumedAt,\n ...ids,\n ...(resource ? [resource.resourceType, resource.resourceId] : []),\n ],\n });\n return result.rowsAffected ?? 0;\n}\n\nexport async function upsertReviewStatus(\n input: UpsertReviewStatusInput,\n): Promise<ReviewStatusEntry> {\n await ensureReviewTables();\n const client = getDbExec();\n const id = statusId(input.resourceType, input.resourceId);\n const now = new Date().toISOString();\n const existing = await client.execute({\n sql: \"SELECT id FROM agent_review_statuses WHERE id = ? LIMIT 1\",\n args: [id],\n });\n const entry: ReviewStatusEntry = {\n id,\n resourceType: input.resourceType,\n resourceId: input.resourceId,\n status: input.status,\n note: input.note ?? null,\n updatedBy: input.updatedBy ?? null,\n updatedAt: now,\n ownerEmail: input.ownerEmail ?? input.updatedBy ?? null,\n orgId: input.orgId ?? null,\n visibility:\n input.visibility === \"org\" || input.visibility === \"public\"\n ? input.visibility\n : \"private\",\n metadata: input.metadata ?? null,\n };\n\n if (existing.rows?.length) {\n await client.execute({\n sql: `UPDATE agent_review_statuses\n SET status = ?,\n note = ?,\n updated_by = ?,\n updated_at = ?,\n owner_email = ?,\n org_id = ?,\n visibility = ?,\n metadata_json = ?\n WHERE id = ?`,\n args: [\n entry.status,\n entry.note,\n entry.updatedBy,\n entry.updatedAt,\n entry.ownerEmail,\n entry.orgId,\n entry.visibility,\n stringifyOptionalJson(entry.metadata),\n entry.id,\n ],\n });\n } else {\n await client.execute({\n sql: `INSERT INTO agent_review_statuses (\n id,\n resource_type,\n resource_id,\n status,\n note,\n updated_by,\n updated_at,\n owner_email,\n org_id,\n visibility,\n metadata_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n entry.id,\n entry.resourceType,\n entry.resourceId,\n entry.status,\n entry.note,\n entry.updatedBy,\n entry.updatedAt,\n entry.ownerEmail,\n entry.orgId,\n entry.visibility,\n stringifyOptionalJson(entry.metadata),\n ],\n });\n }\n\n return entry;\n}\n\nexport async function getReviewStatus(\n resourceType: string,\n resourceId: string,\n scope: ReviewScope,\n options: { bypassScope?: boolean } = {},\n): Promise<ReviewStatusEntry | null> {\n await ensureReviewTables();\n const client = getDbExec();\n const { clause, params } = options.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedReviewClause(scope);\n const result = await client.execute({\n sql: `SELECT ${statusColumns()}\n FROM agent_review_statuses\n WHERE resource_type = ? AND resource_id = ? AND ${clause}\n LIMIT 1`,\n args: [resourceType, resourceId, ...params],\n });\n const row = result.rows?.[0];\n return row ? mapStatusRow(row) : null;\n}\n\nexport function __resetReviewInitForTests(): void {\n reviewTablesInitPromise = undefined;\n}\n\nfunction commentColumns(): string {\n return [\n \"id\",\n \"resource_type\",\n \"resource_id\",\n \"thread_id\",\n \"parent_comment_id\",\n \"target_id\",\n \"kind\",\n \"status\",\n \"anchor_json\",\n \"body\",\n \"author_email\",\n \"author_name\",\n \"created_by\",\n \"resolution_target\",\n \"mentions_json\",\n \"owner_email\",\n \"org_id\",\n \"visibility\",\n \"resolved_by\",\n \"resolved_at\",\n \"consumed_at\",\n \"deleted_by\",\n \"deleted_at\",\n \"created_at\",\n \"updated_at\",\n \"metadata_json\",\n ].join(\", \");\n}\n\nfunction statusColumns(): string {\n return [\n \"id\",\n \"resource_type\",\n \"resource_id\",\n \"status\",\n \"note\",\n \"updated_by\",\n \"updated_at\",\n \"owner_email\",\n \"org_id\",\n \"visibility\",\n \"metadata_json\",\n ].join(\", \");\n}\n\nfunction scopedReviewClause(scope: ReviewScope): {\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 return { clause: `(${parts.join(\" OR \")})`, params };\n}\n\nfunction mapCommentRow(row: Record<string, unknown>): ReviewComment {\n return {\n id: String(row.id),\n resourceType: String(row.resource_type),\n resourceId: String(row.resource_id),\n threadId: String(row.thread_id),\n parentCommentId: nullableString(row.parent_comment_id),\n targetId: nullableString(row.target_id),\n kind: normalizeKind(row.kind),\n status: normalizeCommentStatus(row.status),\n anchor: parseOptionalJson(row.anchor_json),\n body: String(row.body),\n authorEmail: nullableString(row.author_email),\n authorName: nullableString(row.author_name),\n createdBy: normalizeActor(row.created_by),\n resolutionTarget: normalizeResolutionTarget(row.resolution_target),\n mentions: parseMentions(row.mentions_json),\n ownerEmail: nullableString(row.owner_email),\n orgId: nullableString(row.org_id),\n visibility: normalizeVisibility(row.visibility),\n resolvedBy: nullableString(row.resolved_by),\n resolvedAt: nullableString(row.resolved_at),\n consumedAt: nullableString(row.consumed_at),\n deletedBy: nullableString(row.deleted_by),\n deletedAt: nullableString(row.deleted_at),\n createdAt: String(row.created_at),\n updatedAt: String(row.updated_at),\n metadata: parseObject(row.metadata_json),\n };\n}\n\nfunction mapStatusRow(row: Record<string, unknown>): ReviewStatusEntry {\n return {\n id: String(row.id),\n resourceType: String(row.resource_type),\n resourceId: String(row.resource_id),\n status: normalizeReviewStatus(row.status),\n note: nullableString(row.note),\n updatedBy: nullableString(row.updated_by),\n updatedAt: String(row.updated_at),\n ownerEmail: nullableString(row.owner_email),\n orgId: nullableString(row.org_id),\n visibility: normalizeVisibility(row.visibility),\n metadata: parseObject(row.metadata_json),\n };\n}\n\nfunction createReviewId(prefix: string): string {\n return `rev_${prefix}_${globalThis.crypto.randomUUID()}`;\n}\n\nfunction statusId(resourceType: string, resourceId: string): string {\n return `${resourceType}:${resourceId}`;\n}\n\nfunction clampLimit(value: number | undefined): number {\n if (!Number.isFinite(value)) {\n return 200;\n }\n return Math.min(500, Math.max(1, Math.floor(value ?? 200)));\n}\n\nfunction nullableString(value: unknown): string | null {\n return value === null || value === undefined ? null : String(value);\n}\n\nfunction stringifyOptionalJson(value: unknown): string | null {\n return value === null || value === undefined ? null : JSON.stringify(value);\n}\n\nfunction parseOptionalJson(value: unknown): unknown | null {\n if (value === null || value === undefined || value === \"\") {\n return null;\n }\n if (typeof value !== \"string\") {\n return value;\n }\n return JSON.parse(value);\n}\n\nfunction parseObject(value: unknown): Record<string, unknown> | null {\n const parsed = parseOptionalJson(value);\n return typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n}\n\nfunction parseMentions(value: unknown): ReviewMention[] {\n const parsed = parseOptionalJson(value);\n return Array.isArray(parsed) ? (parsed as ReviewMention[]) : [];\n}\n\nfunction normalizeVisibility(value: unknown): Visibility {\n return value === \"org\" || value === \"public\" ? value : \"private\";\n}\n\nfunction normalizeKind(value: unknown): ReviewCommentKind {\n return value === \"annotation\" ||\n value === \"correction\" ||\n value === \"question\" ||\n value === \"decision\" ||\n value === \"review\"\n ? value\n : \"comment\";\n}\n\nfunction normalizeCommentStatus(value: unknown): ReviewCommentStatus {\n return value === \"resolved\" || value === \"deleted\" ? value : \"open\";\n}\n\nfunction normalizeReviewStatus(value: unknown): ReviewStatus {\n return value === \"in_review\" ||\n value === \"approved\" ||\n value === \"changes_requested\"\n ? value\n : \"draft\";\n}\n\nfunction normalizeActor(value: unknown): ReviewActorKind {\n return value === \"agent\" || value === \"import\" || value === \"system\"\n ? value\n : \"human\";\n}\n\nfunction normalizeResolutionTarget(\n value: unknown,\n): ReviewResolutionTarget | null {\n return value === \"agent\" || value === \"human\" ? value : null;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/review/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { getDbExec, isPostgres, type DbExec } from \"../db/client.js\";\nimport { ensureIndexExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport type { Visibility } from \"../sharing/schema.js\";\nimport type {\n ReviewActorKind,\n ReviewComment,\n ReviewCommentKind,\n ReviewCommentStatus,\n ReviewMention,\n ReviewResolutionTarget,\n ReviewScope,\n ReviewStatus,\n ReviewStatusEntry,\n} from \"./types.js\";\n\nlet reviewTablesInitPromise: Promise<void> | undefined;\n\nexport interface InsertReviewCommentInput {\n resourceType: string;\n resourceId: string;\n threadId?: string | null;\n parentCommentId?: string | null;\n targetId?: string | null;\n kind?: ReviewCommentKind;\n anchor?: unknown | null;\n body: string;\n authorEmail?: string | null;\n authorName?: string | null;\n createdBy?: ReviewActorKind;\n resolutionTarget?: ReviewResolutionTarget | null;\n mentions?: ReviewMention[];\n ownerEmail?: string | null;\n orgId?: string | null;\n visibility?: Visibility | null;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface QueryReviewCommentsInput {\n resourceType: string;\n resourceId: string;\n scope: ReviewScope;\n bypassScope?: boolean;\n includeResolved?: boolean;\n includeDeleted?: boolean;\n targetId?: string | null;\n rootOnly?: boolean;\n resolutionTargets?: readonly (ReviewResolutionTarget | null)[];\n unconsumedOnly?: boolean;\n limit?: number;\n}\n\nexport interface GetReviewThreadSummaryInput {\n resourceType: string;\n resourceId: string;\n scope: ReviewScope;\n bypassScope?: boolean;\n targetId?: string | null;\n}\n\nexport interface ReviewThreadSummary {\n openCount: number;\n agentQueueCount: number;\n}\n\nexport interface UpsertReviewStatusInput {\n resourceType: string;\n resourceId: string;\n status: ReviewStatus;\n note?: string | null;\n updatedBy?: string | null;\n ownerEmail?: string | null;\n orgId?: string | null;\n visibility?: Visibility | null;\n metadata?: Record<string, unknown> | null;\n}\n\nexport async function ensureReviewTables(): Promise<void> {\n if (!reviewTablesInitPromise) {\n reviewTablesInitPromise = (async () => {\n const client = getDbExec();\n const createCommentsSql = `CREATE TABLE IF NOT EXISTS agent_review_comments (\n id TEXT PRIMARY KEY,\n resource_type TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n thread_id TEXT NOT NULL,\n parent_comment_id TEXT,\n target_id TEXT,\n kind TEXT NOT NULL DEFAULT 'comment',\n status TEXT NOT NULL DEFAULT 'open',\n anchor_json TEXT,\n body TEXT NOT NULL,\n author_email TEXT,\n author_name TEXT,\n created_by TEXT NOT NULL DEFAULT 'human',\n resolution_target TEXT,\n mentions_json TEXT,\n owner_email TEXT,\n org_id TEXT,\n visibility TEXT NOT NULL DEFAULT 'private',\n resolved_by TEXT,\n resolved_at TEXT,\n consumed_at TEXT,\n deleted_by TEXT,\n deleted_at TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n metadata_json TEXT\n )`;\n const createStatusesSql = `CREATE TABLE IF NOT EXISTS agent_review_statuses (\n id TEXT PRIMARY KEY,\n resource_type TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n status TEXT NOT NULL,\n note TEXT,\n updated_by TEXT,\n updated_at TEXT NOT NULL,\n owner_email TEXT,\n org_id TEXT,\n visibility TEXT NOT NULL DEFAULT 'private',\n metadata_json TEXT\n )`;\n const indexes = [\n `CREATE INDEX IF NOT EXISTS idx_agent_review_comments_resource\n ON agent_review_comments (resource_type, resource_id, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_review_comments_thread\n ON agent_review_comments (thread_id, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_review_comments_owner\n ON agent_review_comments (owner_email, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_review_comments_org\n ON agent_review_comments (org_id, created_at)`,\n `CREATE INDEX IF NOT EXISTS idx_agent_review_comments_queue\n ON agent_review_comments (\n resource_type,\n resource_id,\n parent_comment_id,\n resolution_target,\n consumed_at,\n created_at\n )`,\n `CREATE INDEX IF NOT EXISTS idx_agent_review_statuses_resource\n ON agent_review_statuses (resource_type, resource_id)`,\n ];\n\n if (isPostgres()) {\n await ensureTableExists(\"agent_review_comments\", createCommentsSql);\n await ensureTableExists(\"agent_review_statuses\", createStatusesSql);\n await ensureIndexExists(\n \"idx_agent_review_comments_resource\",\n indexes[0],\n );\n await ensureIndexExists(\"idx_agent_review_comments_thread\", indexes[1]);\n await ensureIndexExists(\"idx_agent_review_comments_owner\", indexes[2]);\n await ensureIndexExists(\"idx_agent_review_comments_org\", indexes[3]);\n await ensureIndexExists(\"idx_agent_review_comments_queue\", indexes[4]);\n await ensureIndexExists(\n \"idx_agent_review_statuses_resource\",\n indexes[5],\n );\n } else {\n await client.execute(createCommentsSql);\n await client.execute(createStatusesSql);\n for (const indexSql of indexes) {\n await client.execute(indexSql);\n }\n }\n })();\n }\n\n await reviewTablesInitPromise;\n}\n\nexport async function insertReviewComment(\n input: InsertReviewCommentInput,\n): Promise<ReviewComment> {\n await ensureReviewTables();\n return insertReviewCommentWithClient(input, getDbExec());\n}\n\nexport async function insertReviewReply(\n input: InsertReviewCommentInput & {\n threadId: string;\n parentCommentId: string;\n },\n routeTarget: ReviewResolutionTarget | null,\n resource: { resourceType: string; resourceId: string },\n): Promise<ReviewComment> {\n await ensureReviewTables();\n const client = getDbExec();\n const insertAndRoute = async (tx: DbExec) => {\n if (routeTarget) {\n const routedCount = await routeReviewThreadWithClient(\n tx,\n input.threadId,\n routeTarget,\n resource,\n );\n if (routedCount < 1) {\n throw new Error(\"Open review thread not found\");\n }\n }\n return insertReviewCommentWithClient(input, tx);\n };\n if (client.transaction) return client.transaction(insertAndRoute);\n\n const reply = await insertReviewCommentWithClient(input, client);\n if (!routeTarget) return reply;\n try {\n const routedCount = await routeReviewThreadWithClient(\n client,\n input.threadId,\n routeTarget,\n resource,\n );\n if (routedCount < 1) throw new Error(\"Open review thread not found\");\n return reply;\n } catch (error) {\n await client.execute({\n sql: `DELETE FROM agent_review_comments\n WHERE id = ? AND resource_type = ? AND resource_id = ?`,\n args: [reply.id, resource.resourceType, resource.resourceId],\n });\n throw error;\n }\n}\n\nasync function insertReviewCommentWithClient(\n input: InsertReviewCommentInput,\n client: DbExec,\n): Promise<ReviewComment> {\n const id = createReviewId(\"comment\");\n const now = new Date().toISOString();\n const comment: ReviewComment = {\n id,\n resourceType: input.resourceType,\n resourceId: input.resourceId,\n threadId: input.threadId ?? id,\n parentCommentId: input.parentCommentId ?? null,\n targetId: input.targetId ?? null,\n kind: input.kind ?? \"comment\",\n status: \"open\",\n anchor: input.anchor ?? null,\n body: input.body,\n authorEmail: input.authorEmail ?? null,\n authorName: input.authorName ?? null,\n createdBy: input.createdBy ?? \"human\",\n resolutionTarget: input.resolutionTarget ?? null,\n mentions: input.mentions ?? [],\n ownerEmail: input.ownerEmail ?? input.authorEmail ?? null,\n orgId: input.orgId ?? null,\n visibility:\n input.visibility === \"org\" || input.visibility === \"public\"\n ? input.visibility\n : \"private\",\n resolvedBy: null,\n resolvedAt: null,\n consumedAt: null,\n deletedBy: null,\n deletedAt: null,\n createdAt: now,\n updatedAt: now,\n metadata: input.metadata ?? null,\n resolutionNote:\n typeof input.metadata?.resolutionNote === \"string\"\n ? input.metadata.resolutionNote\n : null,\n };\n\n await client.execute({\n sql: `INSERT INTO agent_review_comments (\n id,\n resource_type,\n resource_id,\n thread_id,\n parent_comment_id,\n target_id,\n kind,\n status,\n anchor_json,\n body,\n author_email,\n author_name,\n created_by,\n resolution_target,\n mentions_json,\n owner_email,\n org_id,\n visibility,\n resolved_by,\n resolved_at,\n consumed_at,\n deleted_by,\n deleted_at,\n created_at,\n updated_at,\n metadata_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n comment.id,\n comment.resourceType,\n comment.resourceId,\n comment.threadId,\n comment.parentCommentId,\n comment.targetId,\n comment.kind,\n comment.status,\n stringifyOptionalJson(comment.anchor),\n comment.body,\n comment.authorEmail,\n comment.authorName,\n comment.createdBy,\n comment.resolutionTarget,\n stringifyOptionalJson(comment.mentions),\n comment.ownerEmail,\n comment.orgId,\n comment.visibility,\n comment.resolvedBy,\n comment.resolvedAt,\n comment.consumedAt,\n comment.deletedBy,\n comment.deletedAt,\n comment.createdAt,\n comment.updatedAt,\n stringifyOptionalJson(comment.metadata),\n ],\n });\n\n return comment;\n}\n\nexport async function queryReviewComments(\n input: QueryReviewCommentsInput,\n): Promise<ReviewComment[]> {\n await ensureReviewTables();\n const client = getDbExec();\n const { clause, params } = input.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedReviewClause(input.scope);\n const filters = [\"resource_type = ?\", \"resource_id = ?\", clause];\n const filterParams: unknown[] = [\n input.resourceType,\n input.resourceId,\n ...params,\n ];\n if (!input.includeDeleted) {\n filters.push(\"deleted_at IS NULL\");\n filters.push(\"status <> 'deleted'\");\n }\n if (!input.includeResolved) {\n filters.push(\"status <> 'resolved'\");\n }\n if (input.targetId !== undefined) {\n if (input.targetId === null) {\n filters.push(\"target_id IS NULL\");\n } else {\n filters.push(\"target_id = ?\");\n filterParams.push(input.targetId);\n }\n }\n if (input.rootOnly) {\n filters.push(\"parent_comment_id IS NULL\");\n }\n if (input.unconsumedOnly) {\n filters.push(\"consumed_at IS NULL\");\n }\n if (input.resolutionTargets !== undefined) {\n const targets = Array.from(\n new Set(\n input.resolutionTargets.filter(\n (target): target is ReviewResolutionTarget => target !== null,\n ),\n ),\n );\n const resolutionFilters: string[] = [];\n if (targets.length > 0) {\n resolutionFilters.push(\n `resolution_target IN (${targets.map(() => \"?\").join(\", \")})`,\n );\n filterParams.push(...targets);\n }\n if (input.resolutionTargets.includes(null)) {\n resolutionFilters.push(\"resolution_target IS NULL\");\n }\n filters.push(\n resolutionFilters.length > 0\n ? `(${resolutionFilters.join(\" OR \")})`\n : \"1 = 0\",\n );\n }\n\n const selectSql = input.rootOnly\n ? `SELECT ${commentColumns()}\n FROM (\n SELECT ${commentColumns()},\n ROW_NUMBER() OVER (\n PARTITION BY thread_id\n ORDER BY created_at ASC, id ASC\n ) AS review_thread_rank\n FROM agent_review_comments\n WHERE ${filters.join(\" AND \")}\n ) AS distinct_review_threads\n WHERE review_thread_rank = 1`\n : `SELECT ${commentColumns()}\n FROM agent_review_comments\n WHERE ${filters.join(\" AND \")}`;\n const result = await client.execute({\n sql: `${selectSql}\n ORDER BY created_at ASC${input.rootOnly ? \", id ASC\" : \"\"}\n LIMIT ?`,\n args: [...filterParams, clampLimit(input.limit)],\n });\n return (result.rows ?? []).map(mapCommentRow);\n}\n\nexport async function getReviewThreadSummary(\n input: GetReviewThreadSummaryInput,\n): Promise<ReviewThreadSummary> {\n await ensureReviewTables();\n const { clause, params } = input.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedReviewClause(input.scope);\n const filters = [\n \"resource_type = ?\",\n \"resource_id = ?\",\n clause,\n \"parent_comment_id IS NULL\",\n \"deleted_at IS NULL\",\n \"status = 'open'\",\n ];\n const filterParams: unknown[] = [\n input.resourceType,\n input.resourceId,\n ...params,\n ];\n if (input.targetId !== undefined) {\n if (input.targetId === null) {\n filters.push(\"target_id IS NULL\");\n } else {\n filters.push(\"target_id = ?\");\n filterParams.push(input.targetId);\n }\n }\n const result = await getDbExec().execute({\n sql: `SELECT COUNT(DISTINCT thread_id) AS open_count,\n COUNT(DISTINCT CASE\n WHEN (resolution_target IS NULL OR resolution_target <> 'human')\n AND consumed_at IS NULL\n THEN thread_id\n END) AS agent_queue_count\n FROM agent_review_comments\n WHERE ${filters.join(\" AND \")}`,\n args: filterParams,\n });\n const row = result.rows?.[0];\n return {\n openCount: Number(row?.open_count ?? 0),\n agentQueueCount: Number(row?.agent_queue_count ?? 0),\n };\n}\n\nexport async function getReviewCommentById(\n id: string,\n scope: ReviewScope,\n options: { bypassScope?: boolean } = {},\n): Promise<ReviewComment | null> {\n await ensureReviewTables();\n const client = getDbExec();\n const { clause, params } = options.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedReviewClause(scope);\n const result = await client.execute({\n sql: `SELECT ${commentColumns()}\n FROM agent_review_comments\n WHERE id = ? AND ${clause}\n LIMIT 1`,\n args: [id, ...params],\n });\n const row = result.rows?.[0];\n return row ? mapCommentRow(row) : null;\n}\n\nexport async function getReviewThreadRoot(\n threadId: string,\n resource: { resourceType: string; resourceId: string },\n scope: ReviewScope,\n options: { bypassScope?: boolean } = {},\n): Promise<ReviewComment | null> {\n await ensureReviewTables();\n const { clause, params } = options.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedReviewClause(scope);\n const result = await getDbExec().execute({\n sql: `SELECT ${commentColumns()}\n FROM agent_review_comments\n WHERE thread_id = ?\n AND resource_type = ?\n AND resource_id = ?\n AND parent_comment_id IS NULL\n AND ${clause}\n ORDER BY created_at ASC, id ASC\n LIMIT 1`,\n args: [threadId, resource.resourceType, resource.resourceId, ...params],\n });\n const row = result.rows?.[0];\n return row ? mapCommentRow(row) : null;\n}\n\nexport async function resolveReviewThread(\n threadId: string,\n resolvedBy?: string | null,\n resource?: { resourceType: string; resourceId: string },\n resolutionNote?: string,\n): Promise<number> {\n await ensureReviewTables();\n const client = getDbExec();\n const resolve = (tx: DbExec) =>\n resolveReviewThreadWithClient(\n tx,\n threadId,\n resolvedBy,\n resource,\n resolutionNote,\n );\n return client.transaction ? client.transaction(resolve) : resolve(client);\n}\n\nasync function resolveReviewThreadWithClient(\n client: DbExec,\n threadId: string,\n resolvedBy?: string | null,\n resource?: { resourceType: string; resourceId: string },\n resolutionNote?: string,\n): Promise<number> {\n const now = new Date().toISOString();\n const resourceClause = resource\n ? \"AND resource_type = ? AND resource_id = ?\"\n : \"\";\n let rootMetadata: Record<string, unknown> | null = null;\n if (resolutionNote !== undefined) {\n const root = await client.execute({\n sql: `SELECT metadata_json\n FROM agent_review_comments\n WHERE thread_id = ?\n AND parent_comment_id IS NULL\n AND deleted_at IS NULL\n ${resourceClause}\n ORDER BY created_at ASC, id ASC\n LIMIT 1`,\n args: [\n threadId,\n ...(resource ? [resource.resourceType, resource.resourceId] : []),\n ],\n });\n if (!root.rows?.[0]) {\n return 0;\n }\n rootMetadata = {\n ...(parseObject(root.rows[0].metadata_json) ?? {}),\n resolutionNote,\n };\n }\n\n const metadataAssignment =\n resolutionNote === undefined\n ? \"\"\n : \", metadata_json = CASE WHEN parent_comment_id IS NULL THEN ? ELSE metadata_json END\";\n const result = await client.execute({\n sql: `UPDATE agent_review_comments\n SET status = 'resolved',\n resolved_by = ?,\n resolved_at = ?,\n updated_at = ?\n ${metadataAssignment}\n WHERE thread_id = ? AND deleted_at IS NULL ${resourceClause}`,\n args: [\n resolvedBy ?? null,\n now,\n now,\n ...(resolutionNote === undefined\n ? []\n : [stringifyOptionalJson(rootMetadata)]),\n threadId,\n ...(resource ? [resource.resourceType, resource.resourceId] : []),\n ],\n });\n return result.rowsAffected ?? 0;\n}\n\nexport async function routeReviewThread(\n threadId: string,\n resolutionTarget: ReviewResolutionTarget,\n resource: { resourceType: string; resourceId: string },\n): Promise<number> {\n await ensureReviewTables();\n return routeReviewThreadWithClient(\n getDbExec(),\n threadId,\n resolutionTarget,\n resource,\n );\n}\n\nasync function routeReviewThreadWithClient(\n client: DbExec,\n threadId: string,\n resolutionTarget: ReviewResolutionTarget,\n resource: { resourceType: string; resourceId: string },\n): Promise<number> {\n const now = new Date().toISOString();\n const result = await client.execute({\n sql: `UPDATE agent_review_comments\n SET resolution_target = ?,\n consumed_at = CASE WHEN ? = 'agent' THEN NULL ELSE consumed_at END,\n updated_at = ?\n WHERE thread_id = ?\n AND resource_type = ?\n AND resource_id = ?\n AND parent_comment_id IS NULL\n AND status = 'open'\n AND deleted_at IS NULL`,\n args: [\n resolutionTarget,\n resolutionTarget,\n now,\n threadId,\n resource.resourceType,\n resource.resourceId,\n ],\n });\n return result.rowsAffected ?? 0;\n}\n\nexport async function sendReviewThreadToAgent(\n threadId: string,\n resource: { resourceType: string; resourceId: string },\n): Promise<number> {\n return routeReviewThread(threadId, \"agent\", resource);\n}\n\nexport async function deleteReviewComment(\n id: string,\n deletedBy?: string | null,\n): Promise<number> {\n await ensureReviewTables();\n const now = new Date().toISOString();\n const result = await getDbExec().execute({\n sql: `UPDATE agent_review_comments\n SET status = 'deleted',\n deleted_by = ?,\n deleted_at = ?,\n updated_at = ?\n WHERE id = ?`,\n args: [deletedBy ?? null, now, now, id],\n });\n return result.rowsAffected ?? 0;\n}\n\nexport async function consumeReviewFeedback(\n ids: string[],\n consumedAt = new Date().toISOString(),\n resource?: { resourceType: string; resourceId: string },\n): Promise<number> {\n if (!ids.length) {\n return 0;\n }\n await ensureReviewTables();\n const placeholders = ids.map(() => \"?\").join(\", \");\n const resourceClause = resource\n ? \"AND resource_type = ? AND resource_id = ?\"\n : \"\";\n const result = await getDbExec().execute({\n sql: `UPDATE agent_review_comments\n SET consumed_at = ?,\n updated_at = ?\n WHERE id IN (${placeholders}) ${resourceClause}`,\n args: [\n consumedAt,\n consumedAt,\n ...ids,\n ...(resource ? [resource.resourceType, resource.resourceId] : []),\n ],\n });\n return result.rowsAffected ?? 0;\n}\n\nexport async function upsertReviewStatus(\n input: UpsertReviewStatusInput,\n): Promise<ReviewStatusEntry> {\n await ensureReviewTables();\n const client = getDbExec();\n const id = statusId(input.resourceType, input.resourceId);\n const now = new Date().toISOString();\n const existing = await client.execute({\n sql: \"SELECT id FROM agent_review_statuses WHERE id = ? LIMIT 1\",\n args: [id],\n });\n const entry: ReviewStatusEntry = {\n id,\n resourceType: input.resourceType,\n resourceId: input.resourceId,\n status: input.status,\n note: input.note ?? null,\n updatedBy: input.updatedBy ?? null,\n updatedAt: now,\n ownerEmail: input.ownerEmail ?? input.updatedBy ?? null,\n orgId: input.orgId ?? null,\n visibility:\n input.visibility === \"org\" || input.visibility === \"public\"\n ? input.visibility\n : \"private\",\n metadata: input.metadata ?? null,\n };\n\n if (existing.rows?.length) {\n await client.execute({\n sql: `UPDATE agent_review_statuses\n SET status = ?,\n note = ?,\n updated_by = ?,\n updated_at = ?,\n owner_email = ?,\n org_id = ?,\n visibility = ?,\n metadata_json = ?\n WHERE id = ?`,\n args: [\n entry.status,\n entry.note,\n entry.updatedBy,\n entry.updatedAt,\n entry.ownerEmail,\n entry.orgId,\n entry.visibility,\n stringifyOptionalJson(entry.metadata),\n entry.id,\n ],\n });\n } else {\n await client.execute({\n sql: `INSERT INTO agent_review_statuses (\n id,\n resource_type,\n resource_id,\n status,\n note,\n updated_by,\n updated_at,\n owner_email,\n org_id,\n visibility,\n metadata_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n entry.id,\n entry.resourceType,\n entry.resourceId,\n entry.status,\n entry.note,\n entry.updatedBy,\n entry.updatedAt,\n entry.ownerEmail,\n entry.orgId,\n entry.visibility,\n stringifyOptionalJson(entry.metadata),\n ],\n });\n }\n\n return entry;\n}\n\nexport async function getReviewStatus(\n resourceType: string,\n resourceId: string,\n scope: ReviewScope,\n options: { bypassScope?: boolean } = {},\n): Promise<ReviewStatusEntry | null> {\n await ensureReviewTables();\n const client = getDbExec();\n const { clause, params } = options.bypassScope\n ? { clause: \"1 = 1\", params: [] as unknown[] }\n : scopedReviewClause(scope);\n const result = await client.execute({\n sql: `SELECT ${statusColumns()}\n FROM agent_review_statuses\n WHERE resource_type = ? AND resource_id = ? AND ${clause}\n LIMIT 1`,\n args: [resourceType, resourceId, ...params],\n });\n const row = result.rows?.[0];\n return row ? mapStatusRow(row) : null;\n}\n\nexport function __resetReviewInitForTests(): void {\n reviewTablesInitPromise = undefined;\n}\n\nfunction commentColumns(): string {\n return [\n \"id\",\n \"resource_type\",\n \"resource_id\",\n \"thread_id\",\n \"parent_comment_id\",\n \"target_id\",\n \"kind\",\n \"status\",\n \"anchor_json\",\n \"body\",\n \"author_email\",\n \"author_name\",\n \"created_by\",\n \"resolution_target\",\n \"mentions_json\",\n \"owner_email\",\n \"org_id\",\n \"visibility\",\n \"resolved_by\",\n \"resolved_at\",\n \"consumed_at\",\n \"deleted_by\",\n \"deleted_at\",\n \"created_at\",\n \"updated_at\",\n \"metadata_json\",\n ].join(\", \");\n}\n\nfunction statusColumns(): string {\n return [\n \"id\",\n \"resource_type\",\n \"resource_id\",\n \"status\",\n \"note\",\n \"updated_by\",\n \"updated_at\",\n \"owner_email\",\n \"org_id\",\n \"visibility\",\n \"metadata_json\",\n ].join(\", \");\n}\n\nfunction scopedReviewClause(scope: ReviewScope): {\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 return { clause: `(${parts.join(\" OR \")})`, params };\n}\n\nfunction mapCommentRow(row: Record<string, unknown>): ReviewComment {\n const metadata = parseObject(row.metadata_json);\n return {\n id: String(row.id),\n resourceType: String(row.resource_type),\n resourceId: String(row.resource_id),\n threadId: String(row.thread_id),\n parentCommentId: nullableString(row.parent_comment_id),\n targetId: nullableString(row.target_id),\n kind: normalizeKind(row.kind),\n status: normalizeCommentStatus(row.status),\n anchor: parseOptionalJson(row.anchor_json),\n body: String(row.body),\n authorEmail: nullableString(row.author_email),\n authorName: nullableString(row.author_name),\n createdBy: normalizeActor(row.created_by),\n resolutionTarget: normalizeResolutionTarget(row.resolution_target),\n mentions: parseMentions(row.mentions_json),\n ownerEmail: nullableString(row.owner_email),\n orgId: nullableString(row.org_id),\n visibility: normalizeVisibility(row.visibility),\n resolvedBy: nullableString(row.resolved_by),\n resolvedAt: nullableString(row.resolved_at),\n consumedAt: nullableString(row.consumed_at),\n deletedBy: nullableString(row.deleted_by),\n deletedAt: nullableString(row.deleted_at),\n createdAt: String(row.created_at),\n updatedAt: String(row.updated_at),\n metadata,\n resolutionNote:\n typeof metadata?.resolutionNote === \"string\"\n ? metadata.resolutionNote\n : null,\n };\n}\n\nfunction mapStatusRow(row: Record<string, unknown>): ReviewStatusEntry {\n return {\n id: String(row.id),\n resourceType: String(row.resource_type),\n resourceId: String(row.resource_id),\n status: normalizeReviewStatus(row.status),\n note: nullableString(row.note),\n updatedBy: nullableString(row.updated_by),\n updatedAt: String(row.updated_at),\n ownerEmail: nullableString(row.owner_email),\n orgId: nullableString(row.org_id),\n visibility: normalizeVisibility(row.visibility),\n metadata: parseObject(row.metadata_json),\n };\n}\n\nfunction createReviewId(prefix: string): string {\n return `rev_${prefix}_${globalThis.crypto.randomUUID()}`;\n}\n\nfunction statusId(resourceType: string, resourceId: string): string {\n return `${resourceType}:${resourceId}`;\n}\n\nfunction clampLimit(value: number | undefined): number {\n if (!Number.isFinite(value)) {\n return 200;\n }\n return Math.min(500, Math.max(1, Math.floor(value ?? 200)));\n}\n\nfunction nullableString(value: unknown): string | null {\n return value === null || value === undefined ? null : String(value);\n}\n\nfunction stringifyOptionalJson(value: unknown): string | null {\n return value === null || value === undefined ? null : JSON.stringify(value);\n}\n\nfunction parseOptionalJson(value: unknown): unknown | null {\n if (value === null || value === undefined || value === \"\") {\n return null;\n }\n if (typeof value !== \"string\") {\n return value;\n }\n return JSON.parse(value);\n}\n\nfunction parseObject(value: unknown): Record<string, unknown> | null {\n const parsed = parseOptionalJson(value);\n return typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n}\n\nfunction parseMentions(value: unknown): ReviewMention[] {\n const parsed = parseOptionalJson(value);\n return Array.isArray(parsed) ? (parsed as ReviewMention[]) : [];\n}\n\nfunction normalizeVisibility(value: unknown): Visibility {\n return value === \"org\" || value === \"public\" ? value : \"private\";\n}\n\nfunction normalizeKind(value: unknown): ReviewCommentKind {\n return value === \"annotation\" ||\n value === \"correction\" ||\n value === \"question\" ||\n value === \"decision\" ||\n value === \"review\"\n ? value\n : \"comment\";\n}\n\nfunction normalizeCommentStatus(value: unknown): ReviewCommentStatus {\n return value === \"resolved\" || value === \"deleted\" ? value : \"open\";\n}\n\nfunction normalizeReviewStatus(value: unknown): ReviewStatus {\n return value === \"in_review\" ||\n value === \"approved\" ||\n value === \"changes_requested\"\n ? value\n : \"draft\";\n}\n\nfunction normalizeActor(value: unknown): ReviewActorKind {\n return value === \"agent\" || value === \"import\" || value === \"system\"\n ? value\n : \"human\";\n}\n\nfunction normalizeResolutionTarget(\n value: unknown,\n): ReviewResolutionTarget | null {\n return value === \"agent\" || value === \"human\" ? value : null;\n}\n"]}
|
package/dist/review/types.d.ts
CHANGED
|
@@ -56,6 +56,10 @@ export interface ReviewComment {
|
|
|
56
56
|
createdAt: string;
|
|
57
57
|
updatedAt: string;
|
|
58
58
|
metadata: Record<string, unknown> | null;
|
|
59
|
+
/** Persisted on the root comment's metadata when a thread is resolved. */
|
|
60
|
+
resolutionNote?: string | null;
|
|
61
|
+
/** Caller-specific capability computed by list-review-comments. */
|
|
62
|
+
canDelete?: boolean;
|
|
59
63
|
}
|
|
60
64
|
export interface ReviewStatusEntry {
|
|
61
65
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/review/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/review/types.ts"],"names":[],"mappings":"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"}
|
package/dist/review/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/review/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Visibility } from \"../sharing/schema.js\";\n\nexport type ReviewResourceRole = \"viewer\" | \"editor\" | \"admin\" | \"owner\";\nexport type ReviewCommentKind =\n | \"comment\"\n | \"annotation\"\n | \"correction\"\n | \"question\"\n | \"decision\"\n | \"review\";\nexport type ReviewCommentStatus = \"open\" | \"resolved\" | \"deleted\";\nexport type ReviewResolutionTarget = \"agent\" | \"human\";\nexport type ReviewStatus =\n | \"draft\"\n | \"in_review\"\n | \"approved\"\n | \"changes_requested\";\nexport type ReviewActorKind = \"human\" | \"agent\" | \"import\" | \"system\";\n\nexport interface ReviewResourceAccess {\n role: ReviewResourceRole;\n ownerEmail?: string | null;\n orgId?: string | null;\n visibility?: Visibility | null;\n resource?: unknown;\n}\n\nexport interface ReviewResourceContext {\n userEmail?: string | null;\n orgId?: string | null;\n caller?: string | null;\n request?: unknown;\n [key: string]: unknown;\n}\n\nexport interface ReviewableResourceRegistration {\n type: string;\n displayName?: string;\n resolveAccess?: (\n resourceId: string,\n ctx?: ReviewResourceContext,\n ) => Promise<ReviewResourceAccess | null> | ReviewResourceAccess | null;\n}\n\nexport interface ReviewMention {\n label: string;\n email?: string | null;\n id?: string | null;\n}\n\nexport interface ReviewComment {\n id: string;\n resourceType: string;\n resourceId: string;\n threadId: string;\n parentCommentId: string | null;\n targetId: string | null;\n kind: ReviewCommentKind;\n status: ReviewCommentStatus;\n anchor: unknown | null;\n body: string;\n authorEmail: string | null;\n authorName: string | null;\n createdBy: ReviewActorKind;\n resolutionTarget: ReviewResolutionTarget | null;\n mentions: ReviewMention[];\n ownerEmail: string | null;\n orgId: string | null;\n visibility: Visibility;\n resolvedBy: string | null;\n resolvedAt: string | null;\n consumedAt: string | null;\n deletedBy: string | null;\n deletedAt: string | null;\n createdAt: string;\n updatedAt: string;\n metadata: Record<string, unknown> | null;\n}\n\nexport interface ReviewStatusEntry {\n id: string;\n resourceType: string;\n resourceId: string;\n status: ReviewStatus;\n note: string | null;\n updatedBy: string | null;\n updatedAt: string;\n ownerEmail: string | null;\n orgId: string | null;\n visibility: Visibility;\n metadata: Record<string, unknown> | null;\n}\n\nexport interface ReviewScope {\n userEmail?: string | null;\n orgId?: string | null;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/review/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Visibility } from \"../sharing/schema.js\";\n\nexport type ReviewResourceRole = \"viewer\" | \"editor\" | \"admin\" | \"owner\";\nexport type ReviewCommentKind =\n | \"comment\"\n | \"annotation\"\n | \"correction\"\n | \"question\"\n | \"decision\"\n | \"review\";\nexport type ReviewCommentStatus = \"open\" | \"resolved\" | \"deleted\";\nexport type ReviewResolutionTarget = \"agent\" | \"human\";\nexport type ReviewStatus =\n | \"draft\"\n | \"in_review\"\n | \"approved\"\n | \"changes_requested\";\nexport type ReviewActorKind = \"human\" | \"agent\" | \"import\" | \"system\";\n\nexport interface ReviewResourceAccess {\n role: ReviewResourceRole;\n ownerEmail?: string | null;\n orgId?: string | null;\n visibility?: Visibility | null;\n resource?: unknown;\n}\n\nexport interface ReviewResourceContext {\n userEmail?: string | null;\n orgId?: string | null;\n caller?: string | null;\n request?: unknown;\n [key: string]: unknown;\n}\n\nexport interface ReviewableResourceRegistration {\n type: string;\n displayName?: string;\n resolveAccess?: (\n resourceId: string,\n ctx?: ReviewResourceContext,\n ) => Promise<ReviewResourceAccess | null> | ReviewResourceAccess | null;\n}\n\nexport interface ReviewMention {\n label: string;\n email?: string | null;\n id?: string | null;\n}\n\nexport interface ReviewComment {\n id: string;\n resourceType: string;\n resourceId: string;\n threadId: string;\n parentCommentId: string | null;\n targetId: string | null;\n kind: ReviewCommentKind;\n status: ReviewCommentStatus;\n anchor: unknown | null;\n body: string;\n authorEmail: string | null;\n authorName: string | null;\n createdBy: ReviewActorKind;\n resolutionTarget: ReviewResolutionTarget | null;\n mentions: ReviewMention[];\n ownerEmail: string | null;\n orgId: string | null;\n visibility: Visibility;\n resolvedBy: string | null;\n resolvedAt: string | null;\n consumedAt: string | null;\n deletedBy: string | null;\n deletedAt: string | null;\n createdAt: string;\n updatedAt: string;\n metadata: Record<string, unknown> | null;\n /** Persisted on the root comment's metadata when a thread is resolved. */\n resolutionNote?: string | null;\n /** Caller-specific capability computed by list-review-comments. */\n canDelete?: boolean;\n}\n\nexport interface ReviewStatusEntry {\n id: string;\n resourceType: string;\n resourceId: string;\n status: ReviewStatus;\n note: string | null;\n updatedBy: string | null;\n updatedAt: string;\n ownerEmail: string | null;\n orgId: string | null;\n visibility: Visibility;\n metadata: Record<string, unknown> | null;\n}\n\nexport interface ReviewScope {\n userEmail?: string | null;\n orgId?: string | null;\n}\n"]}
|
package/dist/secrets/crypto.d.ts
CHANGED
|
@@ -14,10 +14,15 @@
|
|
|
14
14
|
* `<APP_NAME>_SECRETS_ENCRYPTION_KEY` when set, then `SECRETS_ENCRYPTION_KEY`,
|
|
15
15
|
* then `BETTER_AUTH_SECRET`. The app-scoped key lets a local multi-app
|
|
16
16
|
* workspace read one app's encrypted production data without replacing the
|
|
17
|
-
* shared local auth secret.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* shared local auth secret. Hosted workspace deploys (`AGENT_NATIVE_WORKSPACE`)
|
|
18
|
+
* typically set none of those literal env vars per app; in that case the
|
|
19
|
+
* shared-key variant falls back further to material derived from the
|
|
20
|
+
* workspace-wide `A2A_SECRET` (see `getWorkspaceA2ADerivedSecret`), so sibling
|
|
21
|
+
* apps in the same workspace still land on the same shared key without any
|
|
22
|
+
* extra configuration. In production we refuse to start without configured
|
|
23
|
+
* key material — a CWD-derived fallback would be effectively static (e.g.
|
|
24
|
+
* `/var/task` on Lambda), so anyone with read access to the DB could decrypt
|
|
25
|
+
* every secret.
|
|
21
26
|
*
|
|
22
27
|
* Encrypted values are tagged `v1:<iv-hex>:<ct-hex>:<tag-hex>`. The `v1:` prefix
|
|
23
28
|
* lets readers distinguish ciphertext from legacy plaintext during migration.
|
|
@@ -32,9 +37,12 @@ export declare function getSecretEncryptionKey(): Buffer;
|
|
|
32
37
|
* Derive the preferred workspace-shared key used by `app_secrets` rows.
|
|
33
38
|
* Unlike generic column-level encryption, workspace vault data should decrypt
|
|
34
39
|
* in sibling apps, so `SECRETS_ENCRYPTION_KEY` / `BETTER_AUTH_SECRET` take
|
|
35
|
-
* precedence.
|
|
36
|
-
*
|
|
37
|
-
*
|
|
40
|
+
* precedence. Hosted workspace deploys (`AGENT_NATIVE_WORKSPACE`) that set
|
|
41
|
+
* neither literal var still get stable shared material derived from the
|
|
42
|
+
* workspace-wide `A2A_SECRET` before falling further back. The app-scoped key
|
|
43
|
+
* remains a compatibility fallback for deployments that have not configured
|
|
44
|
+
* shared material yet; once the shared key is configured, writes use it and
|
|
45
|
+
* reads still fall back to old rows.
|
|
38
46
|
*/
|
|
39
47
|
export declare function getSharedSecretEncryptionKey(): Buffer;
|
|
40
48
|
/** Whether this deployment has stable workspace-shared key material. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/secrets/crypto.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/secrets/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAqFH;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAkB/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CAUrD;AAED,wEAAwE;AACxE,wBAAgB,oCAAoC,IAAI,OAAO,CAE9D;AAiCD,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,sDAAsD;AACtD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,sDAAsD;AACtD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAElE;AAUD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEtE"}
|
package/dist/secrets/crypto.js
CHANGED
|
@@ -14,14 +14,20 @@
|
|
|
14
14
|
* `<APP_NAME>_SECRETS_ENCRYPTION_KEY` when set, then `SECRETS_ENCRYPTION_KEY`,
|
|
15
15
|
* then `BETTER_AUTH_SECRET`. The app-scoped key lets a local multi-app
|
|
16
16
|
* workspace read one app's encrypted production data without replacing the
|
|
17
|
-
* shared local auth secret.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* shared local auth secret. Hosted workspace deploys (`AGENT_NATIVE_WORKSPACE`)
|
|
18
|
+
* typically set none of those literal env vars per app; in that case the
|
|
19
|
+
* shared-key variant falls back further to material derived from the
|
|
20
|
+
* workspace-wide `A2A_SECRET` (see `getWorkspaceA2ADerivedSecret`), so sibling
|
|
21
|
+
* apps in the same workspace still land on the same shared key without any
|
|
22
|
+
* extra configuration. In production we refuse to start without configured
|
|
23
|
+
* key material — a CWD-derived fallback would be effectively static (e.g.
|
|
24
|
+
* `/var/task` on Lambda), so anyone with read access to the DB could decrypt
|
|
25
|
+
* every secret.
|
|
21
26
|
*
|
|
22
27
|
* Encrypted values are tagged `v1:<iv-hex>:<ct-hex>:<tag-hex>`. The `v1:` prefix
|
|
23
28
|
* lets readers distinguish ciphertext from legacy plaintext during migration.
|
|
24
29
|
*/
|
|
30
|
+
import { getWorkspaceA2ADerivedSecret } from "../server/derived-secret.js";
|
|
25
31
|
function getNodeCrypto() {
|
|
26
32
|
if (typeof window !== "undefined" ||
|
|
27
33
|
typeof process === "undefined" ||
|
|
@@ -63,7 +69,9 @@ function appScopedEncryptionKey() {
|
|
|
63
69
|
function sharedEncryptionKeyMaterial() {
|
|
64
70
|
if (typeof process === "undefined")
|
|
65
71
|
return undefined;
|
|
66
|
-
return process.env.SECRETS_ENCRYPTION_KEY ||
|
|
72
|
+
return (process.env.SECRETS_ENCRYPTION_KEY ||
|
|
73
|
+
process.env.BETTER_AUTH_SECRET ||
|
|
74
|
+
getWorkspaceA2ADerivedSecret("secrets-encryption"));
|
|
67
75
|
}
|
|
68
76
|
function deriveSecretEncryptionKey(explicit, errorMessage, warningMessage) {
|
|
69
77
|
const { createHash } = requireNodeCrypto();
|
|
@@ -103,14 +111,19 @@ export function getSecretEncryptionKey() {
|
|
|
103
111
|
* Derive the preferred workspace-shared key used by `app_secrets` rows.
|
|
104
112
|
* Unlike generic column-level encryption, workspace vault data should decrypt
|
|
105
113
|
* in sibling apps, so `SECRETS_ENCRYPTION_KEY` / `BETTER_AUTH_SECRET` take
|
|
106
|
-
* precedence.
|
|
107
|
-
*
|
|
108
|
-
*
|
|
114
|
+
* precedence. Hosted workspace deploys (`AGENT_NATIVE_WORKSPACE`) that set
|
|
115
|
+
* neither literal var still get stable shared material derived from the
|
|
116
|
+
* workspace-wide `A2A_SECRET` before falling further back. The app-scoped key
|
|
117
|
+
* remains a compatibility fallback for deployments that have not configured
|
|
118
|
+
* shared material yet; once the shared key is configured, writes use it and
|
|
119
|
+
* reads still fall back to old rows.
|
|
109
120
|
*/
|
|
110
121
|
export function getSharedSecretEncryptionKey() {
|
|
111
122
|
return deriveSecretEncryptionKey(sharedEncryptionKeyMaterial() || appScopedEncryptionKey(), "[agent-native/secrets] Refusing to start in production without encryption key material for workspace secrets. " +
|
|
112
|
-
"Set SECRETS_ENCRYPTION_KEY, BETTER_AUTH_SECRET, or the app-scoped *_SECRETS_ENCRYPTION_KEY in the deploy environment
|
|
113
|
-
"
|
|
123
|
+
"Set SECRETS_ENCRYPTION_KEY, BETTER_AUTH_SECRET, or the app-scoped *_SECRETS_ENCRYPTION_KEY in the deploy environment " +
|
|
124
|
+
"— or, on a hosted workspace deploy, ensure A2A_SECRET is set so shared material can be derived from it.", "[agent-native/secrets] SECRETS_ENCRYPTION_KEY not set — using app-scoped or machine-local fallback for workspace secrets. " +
|
|
125
|
+
"Set SECRETS_ENCRYPTION_KEY or BETTER_AUTH_SECRET in every workspace app so sibling apps share vault rows, " +
|
|
126
|
+
"or rely on A2A_SECRET-derived material on hosted workspace deploys.");
|
|
114
127
|
}
|
|
115
128
|
/** Whether this deployment has stable workspace-shared key material. */
|
|
116
129
|
export function hasSharedSecretEncryptionKeyMaterial() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/secrets/crypto.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared AES-256-GCM encryption for secret values at rest.\n *\n * Used by the framework secrets vault, per-user/per-org credentials\n * (`resolveCredential` / `saveCredential`, stored in `settings`), and other\n * column-level encrypted values. The `app_secrets` storage layer uses the\n * shared-key variant below because workspace-scoped vault rows are readable by\n * sibling apps in the same workspace. When a deployment has not been given\n * shared key material yet, that variant falls back to the app-scoped key so\n * existing single-app deployments can keep reading and writing secrets while\n * they migrate to the shared key.\n *\n * The default encryption key is derived from\n * `<APP_NAME>_SECRETS_ENCRYPTION_KEY` when set, then `SECRETS_ENCRYPTION_KEY`,\n * then `BETTER_AUTH_SECRET`. The app-scoped key lets a local multi-app\n * workspace read one app's encrypted production data without replacing the\n * shared local auth secret. In production we refuse to start without\n * configured key material — a CWD-derived fallback would be effectively\n * static (e.g. `/var/task` on Lambda), so anyone with read access to the DB\n * could decrypt every secret.\n *\n * Encrypted values are tagged `v1:<iv-hex>:<ct-hex>:<tag-hex>`. The `v1:` prefix\n * lets readers distinguish ciphertext from legacy plaintext during migration.\n */\n\ntype NodeCryptoModule = typeof import(\"node:crypto\");\n\nfunction getNodeCrypto(): NodeCryptoModule | undefined {\n if (\n typeof window !== \"undefined\" ||\n typeof process === \"undefined\" ||\n !process.versions?.node ||\n typeof process.getBuiltinModule !== \"function\"\n ) {\n return undefined;\n }\n return process.getBuiltinModule(\"node:crypto\") as\n | NodeCryptoModule\n | undefined;\n}\n\nconst nodeCrypto = getNodeCrypto();\n\nlet _warnedFallback = false;\n\nfunction requireNodeCrypto(): NonNullable<typeof nodeCrypto> {\n if (!nodeCrypto) {\n throw new Error(\n \"[agent-native/secrets] Secret encryption is only available in server/runtime code.\",\n );\n }\n return nodeCrypto;\n}\n\nfunction processNodeEnv(): string | undefined {\n if (typeof process === \"undefined\") return undefined;\n return process.env.NODE_ENV;\n}\n\nfunction processCwd(): string {\n if (typeof process === \"undefined\") return \".\";\n return process.cwd();\n}\n\nfunction appScopedEncryptionKey(): string | undefined {\n if (typeof process === \"undefined\") return undefined;\n const appName = process.env.APP_NAME?.trim() // guard:allow-env-credential — deploy-level app configuration selects the scoped encryption key.\n .toUpperCase()\n .replace(/[^A-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n return appName\n ? process.env[`${appName}_SECRETS_ENCRYPTION_KEY`] // guard:allow-env-credential — deploy-level app encryption material, never a user credential.\n : undefined;\n}\n\nfunction sharedEncryptionKeyMaterial(): string | undefined {\n if (typeof process === \"undefined\") return undefined;\n return process.env.SECRETS_ENCRYPTION_KEY || process.env.BETTER_AUTH_SECRET;\n}\n\nfunction deriveSecretEncryptionKey(\n explicit: string | undefined,\n errorMessage: string,\n warningMessage: string,\n): Buffer {\n const { createHash } = requireNodeCrypto();\n\n if (!explicit) {\n if (processNodeEnv() === \"production\") {\n throw new Error(errorMessage);\n }\n if (!_warnedFallback) {\n _warnedFallback = true;\n // eslint-disable-next-line no-console\n console.warn(warningMessage);\n }\n }\n\n const material = explicit || `agent-native-secrets:${processCwd()}`;\n return createHash(\"sha256\").update(material).digest();\n}\n\n/**\n * Derive the key used by generic encrypted values such as credentials and\n * OAuth tokens. App-specific key material is allowed for these app-local\n * values.\n */\nexport function getSecretEncryptionKey(): Buffer {\n const appName =\n typeof process === \"undefined\"\n ? undefined\n : process.env.APP_NAME?.trim() // guard:allow-env-credential — deploy-level app configuration selects the scoped encryption key.\n .toUpperCase()\n .replace(/[^A-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n return deriveSecretEncryptionKey(\n appScopedEncryptionKey() || sharedEncryptionKeyMaterial(),\n \"[agent-native/secrets] Refusing to start in production without an encryption key. \" +\n `Set ${appName ? `${appName}_SECRETS_ENCRYPTION_KEY, ` : \"\"}SECRETS_ENCRYPTION_KEY, or BETTER_AUTH_SECRET in the deploy environment. ` +\n \"The previous CWD-derived fallback was effectively static (e.g. `/var/task` on Lambda), \" +\n \"which means anyone with read access to the DB could decrypt every secret.\",\n \"[agent-native/secrets] SECRETS_ENCRYPTION_KEY not set — using a machine-local fallback. \" +\n \"Set an app-scoped *_SECRETS_ENCRYPTION_KEY, SECRETS_ENCRYPTION_KEY, or BETTER_AUTH_SECRET for production. \" +\n \"Production deploys without one of these env vars now hard-fail.\",\n );\n}\n\n/**\n * Derive the preferred workspace-shared key used by `app_secrets` rows.\n * Unlike generic column-level encryption, workspace vault data should decrypt\n * in sibling apps, so `SECRETS_ENCRYPTION_KEY` / `BETTER_AUTH_SECRET` take\n * precedence. The app-scoped key remains a compatibility fallback for\n * deployments that have not configured shared material yet; once the shared\n * key is configured, writes use it and reads still fall back to old rows.\n */\nexport function getSharedSecretEncryptionKey(): Buffer {\n return deriveSecretEncryptionKey(\n sharedEncryptionKeyMaterial() || appScopedEncryptionKey(),\n \"[agent-native/secrets] Refusing to start in production without encryption key material for workspace secrets. \" +\n \"Set SECRETS_ENCRYPTION_KEY, BETTER_AUTH_SECRET, or the app-scoped *_SECRETS_ENCRYPTION_KEY in the deploy environment.\",\n \"[agent-native/secrets] SECRETS_ENCRYPTION_KEY not set — using app-scoped or machine-local fallback for workspace secrets. \" +\n \"Set SECRETS_ENCRYPTION_KEY or BETTER_AUTH_SECRET in every workspace app so sibling apps share vault rows.\",\n );\n}\n\n/** Whether this deployment has stable workspace-shared key material. */\nexport function hasSharedSecretEncryptionKeyMaterial(): boolean {\n return Boolean(sharedEncryptionKeyMaterial());\n}\n\nfunction encryptWithKey(plaintext: string, key: Buffer): string {\n const { createCipheriv, randomBytes } = requireNodeCrypto();\n const iv = randomBytes(12);\n const cipher = createCipheriv(\"aes-256-gcm\", key, iv);\n const ct = Buffer.concat([cipher.update(plaintext, \"utf8\"), cipher.final()]);\n const tag = cipher.getAuthTag();\n return `v1:${iv.toString(\"hex\")}:${ct.toString(\"hex\")}:${tag.toString(\"hex\")}`;\n}\n\nfunction decryptWithKey(encrypted: string, key: Buffer): string {\n const { createDecipheriv } = requireNodeCrypto();\n if (!encrypted.startsWith(\"v1:\")) {\n throw new Error(\"Unrecognised secret encoding\");\n }\n const [, ivHex, ctHex, tagHex] = encrypted.split(\":\");\n if (!ivHex || !ctHex || !tagHex) {\n throw new Error(\"Corrupt secret payload\");\n }\n const decipher = createDecipheriv(\n \"aes-256-gcm\",\n key,\n Buffer.from(ivHex, \"hex\"),\n );\n decipher.setAuthTag(Buffer.from(tagHex, \"hex\"));\n const pt = Buffer.concat([\n decipher.update(Buffer.from(ctHex, \"hex\")),\n decipher.final(),\n ]);\n return pt.toString(\"utf8\");\n}\n\n/** Encrypt a plain-text value with the generic app-local key. */\nexport function encryptSecretValue(plaintext: string): string {\n return encryptWithKey(plaintext, getSecretEncryptionKey());\n}\n\n/** Decrypt a value produced by `encryptSecretValue`. Throws on tampering. */\nexport function decryptSecretValue(encrypted: string): string {\n return decryptWithKey(encrypted, getSecretEncryptionKey());\n}\n\n/** Encrypt a workspace-shared `app_secrets` value. */\nexport function encryptSharedSecretValue(plaintext: string): string {\n return encryptWithKey(plaintext, getSharedSecretEncryptionKey());\n}\n\n/** Decrypt a workspace-shared `app_secrets` value. */\nexport function decryptSharedSecretValue(encrypted: string): string {\n return decryptWithKey(encrypted, getSharedSecretEncryptionKey());\n}\n\n/**\n * Strict check for a value produced by `encryptSecretValue`: `v1:` followed by\n * three hex segments. Intentionally strict so a legacy plaintext credential\n * that merely happens to start with `v1:` is treated as plaintext (and read via\n * the legacy fallback) rather than mis-decrypted.\n */\nconst ENCRYPTED_VALUE_RE = /^v1:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+$/;\n\nexport function isEncryptedSecretValue(value: unknown): value is string {\n return typeof value === \"string\" && ENCRYPTED_VALUE_RE.test(value);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/secrets/crypto.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared AES-256-GCM encryption for secret values at rest.\n *\n * Used by the framework secrets vault, per-user/per-org credentials\n * (`resolveCredential` / `saveCredential`, stored in `settings`), and other\n * column-level encrypted values. The `app_secrets` storage layer uses the\n * shared-key variant below because workspace-scoped vault rows are readable by\n * sibling apps in the same workspace. When a deployment has not been given\n * shared key material yet, that variant falls back to the app-scoped key so\n * existing single-app deployments can keep reading and writing secrets while\n * they migrate to the shared key.\n *\n * The default encryption key is derived from\n * `<APP_NAME>_SECRETS_ENCRYPTION_KEY` when set, then `SECRETS_ENCRYPTION_KEY`,\n * then `BETTER_AUTH_SECRET`. The app-scoped key lets a local multi-app\n * workspace read one app's encrypted production data without replacing the\n * shared local auth secret. Hosted workspace deploys (`AGENT_NATIVE_WORKSPACE`)\n * typically set none of those literal env vars per app; in that case the\n * shared-key variant falls back further to material derived from the\n * workspace-wide `A2A_SECRET` (see `getWorkspaceA2ADerivedSecret`), so sibling\n * apps in the same workspace still land on the same shared key without any\n * extra configuration. In production we refuse to start without configured\n * key material — a CWD-derived fallback would be effectively static (e.g.\n * `/var/task` on Lambda), so anyone with read access to the DB could decrypt\n * every secret.\n *\n * Encrypted values are tagged `v1:<iv-hex>:<ct-hex>:<tag-hex>`. The `v1:` prefix\n * lets readers distinguish ciphertext from legacy plaintext during migration.\n */\n\nimport { getWorkspaceA2ADerivedSecret } from \"../server/derived-secret.js\";\n\ntype NodeCryptoModule = typeof import(\"node:crypto\");\n\nfunction getNodeCrypto(): NodeCryptoModule | undefined {\n if (\n typeof window !== \"undefined\" ||\n typeof process === \"undefined\" ||\n !process.versions?.node ||\n typeof process.getBuiltinModule !== \"function\"\n ) {\n return undefined;\n }\n return process.getBuiltinModule(\"node:crypto\") as\n | NodeCryptoModule\n | undefined;\n}\n\nconst nodeCrypto = getNodeCrypto();\n\nlet _warnedFallback = false;\n\nfunction requireNodeCrypto(): NonNullable<typeof nodeCrypto> {\n if (!nodeCrypto) {\n throw new Error(\n \"[agent-native/secrets] Secret encryption is only available in server/runtime code.\",\n );\n }\n return nodeCrypto;\n}\n\nfunction processNodeEnv(): string | undefined {\n if (typeof process === \"undefined\") return undefined;\n return process.env.NODE_ENV;\n}\n\nfunction processCwd(): string {\n if (typeof process === \"undefined\") return \".\";\n return process.cwd();\n}\n\nfunction appScopedEncryptionKey(): string | undefined {\n if (typeof process === \"undefined\") return undefined;\n const appName = process.env.APP_NAME?.trim() // guard:allow-env-credential — deploy-level app configuration selects the scoped encryption key.\n .toUpperCase()\n .replace(/[^A-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n return appName\n ? process.env[`${appName}_SECRETS_ENCRYPTION_KEY`] // guard:allow-env-credential — deploy-level app encryption material, never a user credential.\n : undefined;\n}\n\nfunction sharedEncryptionKeyMaterial(): string | undefined {\n if (typeof process === \"undefined\") return undefined;\n return (\n process.env.SECRETS_ENCRYPTION_KEY ||\n process.env.BETTER_AUTH_SECRET ||\n getWorkspaceA2ADerivedSecret(\"secrets-encryption\")\n );\n}\n\nfunction deriveSecretEncryptionKey(\n explicit: string | undefined,\n errorMessage: string,\n warningMessage: string,\n): Buffer {\n const { createHash } = requireNodeCrypto();\n\n if (!explicit) {\n if (processNodeEnv() === \"production\") {\n throw new Error(errorMessage);\n }\n if (!_warnedFallback) {\n _warnedFallback = true;\n // eslint-disable-next-line no-console\n console.warn(warningMessage);\n }\n }\n\n const material = explicit || `agent-native-secrets:${processCwd()}`;\n return createHash(\"sha256\").update(material).digest();\n}\n\n/**\n * Derive the key used by generic encrypted values such as credentials and\n * OAuth tokens. App-specific key material is allowed for these app-local\n * values.\n */\nexport function getSecretEncryptionKey(): Buffer {\n const appName =\n typeof process === \"undefined\"\n ? undefined\n : process.env.APP_NAME?.trim() // guard:allow-env-credential — deploy-level app configuration selects the scoped encryption key.\n .toUpperCase()\n .replace(/[^A-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n return deriveSecretEncryptionKey(\n appScopedEncryptionKey() || sharedEncryptionKeyMaterial(),\n \"[agent-native/secrets] Refusing to start in production without an encryption key. \" +\n `Set ${appName ? `${appName}_SECRETS_ENCRYPTION_KEY, ` : \"\"}SECRETS_ENCRYPTION_KEY, or BETTER_AUTH_SECRET in the deploy environment. ` +\n \"The previous CWD-derived fallback was effectively static (e.g. `/var/task` on Lambda), \" +\n \"which means anyone with read access to the DB could decrypt every secret.\",\n \"[agent-native/secrets] SECRETS_ENCRYPTION_KEY not set — using a machine-local fallback. \" +\n \"Set an app-scoped *_SECRETS_ENCRYPTION_KEY, SECRETS_ENCRYPTION_KEY, or BETTER_AUTH_SECRET for production. \" +\n \"Production deploys without one of these env vars now hard-fail.\",\n );\n}\n\n/**\n * Derive the preferred workspace-shared key used by `app_secrets` rows.\n * Unlike generic column-level encryption, workspace vault data should decrypt\n * in sibling apps, so `SECRETS_ENCRYPTION_KEY` / `BETTER_AUTH_SECRET` take\n * precedence. Hosted workspace deploys (`AGENT_NATIVE_WORKSPACE`) that set\n * neither literal var still get stable shared material derived from the\n * workspace-wide `A2A_SECRET` before falling further back. The app-scoped key\n * remains a compatibility fallback for deployments that have not configured\n * shared material yet; once the shared key is configured, writes use it and\n * reads still fall back to old rows.\n */\nexport function getSharedSecretEncryptionKey(): Buffer {\n return deriveSecretEncryptionKey(\n sharedEncryptionKeyMaterial() || appScopedEncryptionKey(),\n \"[agent-native/secrets] Refusing to start in production without encryption key material for workspace secrets. \" +\n \"Set SECRETS_ENCRYPTION_KEY, BETTER_AUTH_SECRET, or the app-scoped *_SECRETS_ENCRYPTION_KEY in the deploy environment \" +\n \"— or, on a hosted workspace deploy, ensure A2A_SECRET is set so shared material can be derived from it.\",\n \"[agent-native/secrets] SECRETS_ENCRYPTION_KEY not set — using app-scoped or machine-local fallback for workspace secrets. \" +\n \"Set SECRETS_ENCRYPTION_KEY or BETTER_AUTH_SECRET in every workspace app so sibling apps share vault rows, \" +\n \"or rely on A2A_SECRET-derived material on hosted workspace deploys.\",\n );\n}\n\n/** Whether this deployment has stable workspace-shared key material. */\nexport function hasSharedSecretEncryptionKeyMaterial(): boolean {\n return Boolean(sharedEncryptionKeyMaterial());\n}\n\nfunction encryptWithKey(plaintext: string, key: Buffer): string {\n const { createCipheriv, randomBytes } = requireNodeCrypto();\n const iv = randomBytes(12);\n const cipher = createCipheriv(\"aes-256-gcm\", key, iv);\n const ct = Buffer.concat([cipher.update(plaintext, \"utf8\"), cipher.final()]);\n const tag = cipher.getAuthTag();\n return `v1:${iv.toString(\"hex\")}:${ct.toString(\"hex\")}:${tag.toString(\"hex\")}`;\n}\n\nfunction decryptWithKey(encrypted: string, key: Buffer): string {\n const { createDecipheriv } = requireNodeCrypto();\n if (!encrypted.startsWith(\"v1:\")) {\n throw new Error(\"Unrecognised secret encoding\");\n }\n const [, ivHex, ctHex, tagHex] = encrypted.split(\":\");\n if (!ivHex || !ctHex || !tagHex) {\n throw new Error(\"Corrupt secret payload\");\n }\n const decipher = createDecipheriv(\n \"aes-256-gcm\",\n key,\n Buffer.from(ivHex, \"hex\"),\n );\n decipher.setAuthTag(Buffer.from(tagHex, \"hex\"));\n const pt = Buffer.concat([\n decipher.update(Buffer.from(ctHex, \"hex\")),\n decipher.final(),\n ]);\n return pt.toString(\"utf8\");\n}\n\n/** Encrypt a plain-text value with the generic app-local key. */\nexport function encryptSecretValue(plaintext: string): string {\n return encryptWithKey(plaintext, getSecretEncryptionKey());\n}\n\n/** Decrypt a value produced by `encryptSecretValue`. Throws on tampering. */\nexport function decryptSecretValue(encrypted: string): string {\n return decryptWithKey(encrypted, getSecretEncryptionKey());\n}\n\n/** Encrypt a workspace-shared `app_secrets` value. */\nexport function encryptSharedSecretValue(plaintext: string): string {\n return encryptWithKey(plaintext, getSharedSecretEncryptionKey());\n}\n\n/** Decrypt a workspace-shared `app_secrets` value. */\nexport function decryptSharedSecretValue(encrypted: string): string {\n return decryptWithKey(encrypted, getSharedSecretEncryptionKey());\n}\n\n/**\n * Strict check for a value produced by `encryptSecretValue`: `v1:` followed by\n * three hex segments. Intentionally strict so a legacy plaintext credential\n * that merely happens to start with `v1:` is treated as plaintext (and read via\n * the legacy fallback) rather than mis-decrypted.\n */\nconst ENCRYPTED_VALUE_RE = /^v1:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+$/;\n\nexport function isEncryptedSecretValue(value: unknown): value is string {\n return typeof value === \"string\" && ENCRYPTED_VALUE_RE.test(value);\n}\n"]}
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -34,37 +34,37 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
|
|
|
34
34
|
/** POST /_agent-native/secrets/:key — write a secret. */
|
|
35
35
|
export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
36
36
|
error: string;
|
|
37
|
-
ok?: undefined;
|
|
38
37
|
status?: undefined;
|
|
38
|
+
ok?: undefined;
|
|
39
39
|
} | {
|
|
40
|
-
error?: undefined;
|
|
41
40
|
ok: boolean;
|
|
42
41
|
status: string;
|
|
42
|
+
error?: undefined;
|
|
43
43
|
} | {
|
|
44
|
-
ok?: undefined;
|
|
45
44
|
error: string;
|
|
46
45
|
removed?: undefined;
|
|
46
|
+
ok?: undefined;
|
|
47
47
|
} | {
|
|
48
|
-
error?: undefined;
|
|
49
48
|
ok: boolean;
|
|
50
49
|
removed: boolean;
|
|
50
|
+
error?: undefined;
|
|
51
51
|
}>>;
|
|
52
52
|
/**
|
|
53
53
|
* POST /_agent-native/secrets/:key/test — re-run the validator against the
|
|
54
54
|
* current stored value without changing anything. Useful for the "Test" button.
|
|
55
55
|
*/
|
|
56
56
|
export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
57
|
-
ok?: undefined;
|
|
58
57
|
error: string;
|
|
59
58
|
note?: undefined;
|
|
59
|
+
ok?: undefined;
|
|
60
60
|
} | {
|
|
61
|
-
error?: undefined;
|
|
62
61
|
ok: boolean;
|
|
63
62
|
note?: undefined;
|
|
64
|
-
} | {
|
|
65
63
|
error?: undefined;
|
|
64
|
+
} | {
|
|
66
65
|
ok: boolean;
|
|
67
66
|
note: string;
|
|
67
|
+
error?: undefined;
|
|
68
68
|
} | {
|
|
69
69
|
note?: undefined;
|
|
70
70
|
ok: boolean;
|
|
@@ -95,12 +95,12 @@ export interface AdHocSecretPayload {
|
|
|
95
95
|
export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
|
|
96
96
|
error: string;
|
|
97
97
|
} | {
|
|
98
|
-
error?: undefined;
|
|
99
98
|
ok: boolean;
|
|
100
99
|
key: string;
|
|
101
|
-
} | {
|
|
102
100
|
error?: undefined;
|
|
101
|
+
} | {
|
|
103
102
|
ok: boolean;
|
|
104
103
|
removed: boolean;
|
|
104
|
+
error?: undefined;
|
|
105
105
|
}>>;
|
|
106
106
|
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/secrets/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAaH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA+FjD;;;GAGG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI3C;AAMD,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/secrets/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAaH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA+FjD;;;GAGG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI3C;AAMD,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAoF3E;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AA8GD;;;GAGG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,SAAS,GACb,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA0BlC;AAED,wEAAwE;AACxE,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAgCzC;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,SAAS,GACb,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAItD;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,SAAS,GACb,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAkC5B;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,EAAE,CAAC,CAmCvB;AAeD,wBAAsB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAStE"}
|
package/dist/secrets/storage.js
CHANGED
|
@@ -110,8 +110,9 @@ export async function writeAppSecret(args) {
|
|
|
110
110
|
const now = Date.now();
|
|
111
111
|
// Dual-write during rollout: old readers continue using encrypted_value,
|
|
112
112
|
// while new readers prefer the nullable shared ciphertext. An app-only
|
|
113
|
-
// deployment leaves the shared column null; on an update,
|
|
114
|
-
// shared
|
|
113
|
+
// deployment leaves the shared column null; on an update, a writer without
|
|
114
|
+
// shared key material clears any existing shared ciphertext rather than
|
|
115
|
+
// preserving it (see the upsert SQL below for why).
|
|
115
116
|
const encrypted = encryptLegacyValue(value);
|
|
116
117
|
const sharedEncrypted = hasSharedSecretEncryptionKeyMaterial()
|
|
117
118
|
? encryptValue(value)
|
|
@@ -128,11 +129,23 @@ export async function writeAppSecret(args) {
|
|
|
128
129
|
// keeps its original id (any stored references stay stable); only a
|
|
129
130
|
// genuinely new row gets the freshly generated `id`. This syntax is
|
|
130
131
|
// portable across SQLite (UPSERT since 3.24) and Postgres.
|
|
132
|
+
//
|
|
133
|
+
// shared_encrypted_value is overwritten with `excluded.shared_encrypted_value`
|
|
134
|
+
// (NULL when this writer lacks shared key material) rather than preserved
|
|
135
|
+
// via COALESCE. Preserving an existing shared ciphertext across a value
|
|
136
|
+
// update would let a sibling app silently decrypt a STALE value after the
|
|
137
|
+
// owner rotates it — a material-less writer has no way to produce the new
|
|
138
|
+
// shared ciphertext, so it must clear the old one instead of leaving it
|
|
139
|
+
// pointing at data that's no longer current. Siblings then get an honest
|
|
140
|
+
// cache miss (falling back to the legacy column or reporting missing) until
|
|
141
|
+
// the owning app's next read repopulates shared_encrypted_value via
|
|
142
|
+
// `populateSharedAppSecret`, which only ever fills a NULL column. A
|
|
143
|
+
// temporary miss is safer than serving rotated-away plaintext.
|
|
131
144
|
const upsertSql = `INSERT INTO app_secrets (id, scope, scope_id, key, encrypted_value, shared_encrypted_value, description, url_allowlist, created_at, updated_at)
|
|
132
145
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
133
146
|
ON CONFLICT (scope, scope_id, key) DO UPDATE SET
|
|
134
147
|
encrypted_value = excluded.encrypted_value,
|
|
135
|
-
shared_encrypted_value =
|
|
148
|
+
shared_encrypted_value = excluded.shared_encrypted_value,
|
|
136
149
|
description = excluded.description,
|
|
137
150
|
url_allowlist = excluded.url_allowlist,
|
|
138
151
|
updated_at = excluded.updated_at`;
|