@agent-native/core 0.109.2 → 0.109.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +16 -0
- package/corpus/core/docs/content/agent-native-toolkit.mdx +46 -13
- package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +79 -55
- package/corpus/core/docs/content/locales/ar-SA/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/ar-SA/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/ar-SA/toolkit-editors-canvases.mdx +17 -0
- package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +82 -54
- package/corpus/core/docs/content/locales/de-DE/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/de-DE/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/de-DE/toolkit-editors-canvases.mdx +17 -0
- package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +81 -52
- package/corpus/core/docs/content/locales/es-ES/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/es-ES/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/es-ES/toolkit-editors-canvases.mdx +21 -0
- package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +84 -54
- package/corpus/core/docs/content/locales/fr-FR/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/fr-FR/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/fr-FR/toolkit-editors-canvases.mdx +21 -0
- package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +69 -62
- package/corpus/core/docs/content/locales/hi-IN/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/hi-IN/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/hi-IN/toolkit-editors-canvases.mdx +17 -0
- package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +69 -62
- package/corpus/core/docs/content/locales/ja-JP/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/ja-JP/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/ja-JP/toolkit-editors-canvases.mdx +17 -0
- package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +69 -62
- package/corpus/core/docs/content/locales/ko-KR/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/ko-KR/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/ko-KR/toolkit-editors-canvases.mdx +17 -0
- package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +82 -54
- package/corpus/core/docs/content/locales/pt-BR/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/pt-BR/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/pt-BR/toolkit-editors-canvases.mdx +17 -0
- package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +69 -62
- package/corpus/core/docs/content/locales/zh-CN/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/zh-CN/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/zh-CN/toolkit-editors-canvases.mdx +17 -0
- package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +69 -62
- package/corpus/core/docs/content/locales/zh-TW/toolkit-capability-packages.mdx +21 -0
- package/corpus/core/docs/content/locales/zh-TW/toolkit-context-knowledge.mdx +12 -0
- package/corpus/core/docs/content/locales/zh-TW/toolkit-editors-canvases.mdx +17 -0
- package/corpus/core/docs/content/toolkit-capability-packages.mdx +52 -0
- package/corpus/core/docs/content/toolkit-context-knowledge.mdx +46 -0
- package/corpus/core/docs/content/toolkit-editors-canvases.mdx +55 -0
- package/corpus/core/package.json +35 -34
- package/corpus/core/src/cli/create.ts +57 -15
- package/corpus/core/src/cli/package-lifecycle.ts +2 -0
- package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +2 -0
- package/corpus/core/src/client/context-xray/ContextMeter.tsx +31 -111
- package/corpus/core/src/client/context-xray/ContextSegmentRow.tsx +8 -111
- package/corpus/core/src/client/context-xray/ContextTreemap.tsx +6 -111
- package/corpus/core/src/client/context-xray/ContextXRayPanel.tsx +31 -391
- package/corpus/core/src/client/context-xray/SegmentProvenancePopover.tsx +4 -52
- package/corpus/core/src/client/context-xray/format.ts +0 -33
- package/corpus/core/src/client/require-session.tsx +19 -3
- package/corpus/core/src/client/rich-markdown-editor/index.ts +42 -57
- package/corpus/core/src/client/rich-markdown-editor/uploadEditorImage.ts +2 -1
- package/corpus/core/src/client/use-action.ts +145 -2
- package/corpus/core/src/client/use-session.ts +79 -48
- package/corpus/core/src/client/visual-style-controls.tsx +1 -1088
- package/corpus/core/src/collab/agent-identity.ts +5 -22
- package/corpus/core/src/collab/client.ts +1 -53
- package/corpus/core/src/db/client.ts +13 -7
- package/corpus/core/src/db/create-get-db.ts +20 -13
- package/corpus/core/src/db/request-telemetry.ts +154 -0
- package/corpus/core/src/integrations/index.ts +1 -0
- package/corpus/core/src/integrations/plugin.ts +9 -3
- package/corpus/core/src/integrations/remote-push-delivery-job.ts +48 -0
- package/corpus/core/src/integrations/remote-push-delivery.ts +370 -0
- package/corpus/core/src/integrations/remote-push-store.ts +275 -26
- package/corpus/core/src/server/better-auth-instance.ts +11 -3
- package/corpus/core/src/server/core-routes-plugin.ts +36 -14
- package/corpus/core/src/server/framework-request-handler.ts +11 -1
- package/corpus/core/src/server/http-response-telemetry.ts +233 -31
- package/corpus/core/src/styles/rich-markdown-editor.css +1 -510
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
- package/corpus/core/src/testing.ts +1 -1
- package/corpus/core/src/vite/client.ts +3 -0
- package/corpus/templates/clips/actions/finalize-recording.ts +3 -1
- package/corpus/templates/clips/actions/set-mobile-capture-state.ts +4 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -6
- package/corpus/templates/clips/changelog/2026-07-18-new-recording-is-now-emphasized-as-the-primary-action-in-the.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-18-recordings-now-remain-safely-recoverable-until-the-stored-me.md +6 -0
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +5 -3
- package/corpus/templates/content/app/components/editor/extensions/DragHandle.tsx +4 -4
- package/corpus/templates/content/package.json +25 -25
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +2 -1
- package/corpus/templates/design/package.json +1 -1
- package/corpus/templates/mail/package.json +9 -9
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +2 -0
- package/corpus/templates/plan/app/components/editor/PlanDocumentEditor.tsx +8 -8
- package/corpus/templates/plan/app/components/editor/planSlashCommands.ts +6 -6
- package/corpus/templates/plan/app/components/plan/PlanImageNode.tsx +4 -7
- package/corpus/templates/plan/app/components/plan/PlanMarkdownEditor.tsx +6 -4
- package/corpus/templates/plan/app/components/plan/PlanVisualSurface.tsx +1 -1
- package/corpus/templates/plan/changelog/2026-07-18-visual-plans-now-open-on-wireframes-by-default-when-a-protot.md +6 -0
- package/corpus/templates/plan/package.json +3 -3
- package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +2 -2
- package/corpus/templates/slides/app/components/editor/TweaksPanel.tsx +2 -2
- package/corpus/templates/slides/package.json +13 -13
- package/corpus/templates/tasks/AGENTS.md +3 -0
- package/corpus/templates/tasks/actions/render-task-list-inline.ts +202 -0
- package/corpus/templates/tasks/changelog/2026-07-18-task-lists-can-now-appear-as-interactive-widgets-inline-in-c.md +6 -0
- package/corpus/templates/tasks/docs/features/f8-chat.mdx +2 -0
- package/corpus/templates/tasks/server/plugins/agent-chat.ts +2 -0
- package/dist/catalog.json +39 -1
- package/dist/cli/create.d.ts +10 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +49 -16
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/package-lifecycle.d.ts.map +1 -1
- package/dist/cli/package-lifecycle.js +2 -0
- package/dist/cli/package-lifecycle.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 +2 -0
- package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
- package/dist/client/context-xray/ContextMeter.d.ts.map +1 -1
- package/dist/client/context-xray/ContextMeter.js +8 -23
- package/dist/client/context-xray/ContextMeter.js.map +1 -1
- package/dist/client/context-xray/ContextSegmentRow.d.ts.map +1 -1
- package/dist/client/context-xray/ContextSegmentRow.js +3 -19
- package/dist/client/context-xray/ContextSegmentRow.js.map +1 -1
- package/dist/client/context-xray/ContextTreemap.d.ts.map +1 -1
- package/dist/client/context-xray/ContextTreemap.js +3 -54
- package/dist/client/context-xray/ContextTreemap.js.map +1 -1
- package/dist/client/context-xray/ContextXRayPanel.d.ts.map +1 -1
- package/dist/client/context-xray/ContextXRayPanel.js +21 -163
- package/dist/client/context-xray/ContextXRayPanel.js.map +1 -1
- package/dist/client/context-xray/SegmentProvenancePopover.d.ts.map +1 -1
- package/dist/client/context-xray/SegmentProvenancePopover.js +3 -4
- package/dist/client/context-xray/SegmentProvenancePopover.js.map +1 -1
- package/dist/client/context-xray/format.d.ts +0 -4
- package/dist/client/context-xray/format.d.ts.map +1 -1
- package/dist/client/context-xray/format.js +0 -49
- package/dist/client/context-xray/format.js.map +1 -1
- package/dist/client/require-session.d.ts.map +1 -1
- package/dist/client/require-session.js +6 -3
- package/dist/client/require-session.js.map +1 -1
- package/dist/client/rich-markdown-editor/index.d.ts +1 -12
- package/dist/client/rich-markdown-editor/index.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/index.js +1 -12
- package/dist/client/rich-markdown-editor/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts +1 -1
- package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/uploadEditorImage.js.map +1 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +117 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-session.d.ts.map +1 -1
- package/dist/client/use-session.js +72 -50
- package/dist/client/use-session.js.map +1 -1
- package/dist/client/visual-style-controls.d.ts +1 -89
- package/dist/client/visual-style-controls.d.ts.map +1 -1
- package/dist/client/visual-style-controls.js +1 -498
- package/dist/client/visual-style-controls.js.map +1 -1
- package/dist/collab/agent-identity.d.ts +1 -14
- package/dist/collab/agent-identity.d.ts.map +1 -1
- package/dist/collab/agent-identity.js +1 -13
- package/dist/collab/agent-identity.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/client.d.ts +1 -19
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +1 -53
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +7 -1
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.d.ts +3 -6
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +9 -2
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/request-telemetry.d.ts +23 -0
- package/dist/db/request-telemetry.d.ts.map +1 -0
- package/dist/db/request-telemetry.js +95 -0
- package/dist/db/request-telemetry.js.map +1 -0
- package/dist/integrations/index.d.ts +1 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +1 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +8 -3
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/remote-push-delivery-job.d.ts +4 -0
- package/dist/integrations/remote-push-delivery-job.d.ts.map +1 -0
- package/dist/integrations/remote-push-delivery-job.js +44 -0
- package/dist/integrations/remote-push-delivery-job.js.map +1 -0
- package/dist/integrations/remote-push-delivery.d.ts +11 -0
- package/dist/integrations/remote-push-delivery.d.ts.map +1 -0
- package/dist/integrations/remote-push-delivery.js +265 -0
- package/dist/integrations/remote-push-delivery.js.map +1 -0
- package/dist/integrations/remote-push-store.d.ts +33 -0
- package/dist/integrations/remote-push-store.d.ts.map +1 -1
- package/dist/integrations/remote-push-store.js +195 -26
- package/dist/integrations/remote-push-store.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- 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/secrets/routes.d.ts +9 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/better-auth-instance.js +7 -3
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +8 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +23 -8
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +9 -1
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/http-response-telemetry.d.ts +3 -2
- package/dist/server/http-response-telemetry.d.ts.map +1 -1
- package/dist/server/http-response-telemetry.js +160 -27
- package/dist/server/http-response-telemetry.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/rich-markdown-editor.css +1 -510
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
- package/dist/testing.d.ts +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +3 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/agent-native-toolkit.mdx +46 -13
- package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +79 -55
- package/docs/content/locales/ar-SA/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/ar-SA/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/ar-SA/toolkit-editors-canvases.mdx +17 -0
- package/docs/content/locales/de-DE/agent-native-toolkit.mdx +82 -54
- package/docs/content/locales/de-DE/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/de-DE/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/de-DE/toolkit-editors-canvases.mdx +17 -0
- package/docs/content/locales/es-ES/agent-native-toolkit.mdx +81 -52
- package/docs/content/locales/es-ES/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/es-ES/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/es-ES/toolkit-editors-canvases.mdx +21 -0
- package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +84 -54
- package/docs/content/locales/fr-FR/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/fr-FR/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/fr-FR/toolkit-editors-canvases.mdx +21 -0
- package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +69 -62
- package/docs/content/locales/hi-IN/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/hi-IN/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/hi-IN/toolkit-editors-canvases.mdx +17 -0
- package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +69 -62
- package/docs/content/locales/ja-JP/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/ja-JP/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/ja-JP/toolkit-editors-canvases.mdx +17 -0
- package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +69 -62
- package/docs/content/locales/ko-KR/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/ko-KR/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/ko-KR/toolkit-editors-canvases.mdx +17 -0
- package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +82 -54
- package/docs/content/locales/pt-BR/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/pt-BR/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/pt-BR/toolkit-editors-canvases.mdx +17 -0
- package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +69 -62
- package/docs/content/locales/zh-CN/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/zh-CN/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/zh-CN/toolkit-editors-canvases.mdx +17 -0
- package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +69 -62
- package/docs/content/locales/zh-TW/toolkit-capability-packages.mdx +21 -0
- package/docs/content/locales/zh-TW/toolkit-context-knowledge.mdx +12 -0
- package/docs/content/locales/zh-TW/toolkit-editors-canvases.mdx +17 -0
- package/docs/content/toolkit-capability-packages.mdx +52 -0
- package/docs/content/toolkit-context-knowledge.mdx +46 -0
- package/docs/content/toolkit-editors-canvases.mdx +55 -0
- package/package.json +27 -26
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
- package/corpus/core/src/client/rich-markdown-editor/BubbleToolbar.tsx +0 -253
- package/corpus/core/src/client/rich-markdown-editor/CodeBlockNode.tsx +0 -258
- package/corpus/core/src/client/rich-markdown-editor/DragHandle.ts +0 -1437
- package/corpus/core/src/client/rich-markdown-editor/ImageExtension.ts +0 -306
- package/corpus/core/src/client/rich-markdown-editor/RichMarkdownEditor.tsx +0 -80
- package/corpus/core/src/client/rich-markdown-editor/RunId.ts +0 -61
- package/corpus/core/src/client/rich-markdown-editor/SharedRichEditor.tsx +0 -321
- package/corpus/core/src/client/rich-markdown-editor/SlashCommandMenu.tsx +0 -310
- package/corpus/core/src/client/rich-markdown-editor/extensions.ts +0 -402
- package/corpus/core/src/client/rich-markdown-editor/gfmDoc.ts +0 -92
- package/corpus/core/src/client/rich-markdown-editor/surgical-apply.ts +0 -192
- package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +0 -590
- package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts +0 -37
- package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/BubbleToolbar.js +0 -171
- package/dist/client/rich-markdown-editor/BubbleToolbar.js.map +0 -1
- package/dist/client/rich-markdown-editor/CodeBlockNode.d.ts +0 -49
- package/dist/client/rich-markdown-editor/CodeBlockNode.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/CodeBlockNode.js +0 -127
- package/dist/client/rich-markdown-editor/CodeBlockNode.js.map +0 -1
- package/dist/client/rich-markdown-editor/DragHandle.d.ts +0 -97
- package/dist/client/rich-markdown-editor/DragHandle.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/DragHandle.js +0 -1066
- package/dist/client/rich-markdown-editor/DragHandle.js.map +0 -1
- package/dist/client/rich-markdown-editor/ImageExtension.d.ts +0 -63
- package/dist/client/rich-markdown-editor/ImageExtension.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/ImageExtension.js +0 -243
- package/dist/client/rich-markdown-editor/ImageExtension.js.map +0 -1
- package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts +0 -51
- package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/RichMarkdownEditor.js +0 -37
- package/dist/client/rich-markdown-editor/RichMarkdownEditor.js.map +0 -1
- package/dist/client/rich-markdown-editor/RunId.d.ts +0 -28
- package/dist/client/rich-markdown-editor/RunId.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/RunId.js +0 -60
- package/dist/client/rich-markdown-editor/RunId.js.map +0 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +0 -110
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.js +0 -144
- package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +0 -1
- package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts +0 -41
- package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/SlashCommandMenu.js +0 -221
- package/dist/client/rich-markdown-editor/SlashCommandMenu.js.map +0 -1
- package/dist/client/rich-markdown-editor/extensions.d.ts +0 -178
- package/dist/client/rich-markdown-editor/extensions.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/extensions.js +0 -224
- package/dist/client/rich-markdown-editor/extensions.js.map +0 -1
- package/dist/client/rich-markdown-editor/gfmDoc.d.ts +0 -24
- package/dist/client/rich-markdown-editor/gfmDoc.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/gfmDoc.js +0 -83
- package/dist/client/rich-markdown-editor/gfmDoc.js.map +0 -1
- package/dist/client/rich-markdown-editor/surgical-apply.d.ts +0 -66
- package/dist/client/rich-markdown-editor/surgical-apply.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/surgical-apply.js +0 -147
- package/dist/client/rich-markdown-editor/surgical-apply.js.map +0 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +0 -110
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +0 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +0 -441
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getDbExec, isPostgres, intType, retryOnDdlRace, } from "../db/client.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
|
|
3
|
+
import { isDuplicateColumnError } from "../db/migrations.js";
|
|
3
4
|
let _initPromise;
|
|
4
5
|
// Build the CREATE SQL lazily (not at module scope) so intType() runs at
|
|
5
6
|
// RUNTIME, not import time — a module-scope call breaks any consumer whose
|
|
@@ -33,6 +34,10 @@ function buildCreateNotificationsSql() {
|
|
|
33
34
|
payload_json TEXT NOT NULL,
|
|
34
35
|
status TEXT NOT NULL,
|
|
35
36
|
attempts ${intType()} NOT NULL DEFAULT 0,
|
|
37
|
+
provider_ticket_id TEXT,
|
|
38
|
+
next_attempt_at ${intType()} NOT NULL DEFAULT 0,
|
|
39
|
+
last_error TEXT,
|
|
40
|
+
delivered_at ${intType()},
|
|
36
41
|
created_at ${intType()} NOT NULL,
|
|
37
42
|
updated_at ${intType()} NOT NULL
|
|
38
43
|
)
|
|
@@ -51,6 +56,11 @@ async function ensureTables() {
|
|
|
51
56
|
await ensureIndexExists("idx_remote_push_owner", `CREATE INDEX IF NOT EXISTS idx_remote_push_owner ON integration_remote_push_registrations(owner_email, org_id, status)`);
|
|
52
57
|
await ensureTableExists("integration_remote_push_notifications", createNotificationsSql);
|
|
53
58
|
await ensureIndexExists("idx_remote_push_notifications_owner", `CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_owner ON integration_remote_push_notifications(owner_email, org_id, status, created_at)`);
|
|
59
|
+
await ensureColumnExists("integration_remote_push_notifications", "provider_ticket_id", `ALTER TABLE integration_remote_push_notifications ADD COLUMN IF NOT EXISTS provider_ticket_id TEXT`);
|
|
60
|
+
await ensureColumnExists("integration_remote_push_notifications", "next_attempt_at", `ALTER TABLE integration_remote_push_notifications ADD COLUMN IF NOT EXISTS next_attempt_at ${intType()} NOT NULL DEFAULT 0`);
|
|
61
|
+
await ensureColumnExists("integration_remote_push_notifications", "last_error", `ALTER TABLE integration_remote_push_notifications ADD COLUMN IF NOT EXISTS last_error TEXT`);
|
|
62
|
+
await ensureColumnExists("integration_remote_push_notifications", "delivered_at", `ALTER TABLE integration_remote_push_notifications ADD COLUMN IF NOT EXISTS delivered_at ${intType()}`);
|
|
63
|
+
await ensureIndexExists("idx_remote_push_notifications_delivery", `CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_delivery ON integration_remote_push_notifications(status, next_attempt_at, updated_at)`);
|
|
54
64
|
return;
|
|
55
65
|
}
|
|
56
66
|
// SQLite (local dev): keep existing behavior
|
|
@@ -59,6 +69,11 @@ async function ensureTables() {
|
|
|
59
69
|
await retryOnDdlRace(() => client.execute(`CREATE INDEX IF NOT EXISTS idx_remote_push_owner ON integration_remote_push_registrations(owner_email, org_id, status)`));
|
|
60
70
|
await retryOnDdlRace(() => client.execute(createNotificationsSql));
|
|
61
71
|
await retryOnDdlRace(() => client.execute(`CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_owner ON integration_remote_push_notifications(owner_email, org_id, status, created_at)`));
|
|
72
|
+
await addNotificationColumnIfMissing("provider_ticket_id", "TEXT");
|
|
73
|
+
await addNotificationColumnIfMissing("next_attempt_at", `${intType()} NOT NULL DEFAULT 0`);
|
|
74
|
+
await addNotificationColumnIfMissing("last_error", "TEXT");
|
|
75
|
+
await addNotificationColumnIfMissing("delivered_at", intType());
|
|
76
|
+
await retryOnDdlRace(() => client.execute(`CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_delivery ON integration_remote_push_notifications(status, next_attempt_at, updated_at)`));
|
|
62
77
|
})().catch((err) => {
|
|
63
78
|
// Retry init on the next call after a failed startup.
|
|
64
79
|
_initPromise = undefined;
|
|
@@ -67,6 +82,15 @@ async function ensureTables() {
|
|
|
67
82
|
}
|
|
68
83
|
return _initPromise;
|
|
69
84
|
}
|
|
85
|
+
async function addNotificationColumnIfMissing(name, definition) {
|
|
86
|
+
try {
|
|
87
|
+
await retryOnDdlRace(() => getDbExec().execute(`ALTER TABLE integration_remote_push_notifications ADD COLUMN ${name} ${definition}`));
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (!isDuplicateColumnError(error))
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
70
94
|
function rowToRegistration(row) {
|
|
71
95
|
return {
|
|
72
96
|
id: row.id,
|
|
@@ -85,13 +109,17 @@ function rowToRegistration(row) {
|
|
|
85
109
|
};
|
|
86
110
|
}
|
|
87
111
|
function rowToNotification(row) {
|
|
112
|
+
const storedStatus = String(row.status ?? "pending");
|
|
113
|
+
const status = storedStatus === "delivered" || storedStatus === "failed"
|
|
114
|
+
? storedStatus
|
|
115
|
+
: "pending";
|
|
88
116
|
return {
|
|
89
117
|
id: row.id,
|
|
90
118
|
ownerEmail: row.owner_email,
|
|
91
119
|
orgId: row.org_id ?? null,
|
|
92
120
|
registrationId: row.registration_id,
|
|
93
121
|
payload: parseJson(row.payload_json, null),
|
|
94
|
-
status
|
|
122
|
+
status,
|
|
95
123
|
attempts: Number(row.attempts ?? 0),
|
|
96
124
|
createdAt: Number(row.created_at ?? 0),
|
|
97
125
|
updatedAt: Number(row.updated_at ?? 0),
|
|
@@ -235,42 +263,47 @@ export async function queueRemotePushNotifications(input) {
|
|
|
235
263
|
orgId: input.orgId ?? null,
|
|
236
264
|
limit: 100,
|
|
237
265
|
});
|
|
266
|
+
if (registrations.length === 0)
|
|
267
|
+
return { queued: 0 };
|
|
238
268
|
const client = getDbExec();
|
|
239
269
|
const now = Date.now();
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
270
|
+
const payload = JSON.stringify(input.payload ?? null);
|
|
271
|
+
const values = registrations.map(() => "(?, ?, ?, ?, ?, 'pending', 0, ?, ?, ?)");
|
|
272
|
+
const args = registrations.flatMap((registration) => [
|
|
273
|
+
`remote-push-notification-${now}-${randomHex(8)}`,
|
|
274
|
+
input.ownerEmail,
|
|
275
|
+
input.orgId ?? null,
|
|
276
|
+
registration.id,
|
|
277
|
+
payload,
|
|
278
|
+
now,
|
|
279
|
+
now,
|
|
280
|
+
now,
|
|
281
|
+
]);
|
|
282
|
+
const result = await client.execute({
|
|
283
|
+
sql: `INSERT INTO integration_remote_push_notifications
|
|
245
284
|
(id, owner_email, org_id, registration_id, payload_json, status,
|
|
246
|
-
attempts, created_at, updated_at)
|
|
247
|
-
VALUES (
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
JSON.stringify(input.payload ?? null),
|
|
254
|
-
"pending",
|
|
255
|
-
0,
|
|
256
|
-
now,
|
|
257
|
-
now,
|
|
258
|
-
],
|
|
259
|
-
});
|
|
260
|
-
queued += result.rowsAffected ?? result.rowCount ?? 0;
|
|
261
|
-
}
|
|
262
|
-
return { queued };
|
|
285
|
+
attempts, next_attempt_at, created_at, updated_at)
|
|
286
|
+
VALUES ${values.join(", ")}`,
|
|
287
|
+
args,
|
|
288
|
+
});
|
|
289
|
+
return {
|
|
290
|
+
queued: result.rowsAffected ?? result.rowCount ?? 0,
|
|
291
|
+
};
|
|
263
292
|
}
|
|
264
293
|
export async function listRemotePushNotificationsForOwner(input) {
|
|
265
294
|
await ensureTables();
|
|
266
295
|
const limit = Math.max(1, Math.min(input.limit ?? 50, 100));
|
|
267
|
-
const statusClause = input.status
|
|
296
|
+
const statusClause = input.status
|
|
297
|
+
? input.status === "pending"
|
|
298
|
+
? " AND status IN ('pending', 'sending', 'sent', 'checking')"
|
|
299
|
+
: " AND status = ?"
|
|
300
|
+
: "";
|
|
268
301
|
const args = [
|
|
269
302
|
input.ownerEmail,
|
|
270
303
|
input.orgId ?? null,
|
|
271
304
|
input.orgId ?? null,
|
|
272
305
|
];
|
|
273
|
-
if (input.status)
|
|
306
|
+
if (input.status && input.status !== "pending")
|
|
274
307
|
args.push(input.status);
|
|
275
308
|
args.push(limit);
|
|
276
309
|
const { rows } = await getDbExec().execute({
|
|
@@ -283,6 +316,142 @@ export async function listRemotePushNotificationsForOwner(input) {
|
|
|
283
316
|
});
|
|
284
317
|
return rows.map((row) => rowToNotification(row));
|
|
285
318
|
}
|
|
319
|
+
export async function claimNextRemotePushDelivery(input) {
|
|
320
|
+
await ensureTables();
|
|
321
|
+
const client = getDbExec();
|
|
322
|
+
const now = input?.now ?? Date.now();
|
|
323
|
+
const staleBefore = now - Math.max(30_000, input?.staleAfterMs ?? 120_000);
|
|
324
|
+
const { rows } = await client.execute({
|
|
325
|
+
sql: `SELECT n.id, n.registration_id, n.payload_json, n.status, n.attempts,
|
|
326
|
+
n.provider_ticket_id, n.updated_at, r.provider, r.token
|
|
327
|
+
FROM integration_remote_push_notifications n
|
|
328
|
+
INNER JOIN integration_remote_push_registrations r
|
|
329
|
+
ON r.id = n.registration_id
|
|
330
|
+
WHERE r.status = 'active'
|
|
331
|
+
AND (
|
|
332
|
+
(n.status IN ('pending', 'sent') AND n.next_attempt_at <= ?)
|
|
333
|
+
OR (n.status IN ('sending', 'checking') AND n.updated_at <= ?)
|
|
334
|
+
)
|
|
335
|
+
ORDER BY n.created_at ASC
|
|
336
|
+
LIMIT 1`,
|
|
337
|
+
args: [now, staleBefore],
|
|
338
|
+
});
|
|
339
|
+
const row = rows[0];
|
|
340
|
+
if (!row)
|
|
341
|
+
return null;
|
|
342
|
+
const previousStatus = String(row.status ?? "pending");
|
|
343
|
+
const providerTicketId = sanitizeString(row.provider_ticket_id, 200);
|
|
344
|
+
const phase = (previousStatus === "sent" || previousStatus === "checking") &&
|
|
345
|
+
providerTicketId
|
|
346
|
+
? "receipt"
|
|
347
|
+
: "send";
|
|
348
|
+
const claimedStatus = phase === "receipt" ? "checking" : "sending";
|
|
349
|
+
const result = await client.execute({
|
|
350
|
+
sql: `UPDATE integration_remote_push_notifications
|
|
351
|
+
SET status = ?, attempts = attempts + 1, updated_at = ?
|
|
352
|
+
WHERE id = ? AND status = ? AND updated_at = ?`,
|
|
353
|
+
args: [
|
|
354
|
+
claimedStatus,
|
|
355
|
+
now,
|
|
356
|
+
row.id,
|
|
357
|
+
previousStatus,
|
|
358
|
+
Number(row.updated_at),
|
|
359
|
+
],
|
|
360
|
+
});
|
|
361
|
+
if ((result.rowsAffected ?? result.rowCount ?? 0) !== 1)
|
|
362
|
+
return null;
|
|
363
|
+
return {
|
|
364
|
+
id: row.id,
|
|
365
|
+
registrationId: row.registration_id,
|
|
366
|
+
provider: String(row.provider ?? "unknown"),
|
|
367
|
+
token: row.token,
|
|
368
|
+
payload: parseJson(row.payload_json, null),
|
|
369
|
+
phase,
|
|
370
|
+
providerTicketId,
|
|
371
|
+
attempts: Number(row.attempts ?? 0) + 1,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
export async function markRemotePushTicketAccepted(input) {
|
|
375
|
+
await ensureTables();
|
|
376
|
+
const now = Date.now();
|
|
377
|
+
const result = await getDbExec().execute({
|
|
378
|
+
sql: `UPDATE integration_remote_push_notifications
|
|
379
|
+
SET status = 'sent', provider_ticket_id = ?, next_attempt_at = ?,
|
|
380
|
+
last_error = NULL, updated_at = ?
|
|
381
|
+
WHERE id = ? AND status = 'sending'`,
|
|
382
|
+
args: [input.providerTicketId, input.checkAfter, now, input.id],
|
|
383
|
+
});
|
|
384
|
+
return (result.rowsAffected ?? result.rowCount ?? 0) === 1;
|
|
385
|
+
}
|
|
386
|
+
export async function markRemotePushDelivered(id) {
|
|
387
|
+
await ensureTables();
|
|
388
|
+
const now = Date.now();
|
|
389
|
+
const result = await getDbExec().execute({
|
|
390
|
+
sql: `UPDATE integration_remote_push_notifications
|
|
391
|
+
SET status = 'delivered', last_error = NULL, delivered_at = ?,
|
|
392
|
+
updated_at = ?
|
|
393
|
+
WHERE id = ? AND status = 'checking'`,
|
|
394
|
+
args: [now, now, id],
|
|
395
|
+
});
|
|
396
|
+
return (result.rowsAffected ?? result.rowCount ?? 0) === 1;
|
|
397
|
+
}
|
|
398
|
+
export async function retryRemotePushDelivery(input) {
|
|
399
|
+
await ensureTables();
|
|
400
|
+
const currentStatus = input.phase === "receipt" ? "checking" : "sending";
|
|
401
|
+
const retryStatus = input.phase === "receipt" && !input.resend ? "sent" : "pending";
|
|
402
|
+
const clearTicketClause = input.resend ? ", provider_ticket_id = NULL" : "";
|
|
403
|
+
const result = await getDbExec().execute({
|
|
404
|
+
sql: `UPDATE integration_remote_push_notifications
|
|
405
|
+
SET status = ?, next_attempt_at = ?, last_error = ?${clearTicketClause},
|
|
406
|
+
updated_at = ?
|
|
407
|
+
WHERE id = ? AND status = ?`,
|
|
408
|
+
args: [
|
|
409
|
+
retryStatus,
|
|
410
|
+
input.retryAt,
|
|
411
|
+
sanitizeString(input.errorCode, 160) ?? "temporary_error",
|
|
412
|
+
Date.now(),
|
|
413
|
+
input.id,
|
|
414
|
+
currentStatus,
|
|
415
|
+
],
|
|
416
|
+
});
|
|
417
|
+
return (result.rowsAffected ?? result.rowCount ?? 0) === 1;
|
|
418
|
+
}
|
|
419
|
+
export async function failRemotePushDelivery(input) {
|
|
420
|
+
await ensureTables();
|
|
421
|
+
const currentStatus = input.phase === "receipt" ? "checking" : "sending";
|
|
422
|
+
const result = await getDbExec().execute({
|
|
423
|
+
sql: `UPDATE integration_remote_push_notifications
|
|
424
|
+
SET status = 'failed', last_error = ?, updated_at = ?
|
|
425
|
+
WHERE id = ? AND status = ?`,
|
|
426
|
+
args: [
|
|
427
|
+
sanitizeString(input.errorCode, 160) ?? "delivery_failed",
|
|
428
|
+
Date.now(),
|
|
429
|
+
input.id,
|
|
430
|
+
currentStatus,
|
|
431
|
+
],
|
|
432
|
+
});
|
|
433
|
+
return (result.rowsAffected ?? result.rowCount ?? 0) === 1;
|
|
434
|
+
}
|
|
435
|
+
export async function deactivateRemotePushRegistration(registrationId) {
|
|
436
|
+
await ensureTables();
|
|
437
|
+
const client = getDbExec();
|
|
438
|
+
const now = Date.now();
|
|
439
|
+
const result = await client.execute({
|
|
440
|
+
sql: `UPDATE integration_remote_push_registrations
|
|
441
|
+
SET status = 'inactive', updated_at = ?
|
|
442
|
+
WHERE id = ? AND status = 'active'`,
|
|
443
|
+
args: [now, registrationId],
|
|
444
|
+
});
|
|
445
|
+
await client.execute({
|
|
446
|
+
sql: `UPDATE integration_remote_push_notifications
|
|
447
|
+
SET status = 'failed', last_error = 'registration_inactive',
|
|
448
|
+
updated_at = ?
|
|
449
|
+
WHERE registration_id = ?
|
|
450
|
+
AND status IN ('pending', 'sending', 'sent', 'checking')`,
|
|
451
|
+
args: [now, registrationId],
|
|
452
|
+
});
|
|
453
|
+
return (result.rowsAffected ?? result.rowCount ?? 0) === 1;
|
|
454
|
+
}
|
|
286
455
|
async function getRemotePushRegistrationByTokenHash(tokenHash) {
|
|
287
456
|
const { rows } = await getDbExec().execute({
|
|
288
457
|
sql: `SELECT * FROM integration_remote_push_registrations
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-push-store.js","sourceRoot":"","sources":["../../src/integrations/remote-push-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getDbExec,\n isPostgres,\n intType,\n retryOnDdlRace,\n} from \"../db/client.js\";\nimport { ensureTableExists, ensureIndexExists } from \"../db/ddl-guard.js\";\nimport type {\n PublicRemotePushRegistration,\n RemotePushNotification,\n RemotePushRegistration,\n} from \"./remote-types.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\n// Build the CREATE SQL lazily (not at module scope) so intType() runs at\n// RUNTIME, not import time — a module-scope call breaks any consumer whose\n// db/client mock doesn't stub intType (e.g. db-admin specs).\nfunction buildCreateRegistrationsSql(): string {\n return `\n CREATE TABLE IF NOT EXISTS integration_remote_push_registrations (\n id TEXT PRIMARY KEY,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n provider TEXT NOT NULL,\n platform TEXT,\n client_device_id TEXT,\n label TEXT,\n token TEXT NOT NULL,\n token_hash TEXT NOT NULL,\n status TEXT NOT NULL,\n last_seen_at ${intType()},\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n`;\n}\n\nfunction buildCreateNotificationsSql(): string {\n return `\n CREATE TABLE IF NOT EXISTS integration_remote_push_notifications (\n id TEXT PRIMARY KEY,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n registration_id TEXT NOT NULL,\n payload_json TEXT NOT NULL,\n status TEXT NOT NULL,\n attempts ${intType()} NOT NULL DEFAULT 0,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n`;\n}\n\nasync function ensureTables(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createRegistrationsSql = buildCreateRegistrationsSql();\n const createNotificationsSql = buildCreateNotificationsSql();\n if (isPostgres()) {\n // PG guard: probe via information_schema, only issue DDL if missing, bounded lock_timeout\n await ensureTableExists(\n \"integration_remote_push_registrations\",\n createRegistrationsSql,\n );\n await ensureIndexExists(\n \"idx_remote_push_token_hash\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_push_token_hash ON integration_remote_push_registrations(token_hash)`,\n );\n await ensureIndexExists(\n \"idx_remote_push_owner\",\n `CREATE INDEX IF NOT EXISTS idx_remote_push_owner ON integration_remote_push_registrations(owner_email, org_id, status)`,\n );\n await ensureTableExists(\n \"integration_remote_push_notifications\",\n createNotificationsSql,\n );\n await ensureIndexExists(\n \"idx_remote_push_notifications_owner\",\n `CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_owner ON integration_remote_push_notifications(owner_email, org_id, status, created_at)`,\n );\n return;\n }\n // SQLite (local dev): keep existing behavior\n await retryOnDdlRace(() => client.execute(createRegistrationsSql));\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_push_token_hash ON integration_remote_push_registrations(token_hash)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_push_owner ON integration_remote_push_registrations(owner_email, org_id, status)`,\n ),\n );\n\n await retryOnDdlRace(() => client.execute(createNotificationsSql));\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_owner ON integration_remote_push_notifications(owner_email, org_id, status, created_at)`,\n ),\n );\n })().catch((err) => {\n // Retry init on the next call after a failed startup.\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\nfunction rowToRegistration(\n row: Record<string, unknown>,\n): RemotePushRegistration {\n return {\n id: row.id as string,\n ownerEmail: row.owner_email as string,\n orgId: (row.org_id as string | null) ?? null,\n provider: row.provider as string,\n platform: (row.platform as string | null) ?? null,\n clientDeviceId: (row.client_device_id as string | null) ?? null,\n label: (row.label as string | null) ?? null,\n token: row.token as string,\n tokenHash: row.token_hash as string,\n status: row.status as RemotePushRegistration[\"status\"],\n lastSeenAt:\n row.last_seen_at == null ? null : Number(row.last_seen_at as number),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\nfunction rowToNotification(\n row: Record<string, unknown>,\n): RemotePushNotification {\n return {\n id: row.id as string,\n ownerEmail: row.owner_email as string,\n orgId: (row.org_id as string | null) ?? null,\n registrationId: row.registration_id as string,\n payload: parseJson(row.payload_json, null),\n status: row.status as RemotePushNotification[\"status\"],\n attempts: Number(row.attempts ?? 0),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\nexport function toPublicRemotePushRegistration(\n registration: RemotePushRegistration,\n): PublicRemotePushRegistration {\n return {\n id: registration.id,\n ownerEmail: registration.ownerEmail,\n orgId: registration.orgId,\n provider: registration.provider,\n platform: registration.platform,\n clientDeviceId: registration.clientDeviceId,\n label: registration.label,\n status: registration.status,\n lastSeenAt: registration.lastSeenAt,\n createdAt: registration.createdAt,\n updatedAt: registration.updatedAt,\n };\n}\n\nexport async function upsertRemotePushRegistration(input: {\n ownerEmail: string;\n orgId?: string | null;\n provider: string;\n token: string;\n platform?: string | null;\n clientDeviceId?: string | null;\n label?: string | null;\n}): Promise<RemotePushRegistration> {\n await ensureTables();\n const client = getDbExec();\n const now = Date.now();\n const tokenHash = await hashToken(input.token);\n const provider = sanitizeString(input.provider, 80) ?? \"unknown\";\n const platform = sanitizeString(input.platform, 80);\n const clientDeviceId = sanitizeString(input.clientDeviceId, 200);\n const label = sanitizeString(input.label, 200);\n\n const existing = await getRemotePushRegistrationByTokenHash(tokenHash);\n if (existing) {\n await client.execute({\n sql: `UPDATE integration_remote_push_registrations\n SET owner_email = ?,\n org_id = ?,\n provider = ?,\n platform = ?,\n client_device_id = ?,\n label = ?,\n token = ?,\n status = 'active',\n last_seen_at = ?,\n updated_at = ?\n WHERE token_hash = ?`,\n args: [\n input.ownerEmail,\n input.orgId ?? null,\n provider,\n platform,\n clientDeviceId,\n label,\n input.token,\n now,\n now,\n tokenHash,\n ],\n });\n const updated = await getRemotePushRegistrationByTokenHash(tokenHash);\n if (!updated) throw new Error(\"remote push registration update failed\");\n return updated;\n }\n\n const id = `remote-push-${now}-${randomHex(8)}`;\n await client.execute({\n sql: `INSERT INTO integration_remote_push_registrations\n (id, owner_email, org_id, provider, platform, client_device_id, label,\n token, token_hash, status, last_seen_at, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n input.ownerEmail,\n input.orgId ?? null,\n provider,\n platform,\n clientDeviceId,\n label,\n input.token,\n tokenHash,\n \"active\",\n now,\n now,\n now,\n ],\n });\n const registration = await getRemotePushRegistrationByTokenHash(tokenHash);\n if (!registration) throw new Error(\"remote push registration insert failed\");\n return registration;\n}\n\nexport async function listRemotePushRegistrationsForOwner(input: {\n ownerEmail: string;\n orgId?: string | null;\n includeInactive?: boolean;\n limit?: number;\n}): Promise<RemotePushRegistration[]> {\n await ensureTables();\n const limit = Math.max(1, Math.min(input.limit ?? 50, 100));\n const statusClause = input.includeInactive ? \"\" : \" AND status = 'active'\";\n if (!Object.prototype.hasOwnProperty.call(input, \"orgId\")) {\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_push_registrations\n WHERE owner_email = ?${statusClause}\n ORDER BY COALESCE(last_seen_at, updated_at) DESC\n LIMIT ?`,\n args: [input.ownerEmail, limit],\n });\n return rows.map((row) => rowToRegistration(row as Record<string, unknown>));\n }\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_push_registrations\n WHERE owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)${statusClause}\n ORDER BY COALESCE(last_seen_at, updated_at) DESC\n LIMIT ?`,\n args: [input.ownerEmail, input.orgId ?? null, input.orgId ?? null, limit],\n });\n return rows.map((row) => rowToRegistration(row as Record<string, unknown>));\n}\n\nexport async function unregisterRemotePushRegistrationForOwner(input: {\n ownerEmail: string;\n orgId?: string | null;\n id?: string | null;\n token?: string | null;\n}): Promise<boolean> {\n await ensureTables();\n const tokenHash = input.token ? await hashToken(input.token) : null;\n if (!input.id && !tokenHash) return false;\n const now = Date.now();\n const result = await getDbExec().execute({\n sql: `UPDATE integration_remote_push_registrations\n SET status = 'inactive', updated_at = ?\n WHERE owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)\n AND (${input.id ? \"id = ?\" : \"0 = 1\"} OR ${\n tokenHash ? \"token_hash = ?\" : \"0 = 1\"\n })`,\n args: [\n now,\n input.ownerEmail,\n input.orgId ?? null,\n input.orgId ?? null,\n ...(input.id ? [input.id] : []),\n ...(tokenHash ? [tokenHash] : []),\n ],\n });\n return (result.rowsAffected ?? (result as any).rowCount ?? 0) > 0;\n}\n\nexport async function queueRemotePushNotifications(input: {\n ownerEmail: string;\n orgId?: string | null;\n payload: unknown;\n}): Promise<{ queued: number }> {\n await ensureTables();\n const registrations = await listRemotePushRegistrationsForOwner({\n ownerEmail: input.ownerEmail,\n orgId: input.orgId ?? null,\n limit: 100,\n });\n const client = getDbExec();\n const now = Date.now();\n let queued = 0;\n for (const registration of registrations) {\n const id = `remote-push-notification-${now}-${randomHex(8)}`;\n const result = await client.execute({\n sql: `INSERT INTO integration_remote_push_notifications\n (id, owner_email, org_id, registration_id, payload_json, status,\n attempts, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n input.ownerEmail,\n input.orgId ?? null,\n registration.id,\n JSON.stringify(input.payload ?? null),\n \"pending\",\n 0,\n now,\n now,\n ],\n });\n queued += result.rowsAffected ?? (result as any).rowCount ?? 0;\n }\n return { queued };\n}\n\nexport async function listRemotePushNotificationsForOwner(input: {\n ownerEmail: string;\n orgId?: string | null;\n status?: RemotePushNotification[\"status\"];\n limit?: number;\n}): Promise<RemotePushNotification[]> {\n await ensureTables();\n const limit = Math.max(1, Math.min(input.limit ?? 50, 100));\n const statusClause = input.status ? \" AND status = ?\" : \"\";\n const args: Array<string | number | null> = [\n input.ownerEmail,\n input.orgId ?? null,\n input.orgId ?? null,\n ];\n if (input.status) args.push(input.status);\n args.push(limit);\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_push_notifications\n WHERE owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)${statusClause}\n ORDER BY created_at DESC\n LIMIT ?`,\n args,\n });\n return rows.map((row) => rowToNotification(row as Record<string, unknown>));\n}\n\nasync function getRemotePushRegistrationByTokenHash(\n tokenHash: string,\n): Promise<RemotePushRegistration | null> {\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_push_registrations\n WHERE token_hash = ?\n LIMIT 1`,\n args: [tokenHash],\n });\n return rows[0] ? rowToRegistration(rows[0] as Record<string, unknown>) : null;\n}\n\nasync function hashToken(token: string): Promise<string> {\n const bytes = new TextEncoder().encode(token);\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", bytes);\n return Array.from(new Uint8Array(digest))\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction randomHex(byteLength: number): string {\n const bytes = new Uint8Array(byteLength);\n globalThis.crypto.getRandomValues(bytes);\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction sanitizeString(\n value: string | null | undefined,\n max: number,\n): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed ? trimmed.slice(0, max) : null;\n}\n\nfunction parseJson(value: unknown, fallback: unknown): unknown {\n if (value == null) return fallback;\n try {\n return JSON.parse(String(value));\n } catch {\n return fallback;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remote-push-store.js","sourceRoot":"","sources":["../../src/integrations/remote-push-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getDbExec,\n isPostgres,\n intType,\n retryOnDdlRace,\n} from \"../db/client.js\";\nimport {\n ensureColumnExists,\n ensureIndexExists,\n ensureTableExists,\n} from \"../db/ddl-guard.js\";\nimport { isDuplicateColumnError } from \"../db/migrations.js\";\nimport type {\n PublicRemotePushRegistration,\n RemotePushNotification,\n RemotePushRegistration,\n} from \"./remote-types.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\n// Build the CREATE SQL lazily (not at module scope) so intType() runs at\n// RUNTIME, not import time — a module-scope call breaks any consumer whose\n// db/client mock doesn't stub intType (e.g. db-admin specs).\nfunction buildCreateRegistrationsSql(): string {\n return `\n CREATE TABLE IF NOT EXISTS integration_remote_push_registrations (\n id TEXT PRIMARY KEY,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n provider TEXT NOT NULL,\n platform TEXT,\n client_device_id TEXT,\n label TEXT,\n token TEXT NOT NULL,\n token_hash TEXT NOT NULL,\n status TEXT NOT NULL,\n last_seen_at ${intType()},\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n`;\n}\n\nfunction buildCreateNotificationsSql(): string {\n return `\n CREATE TABLE IF NOT EXISTS integration_remote_push_notifications (\n id TEXT PRIMARY KEY,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n registration_id TEXT NOT NULL,\n payload_json TEXT NOT NULL,\n status TEXT NOT NULL,\n attempts ${intType()} NOT NULL DEFAULT 0,\n provider_ticket_id TEXT,\n next_attempt_at ${intType()} NOT NULL DEFAULT 0,\n last_error TEXT,\n delivered_at ${intType()},\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n`;\n}\n\nasync function ensureTables(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createRegistrationsSql = buildCreateRegistrationsSql();\n const createNotificationsSql = buildCreateNotificationsSql();\n if (isPostgres()) {\n // PG guard: probe via information_schema, only issue DDL if missing, bounded lock_timeout\n await ensureTableExists(\n \"integration_remote_push_registrations\",\n createRegistrationsSql,\n );\n await ensureIndexExists(\n \"idx_remote_push_token_hash\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_push_token_hash ON integration_remote_push_registrations(token_hash)`,\n );\n await ensureIndexExists(\n \"idx_remote_push_owner\",\n `CREATE INDEX IF NOT EXISTS idx_remote_push_owner ON integration_remote_push_registrations(owner_email, org_id, status)`,\n );\n await ensureTableExists(\n \"integration_remote_push_notifications\",\n createNotificationsSql,\n );\n await ensureIndexExists(\n \"idx_remote_push_notifications_owner\",\n `CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_owner ON integration_remote_push_notifications(owner_email, org_id, status, created_at)`,\n );\n await ensureColumnExists(\n \"integration_remote_push_notifications\",\n \"provider_ticket_id\",\n `ALTER TABLE integration_remote_push_notifications ADD COLUMN IF NOT EXISTS provider_ticket_id TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_push_notifications\",\n \"next_attempt_at\",\n `ALTER TABLE integration_remote_push_notifications ADD COLUMN IF NOT EXISTS next_attempt_at ${intType()} NOT NULL DEFAULT 0`,\n );\n await ensureColumnExists(\n \"integration_remote_push_notifications\",\n \"last_error\",\n `ALTER TABLE integration_remote_push_notifications ADD COLUMN IF NOT EXISTS last_error TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_push_notifications\",\n \"delivered_at\",\n `ALTER TABLE integration_remote_push_notifications ADD COLUMN IF NOT EXISTS delivered_at ${intType()}`,\n );\n await ensureIndexExists(\n \"idx_remote_push_notifications_delivery\",\n `CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_delivery ON integration_remote_push_notifications(status, next_attempt_at, updated_at)`,\n );\n return;\n }\n // SQLite (local dev): keep existing behavior\n await retryOnDdlRace(() => client.execute(createRegistrationsSql));\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_push_token_hash ON integration_remote_push_registrations(token_hash)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_push_owner ON integration_remote_push_registrations(owner_email, org_id, status)`,\n ),\n );\n\n await retryOnDdlRace(() => client.execute(createNotificationsSql));\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_owner ON integration_remote_push_notifications(owner_email, org_id, status, created_at)`,\n ),\n );\n await addNotificationColumnIfMissing(\"provider_ticket_id\", \"TEXT\");\n await addNotificationColumnIfMissing(\n \"next_attempt_at\",\n `${intType()} NOT NULL DEFAULT 0`,\n );\n await addNotificationColumnIfMissing(\"last_error\", \"TEXT\");\n await addNotificationColumnIfMissing(\"delivered_at\", intType());\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_push_notifications_delivery ON integration_remote_push_notifications(status, next_attempt_at, updated_at)`,\n ),\n );\n })().catch((err) => {\n // Retry init on the next call after a failed startup.\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\nasync function addNotificationColumnIfMissing(\n name: string,\n definition: string,\n): Promise<void> {\n try {\n await retryOnDdlRace(() =>\n getDbExec().execute(\n `ALTER TABLE integration_remote_push_notifications ADD COLUMN ${name} ${definition}`,\n ),\n );\n } catch (error) {\n if (!isDuplicateColumnError(error)) throw error;\n }\n}\n\nfunction rowToRegistration(\n row: Record<string, unknown>,\n): RemotePushRegistration {\n return {\n id: row.id as string,\n ownerEmail: row.owner_email as string,\n orgId: (row.org_id as string | null) ?? null,\n provider: row.provider as string,\n platform: (row.platform as string | null) ?? null,\n clientDeviceId: (row.client_device_id as string | null) ?? null,\n label: (row.label as string | null) ?? null,\n token: row.token as string,\n tokenHash: row.token_hash as string,\n status: row.status as RemotePushRegistration[\"status\"],\n lastSeenAt:\n row.last_seen_at == null ? null : Number(row.last_seen_at as number),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\nfunction rowToNotification(\n row: Record<string, unknown>,\n): RemotePushNotification {\n const storedStatus = String(row.status ?? \"pending\");\n const status =\n storedStatus === \"delivered\" || storedStatus === \"failed\"\n ? storedStatus\n : \"pending\";\n return {\n id: row.id as string,\n ownerEmail: row.owner_email as string,\n orgId: (row.org_id as string | null) ?? null,\n registrationId: row.registration_id as string,\n payload: parseJson(row.payload_json, null),\n status,\n attempts: Number(row.attempts ?? 0),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\nexport function toPublicRemotePushRegistration(\n registration: RemotePushRegistration,\n): PublicRemotePushRegistration {\n return {\n id: registration.id,\n ownerEmail: registration.ownerEmail,\n orgId: registration.orgId,\n provider: registration.provider,\n platform: registration.platform,\n clientDeviceId: registration.clientDeviceId,\n label: registration.label,\n status: registration.status,\n lastSeenAt: registration.lastSeenAt,\n createdAt: registration.createdAt,\n updatedAt: registration.updatedAt,\n };\n}\n\nexport async function upsertRemotePushRegistration(input: {\n ownerEmail: string;\n orgId?: string | null;\n provider: string;\n token: string;\n platform?: string | null;\n clientDeviceId?: string | null;\n label?: string | null;\n}): Promise<RemotePushRegistration> {\n await ensureTables();\n const client = getDbExec();\n const now = Date.now();\n const tokenHash = await hashToken(input.token);\n const provider = sanitizeString(input.provider, 80) ?? \"unknown\";\n const platform = sanitizeString(input.platform, 80);\n const clientDeviceId = sanitizeString(input.clientDeviceId, 200);\n const label = sanitizeString(input.label, 200);\n\n const existing = await getRemotePushRegistrationByTokenHash(tokenHash);\n if (existing) {\n await client.execute({\n sql: `UPDATE integration_remote_push_registrations\n SET owner_email = ?,\n org_id = ?,\n provider = ?,\n platform = ?,\n client_device_id = ?,\n label = ?,\n token = ?,\n status = 'active',\n last_seen_at = ?,\n updated_at = ?\n WHERE token_hash = ?`,\n args: [\n input.ownerEmail,\n input.orgId ?? null,\n provider,\n platform,\n clientDeviceId,\n label,\n input.token,\n now,\n now,\n tokenHash,\n ],\n });\n const updated = await getRemotePushRegistrationByTokenHash(tokenHash);\n if (!updated) throw new Error(\"remote push registration update failed\");\n return updated;\n }\n\n const id = `remote-push-${now}-${randomHex(8)}`;\n await client.execute({\n sql: `INSERT INTO integration_remote_push_registrations\n (id, owner_email, org_id, provider, platform, client_device_id, label,\n token, token_hash, status, last_seen_at, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n input.ownerEmail,\n input.orgId ?? null,\n provider,\n platform,\n clientDeviceId,\n label,\n input.token,\n tokenHash,\n \"active\",\n now,\n now,\n now,\n ],\n });\n const registration = await getRemotePushRegistrationByTokenHash(tokenHash);\n if (!registration) throw new Error(\"remote push registration insert failed\");\n return registration;\n}\n\nexport async function listRemotePushRegistrationsForOwner(input: {\n ownerEmail: string;\n orgId?: string | null;\n includeInactive?: boolean;\n limit?: number;\n}): Promise<RemotePushRegistration[]> {\n await ensureTables();\n const limit = Math.max(1, Math.min(input.limit ?? 50, 100));\n const statusClause = input.includeInactive ? \"\" : \" AND status = 'active'\";\n if (!Object.prototype.hasOwnProperty.call(input, \"orgId\")) {\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_push_registrations\n WHERE owner_email = ?${statusClause}\n ORDER BY COALESCE(last_seen_at, updated_at) DESC\n LIMIT ?`,\n args: [input.ownerEmail, limit],\n });\n return rows.map((row) => rowToRegistration(row as Record<string, unknown>));\n }\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_push_registrations\n WHERE owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)${statusClause}\n ORDER BY COALESCE(last_seen_at, updated_at) DESC\n LIMIT ?`,\n args: [input.ownerEmail, input.orgId ?? null, input.orgId ?? null, limit],\n });\n return rows.map((row) => rowToRegistration(row as Record<string, unknown>));\n}\n\nexport async function unregisterRemotePushRegistrationForOwner(input: {\n ownerEmail: string;\n orgId?: string | null;\n id?: string | null;\n token?: string | null;\n}): Promise<boolean> {\n await ensureTables();\n const tokenHash = input.token ? await hashToken(input.token) : null;\n if (!input.id && !tokenHash) return false;\n const now = Date.now();\n const result = await getDbExec().execute({\n sql: `UPDATE integration_remote_push_registrations\n SET status = 'inactive', updated_at = ?\n WHERE owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)\n AND (${input.id ? \"id = ?\" : \"0 = 1\"} OR ${\n tokenHash ? \"token_hash = ?\" : \"0 = 1\"\n })`,\n args: [\n now,\n input.ownerEmail,\n input.orgId ?? null,\n input.orgId ?? null,\n ...(input.id ? [input.id] : []),\n ...(tokenHash ? [tokenHash] : []),\n ],\n });\n return (result.rowsAffected ?? (result as any).rowCount ?? 0) > 0;\n}\n\nexport async function queueRemotePushNotifications(input: {\n ownerEmail: string;\n orgId?: string | null;\n payload: unknown;\n}): Promise<{ queued: number }> {\n await ensureTables();\n const registrations = await listRemotePushRegistrationsForOwner({\n ownerEmail: input.ownerEmail,\n orgId: input.orgId ?? null,\n limit: 100,\n });\n if (registrations.length === 0) return { queued: 0 };\n\n const client = getDbExec();\n const now = Date.now();\n const payload = JSON.stringify(input.payload ?? null);\n const values = registrations.map(\n () => \"(?, ?, ?, ?, ?, 'pending', 0, ?, ?, ?)\",\n );\n const args = registrations.flatMap((registration) => [\n `remote-push-notification-${now}-${randomHex(8)}`,\n input.ownerEmail,\n input.orgId ?? null,\n registration.id,\n payload,\n now,\n now,\n now,\n ]);\n const result = await client.execute({\n sql: `INSERT INTO integration_remote_push_notifications\n (id, owner_email, org_id, registration_id, payload_json, status,\n attempts, next_attempt_at, created_at, updated_at)\n VALUES ${values.join(\", \")}`,\n args,\n });\n return {\n queued: result.rowsAffected ?? (result as any).rowCount ?? 0,\n };\n}\n\nexport async function listRemotePushNotificationsForOwner(input: {\n ownerEmail: string;\n orgId?: string | null;\n status?: RemotePushNotification[\"status\"];\n limit?: number;\n}): Promise<RemotePushNotification[]> {\n await ensureTables();\n const limit = Math.max(1, Math.min(input.limit ?? 50, 100));\n const statusClause = input.status\n ? input.status === \"pending\"\n ? \" AND status IN ('pending', 'sending', 'sent', 'checking')\"\n : \" AND status = ?\"\n : \"\";\n const args: Array<string | number | null> = [\n input.ownerEmail,\n input.orgId ?? null,\n input.orgId ?? null,\n ];\n if (input.status && input.status !== \"pending\") args.push(input.status);\n args.push(limit);\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_push_notifications\n WHERE owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)${statusClause}\n ORDER BY created_at DESC\n LIMIT ?`,\n args,\n });\n return rows.map((row) => rowToNotification(row as Record<string, unknown>));\n}\n\nexport interface ClaimedRemotePushDelivery {\n id: string;\n registrationId: string;\n provider: string;\n token: string;\n payload: unknown;\n phase: \"send\" | \"receipt\";\n providerTicketId: string | null;\n attempts: number;\n}\n\nexport async function claimNextRemotePushDelivery(input?: {\n now?: number;\n staleAfterMs?: number;\n}): Promise<ClaimedRemotePushDelivery | null> {\n await ensureTables();\n const client = getDbExec();\n const now = input?.now ?? Date.now();\n const staleBefore = now - Math.max(30_000, input?.staleAfterMs ?? 120_000);\n const { rows } = await client.execute({\n sql: `SELECT n.id, n.registration_id, n.payload_json, n.status, n.attempts,\n n.provider_ticket_id, n.updated_at, r.provider, r.token\n FROM integration_remote_push_notifications n\n INNER JOIN integration_remote_push_registrations r\n ON r.id = n.registration_id\n WHERE r.status = 'active'\n AND (\n (n.status IN ('pending', 'sent') AND n.next_attempt_at <= ?)\n OR (n.status IN ('sending', 'checking') AND n.updated_at <= ?)\n )\n ORDER BY n.created_at ASC\n LIMIT 1`,\n args: [now, staleBefore],\n });\n const row = rows[0] as Record<string, unknown> | undefined;\n if (!row) return null;\n\n const previousStatus = String(row.status ?? \"pending\");\n const providerTicketId = sanitizeString(\n row.provider_ticket_id as string | null,\n 200,\n );\n const phase =\n (previousStatus === \"sent\" || previousStatus === \"checking\") &&\n providerTicketId\n ? \"receipt\"\n : \"send\";\n const claimedStatus = phase === \"receipt\" ? \"checking\" : \"sending\";\n const result = await client.execute({\n sql: `UPDATE integration_remote_push_notifications\n SET status = ?, attempts = attempts + 1, updated_at = ?\n WHERE id = ? AND status = ? AND updated_at = ?`,\n args: [\n claimedStatus,\n now,\n row.id as string,\n previousStatus,\n Number(row.updated_at),\n ],\n });\n if ((result.rowsAffected ?? (result as any).rowCount ?? 0) !== 1) return null;\n\n return {\n id: row.id as string,\n registrationId: row.registration_id as string,\n provider: String(row.provider ?? \"unknown\"),\n token: row.token as string,\n payload: parseJson(row.payload_json, null),\n phase,\n providerTicketId,\n attempts: Number(row.attempts ?? 0) + 1,\n };\n}\n\nexport async function markRemotePushTicketAccepted(input: {\n id: string;\n providerTicketId: string;\n checkAfter: number;\n}): Promise<boolean> {\n await ensureTables();\n const now = Date.now();\n const result = await getDbExec().execute({\n sql: `UPDATE integration_remote_push_notifications\n SET status = 'sent', provider_ticket_id = ?, next_attempt_at = ?,\n last_error = NULL, updated_at = ?\n WHERE id = ? AND status = 'sending'`,\n args: [input.providerTicketId, input.checkAfter, now, input.id],\n });\n return (result.rowsAffected ?? (result as any).rowCount ?? 0) === 1;\n}\n\nexport async function markRemotePushDelivered(id: string): Promise<boolean> {\n await ensureTables();\n const now = Date.now();\n const result = await getDbExec().execute({\n sql: `UPDATE integration_remote_push_notifications\n SET status = 'delivered', last_error = NULL, delivered_at = ?,\n updated_at = ?\n WHERE id = ? AND status = 'checking'`,\n args: [now, now, id],\n });\n return (result.rowsAffected ?? (result as any).rowCount ?? 0) === 1;\n}\n\nexport async function retryRemotePushDelivery(input: {\n id: string;\n phase: \"send\" | \"receipt\";\n retryAt: number;\n errorCode: string;\n resend?: boolean;\n}): Promise<boolean> {\n await ensureTables();\n const currentStatus = input.phase === \"receipt\" ? \"checking\" : \"sending\";\n const retryStatus =\n input.phase === \"receipt\" && !input.resend ? \"sent\" : \"pending\";\n const clearTicketClause = input.resend ? \", provider_ticket_id = NULL\" : \"\";\n const result = await getDbExec().execute({\n sql: `UPDATE integration_remote_push_notifications\n SET status = ?, next_attempt_at = ?, last_error = ?${clearTicketClause},\n updated_at = ?\n WHERE id = ? AND status = ?`,\n args: [\n retryStatus,\n input.retryAt,\n sanitizeString(input.errorCode, 160) ?? \"temporary_error\",\n Date.now(),\n input.id,\n currentStatus,\n ],\n });\n return (result.rowsAffected ?? (result as any).rowCount ?? 0) === 1;\n}\n\nexport async function failRemotePushDelivery(input: {\n id: string;\n phase: \"send\" | \"receipt\";\n errorCode: string;\n}): Promise<boolean> {\n await ensureTables();\n const currentStatus = input.phase === \"receipt\" ? \"checking\" : \"sending\";\n const result = await getDbExec().execute({\n sql: `UPDATE integration_remote_push_notifications\n SET status = 'failed', last_error = ?, updated_at = ?\n WHERE id = ? AND status = ?`,\n args: [\n sanitizeString(input.errorCode, 160) ?? \"delivery_failed\",\n Date.now(),\n input.id,\n currentStatus,\n ],\n });\n return (result.rowsAffected ?? (result as any).rowCount ?? 0) === 1;\n}\n\nexport async function deactivateRemotePushRegistration(\n registrationId: string,\n): Promise<boolean> {\n await ensureTables();\n const client = getDbExec();\n const now = Date.now();\n const result = await client.execute({\n sql: `UPDATE integration_remote_push_registrations\n SET status = 'inactive', updated_at = ?\n WHERE id = ? AND status = 'active'`,\n args: [now, registrationId],\n });\n await client.execute({\n sql: `UPDATE integration_remote_push_notifications\n SET status = 'failed', last_error = 'registration_inactive',\n updated_at = ?\n WHERE registration_id = ?\n AND status IN ('pending', 'sending', 'sent', 'checking')`,\n args: [now, registrationId],\n });\n return (result.rowsAffected ?? (result as any).rowCount ?? 0) === 1;\n}\n\nasync function getRemotePushRegistrationByTokenHash(\n tokenHash: string,\n): Promise<RemotePushRegistration | null> {\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_push_registrations\n WHERE token_hash = ?\n LIMIT 1`,\n args: [tokenHash],\n });\n return rows[0] ? rowToRegistration(rows[0] as Record<string, unknown>) : null;\n}\n\nasync function hashToken(token: string): Promise<string> {\n const bytes = new TextEncoder().encode(token);\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", bytes);\n return Array.from(new Uint8Array(digest))\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction randomHex(byteLength: number): string {\n const bytes = new Uint8Array(byteLength);\n globalThis.crypto.getRandomValues(bytes);\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction sanitizeString(\n value: string | null | undefined,\n max: number,\n): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed ? trimmed.slice(0, max) : null;\n}\n\nfunction parseJson(value: unknown, fallback: unknown): unknown {\n if (value == null) return fallback;\n try {\n return JSON.parse(String(value));\n } catch {\n return fallback;\n }\n}\n"]}
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
* DELETE /_agent-native/notifications/:id — delete
|
|
12
12
|
*/
|
|
13
13
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
14
|
+
error?: undefined;
|
|
14
15
|
count: number;
|
|
15
16
|
updated?: undefined;
|
|
16
|
-
error?: undefined;
|
|
17
17
|
ok?: undefined;
|
|
18
18
|
} | {
|
|
19
|
+
error?: undefined;
|
|
19
20
|
count?: undefined;
|
|
20
21
|
updated: number;
|
|
21
|
-
error?: undefined;
|
|
22
22
|
ok?: undefined;
|
|
23
23
|
} | {
|
|
24
24
|
count?: undefined;
|
|
@@ -26,9 +26,9 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
|
|
|
26
26
|
error: string;
|
|
27
27
|
ok?: undefined;
|
|
28
28
|
} | {
|
|
29
|
+
error?: undefined;
|
|
29
30
|
count?: undefined;
|
|
30
31
|
updated?: undefined;
|
|
31
32
|
ok: boolean;
|
|
32
|
-
error?: undefined;
|
|
33
33
|
}>>;
|
|
34
34
|
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -73,6 +73,7 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
73
73
|
offset?: unknown;
|
|
74
74
|
limit?: unknown;
|
|
75
75
|
}, {
|
|
76
|
+
deleted?: undefined;
|
|
76
77
|
jobs: {
|
|
77
78
|
id: string;
|
|
78
79
|
name: string;
|
|
@@ -83,7 +84,6 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
83
84
|
updatedAt: string;
|
|
84
85
|
}[];
|
|
85
86
|
total: number;
|
|
86
|
-
deleted?: undefined;
|
|
87
87
|
jobId?: undefined;
|
|
88
88
|
} | {
|
|
89
89
|
jobs?: undefined;
|
|
@@ -91,9 +91,9 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
91
91
|
deleted: boolean;
|
|
92
92
|
jobId: string;
|
|
93
93
|
} | {
|
|
94
|
+
deleted?: undefined;
|
|
94
95
|
jobs?: undefined;
|
|
95
96
|
total?: undefined;
|
|
96
|
-
deleted?: undefined;
|
|
97
97
|
jobId?: undefined;
|
|
98
98
|
hits: Record<string, unknown>[];
|
|
99
99
|
offset: number;
|
|
@@ -49,11 +49,11 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
|
|
|
49
49
|
}>;
|
|
50
50
|
/** DELETE /_agent-native/resources/:id — delete a resource */
|
|
51
51
|
export declare function handleDeleteResource(event: any): Promise<{
|
|
52
|
-
error: string;
|
|
53
52
|
ok?: undefined;
|
|
53
|
+
error: string;
|
|
54
54
|
} | {
|
|
55
|
-
ok: boolean;
|
|
56
55
|
error?: undefined;
|
|
56
|
+
ok: boolean;
|
|
57
57
|
}>;
|
|
58
58
|
/** POST /_agent-native/resources/upload — upload a file as a resource */
|
|
59
59
|
export declare function handleUploadResource(event: any): Promise<import("./store.js").Resource | {
|
|
@@ -74,10 +74,10 @@ export declare function handleUploadResource(event: any): Promise<import("./stor
|
|
|
74
74
|
runId: string | null;
|
|
75
75
|
expiresAt: number | null;
|
|
76
76
|
metadata: string | null;
|
|
77
|
+
error?: undefined;
|
|
77
78
|
url: string;
|
|
78
79
|
provider: string;
|
|
79
80
|
storageSetupRequired?: undefined;
|
|
80
|
-
error?: undefined;
|
|
81
81
|
} | {
|
|
82
82
|
error: string;
|
|
83
83
|
storageSetupRequired: boolean;
|
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
|
-
status?: undefined;
|
|
38
37
|
ok?: undefined;
|
|
38
|
+
status?: undefined;
|
|
39
39
|
} | {
|
|
40
|
+
error?: undefined;
|
|
40
41
|
ok: boolean;
|
|
41
42
|
status: string;
|
|
42
|
-
error?: undefined;
|
|
43
43
|
} | {
|
|
44
|
+
ok?: undefined;
|
|
44
45
|
error: string;
|
|
45
46
|
removed?: undefined;
|
|
46
|
-
ok?: undefined;
|
|
47
47
|
} | {
|
|
48
|
+
error?: undefined;
|
|
48
49
|
ok: boolean;
|
|
49
50
|
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;
|
|
57
58
|
error: string;
|
|
58
59
|
note?: undefined;
|
|
59
|
-
ok?: undefined;
|
|
60
60
|
} | {
|
|
61
|
+
error?: undefined;
|
|
61
62
|
ok: boolean;
|
|
62
63
|
note?: undefined;
|
|
63
|
-
error?: undefined;
|
|
64
64
|
} | {
|
|
65
|
+
error?: undefined;
|
|
65
66
|
ok: boolean;
|
|
66
67
|
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;
|
|
98
99
|
ok: boolean;
|
|
99
100
|
key: string;
|
|
100
|
-
error?: undefined;
|
|
101
101
|
} | {
|
|
102
|
+
error?: undefined;
|
|
102
103
|
ok: boolean;
|
|
103
104
|
removed: boolean;
|
|
104
|
-
error?: undefined;
|
|
105
105
|
}>>;
|
|
106
106
|
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -27,11 +27,11 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
|
|
|
27
27
|
export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
28
28
|
error: any;
|
|
29
29
|
} | {
|
|
30
|
+
error?: undefined;
|
|
30
31
|
ok: boolean;
|
|
31
32
|
key: string;
|
|
32
33
|
baseUrlKey?: string;
|
|
33
34
|
scope: AgentEngineApiKeyScope;
|
|
34
|
-
error?: undefined;
|
|
35
35
|
}>>;
|
|
36
36
|
export {};
|
|
37
37
|
//# sourceMappingURL=agent-engine-api-key-route.d.ts.map
|
|
@@ -881,7 +881,7 @@ async function createBetterAuthInstance(config) {
|
|
|
881
881
|
async function buildDatabaseConfig(dialect) {
|
|
882
882
|
if (dialect === "postgres") {
|
|
883
883
|
const url = getDatabaseUrl();
|
|
884
|
-
const { isNeonUrl } = await import("../db/create-get-db.js");
|
|
884
|
+
const { buildResilientNeonPool, buildResilientPostgresJsClient, isNeonUrl, } = await import("../db/create-get-db.js");
|
|
885
885
|
if (isPgliteUrl(url)) {
|
|
886
886
|
const { drizzle } = await loadPgliteDrizzle();
|
|
887
887
|
const client = await getPgliteClient(url);
|
|
@@ -907,7 +907,9 @@ async function buildDatabaseConfig(dialect) {
|
|
|
907
907
|
});
|
|
908
908
|
attachNeonPoolErrorLogger(_neonAuthPool, "db/neon-auth");
|
|
909
909
|
const { drizzle } = await import("drizzle-orm/neon-serverless");
|
|
910
|
-
const db = drizzle(_neonAuthPool, {
|
|
910
|
+
const db = drizzle(buildResilientNeonPool(_neonAuthPool), {
|
|
911
|
+
schema: pgAuthSchema,
|
|
912
|
+
});
|
|
911
913
|
const { drizzleAdapter } = await import("better-auth/adapters/drizzle");
|
|
912
914
|
return drizzleAdapter(db, {
|
|
913
915
|
provider: "pg",
|
|
@@ -922,7 +924,9 @@ async function buildDatabaseConfig(dialect) {
|
|
|
922
924
|
const { default: postgres } = await import("postgres");
|
|
923
925
|
const sql = postgres(url, pgPoolOptions(url));
|
|
924
926
|
const { drizzle } = await import("drizzle-orm/postgres-js");
|
|
925
|
-
const db = drizzle(sql, {
|
|
927
|
+
const db = drizzle(buildResilientPostgresJsClient(sql), {
|
|
928
|
+
schema: pgAuthSchema,
|
|
929
|
+
});
|
|
926
930
|
const { drizzleAdapter } = await import("better-auth/adapters/drizzle");
|
|
927
931
|
return drizzleAdapter(db, {
|
|
928
932
|
provider: "pg",
|