@agent-native/core 0.93.0 → 0.94.1
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 +31 -0
- package/corpus/core/docs/content/a2a-protocol.mdx +21 -5
- package/corpus/core/docs/content/actions.mdx +9 -23
- package/corpus/core/docs/content/agent-mentions.mdx +31 -29
- package/corpus/core/docs/content/agent-native-toolkit.mdx +15 -6
- package/corpus/core/docs/content/agent-surfaces.mdx +9 -13
- package/corpus/core/docs/content/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/authentication.mdx +10 -3
- package/corpus/core/docs/content/automation-connectors.mdx +82 -39
- package/corpus/core/docs/content/automations.mdx +17 -3
- package/corpus/core/docs/content/blueprint-installer.mdx +11 -4
- package/corpus/core/docs/content/cli-adapters.mdx +9 -6
- package/corpus/core/docs/content/client.mdx +16 -0
- package/corpus/core/docs/content/cloneable-saas.mdx +14 -11
- package/corpus/core/docs/content/code-agents-ui.mdx +65 -0
- package/corpus/core/docs/content/components.mdx +30 -14
- package/corpus/core/docs/content/context-awareness.mdx +27 -15
- package/corpus/core/docs/content/creating-templates.mdx +15 -9
- package/corpus/core/docs/content/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/data-programs.mdx +1 -1
- package/corpus/core/docs/content/database.mdx +17 -5
- package/corpus/core/docs/content/deployment.mdx +19 -18
- package/corpus/core/docs/content/dispatch.mdx +6 -2
- package/corpus/core/docs/content/drop-in-agent.mdx +10 -4
- package/corpus/core/docs/content/durable-background-runs.mdx +9 -5
- package/corpus/core/docs/content/durable-resume.mdx +9 -4
- package/corpus/core/docs/content/embedding-sdk.mdx +26 -8
- package/corpus/core/docs/content/evals.mdx +3 -5
- package/corpus/core/docs/content/extensions.mdx +22 -9
- package/corpus/core/docs/content/external-agents.mdx +25 -34
- package/corpus/core/docs/content/faq.mdx +8 -0
- package/corpus/core/docs/content/file-uploads.mdx +12 -3
- package/corpus/core/docs/content/frames.mdx +16 -0
- package/corpus/core/docs/content/generative-ui.mdx +1 -1
- package/corpus/core/docs/content/getting-started.mdx +34 -21
- package/corpus/core/docs/content/harness-agents.mdx +8 -4
- package/corpus/core/docs/content/human-approval.mdx +8 -3
- package/corpus/core/docs/content/internationalization.mdx +9 -4
- package/corpus/core/docs/content/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/local-file-mode.mdx +14 -8
- package/corpus/core/docs/content/locales/ar-SA/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/ar-SA/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/ar-SA/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/ar-SA/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/components.mdx +11 -1
- package/corpus/core/docs/content/locales/ar-SA/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/ar-SA/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/ar-SA/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +2 -7
- package/corpus/core/docs/content/locales/ar-SA/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/ar-SA/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/ar-SA/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/ar-SA/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/ar-SA/server.mdx +17 -10
- package/corpus/core/docs/content/locales/ar-SA/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/ar-SA/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/ar-SA/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/ar-SA/template-clips.mdx +3 -3
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/ar-SA/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/ar-SA/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/ar-SA/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/ar-SA/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/ar-SA/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/ar-SA/workspace.mdx +19 -18
- package/corpus/core/docs/content/locales/de-DE/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/de-DE/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/de-DE/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/de-DE/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/components.mdx +11 -1
- package/corpus/core/docs/content/locales/de-DE/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/de-DE/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/de-DE/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +3 -7
- package/corpus/core/docs/content/locales/de-DE/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/de-DE/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/de-DE/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/de-DE/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/de-DE/server.mdx +18 -10
- package/corpus/core/docs/content/locales/de-DE/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/de-DE/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/de-DE/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/de-DE/template-clips.mdx +3 -3
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/de-DE/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/de-DE/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/de-DE/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/de-DE/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/de-DE/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/de-DE/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/de-DE/workspace.mdx +19 -18
- package/corpus/core/docs/content/locales/es-ES/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/es-ES/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/es-ES/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/es-ES/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/components.mdx +11 -1
- package/corpus/core/docs/content/locales/es-ES/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/es-ES/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/es-ES/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +3 -7
- package/corpus/core/docs/content/locales/es-ES/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/es-ES/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/es-ES/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/es-ES/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/es-ES/server.mdx +17 -10
- package/corpus/core/docs/content/locales/es-ES/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/es-ES/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/es-ES/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/es-ES/template-clips.mdx +3 -3
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/es-ES/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/es-ES/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/es-ES/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/es-ES/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/es-ES/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/es-ES/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/es-ES/workspace.mdx +19 -18
- package/corpus/core/docs/content/locales/fr-FR/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/fr-FR/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/fr-FR/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/fr-FR/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/components.mdx +11 -1
- package/corpus/core/docs/content/locales/fr-FR/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/fr-FR/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/fr-FR/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +3 -7
- package/corpus/core/docs/content/locales/fr-FR/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/fr-FR/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/fr-FR/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/fr-FR/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/fr-FR/server.mdx +17 -10
- package/corpus/core/docs/content/locales/fr-FR/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/fr-FR/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/fr-FR/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/fr-FR/template-clips.mdx +3 -3
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/fr-FR/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/fr-FR/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/fr-FR/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/fr-FR/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/fr-FR/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/fr-FR/workspace.mdx +19 -18
- package/corpus/core/docs/content/locales/hi-IN/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/hi-IN/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/hi-IN/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/hi-IN/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/components.mdx +11 -1
- package/corpus/core/docs/content/locales/hi-IN/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/hi-IN/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/hi-IN/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +2 -7
- package/corpus/core/docs/content/locales/hi-IN/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/hi-IN/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/hi-IN/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/hi-IN/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/hi-IN/server.mdx +17 -10
- package/corpus/core/docs/content/locales/hi-IN/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/hi-IN/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/hi-IN/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/hi-IN/template-clips.mdx +3 -3
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/hi-IN/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/hi-IN/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/hi-IN/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/hi-IN/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/hi-IN/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/hi-IN/workspace.mdx +19 -18
- package/corpus/core/docs/content/locales/ja-JP/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/ja-JP/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/ja-JP/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/ja-JP/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/components.mdx +11 -1
- package/corpus/core/docs/content/locales/ja-JP/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/ja-JP/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/ja-JP/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +2 -7
- package/corpus/core/docs/content/locales/ja-JP/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/ja-JP/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/ja-JP/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/ja-JP/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/ja-JP/server.mdx +17 -10
- package/corpus/core/docs/content/locales/ja-JP/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/ja-JP/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/ja-JP/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/ja-JP/template-clips.mdx +3 -4
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/ja-JP/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/ja-JP/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/ja-JP/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/ja-JP/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/ja-JP/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/ja-JP/workspace.mdx +19 -18
- package/corpus/core/docs/content/locales/ko-KR/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/ko-KR/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/ko-KR/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/ko-KR/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/components.mdx +11 -1
- package/corpus/core/docs/content/locales/ko-KR/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/ko-KR/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/ko-KR/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +2 -7
- package/corpus/core/docs/content/locales/ko-KR/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/ko-KR/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/ko-KR/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/ko-KR/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/ko-KR/server.mdx +17 -10
- package/corpus/core/docs/content/locales/ko-KR/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/ko-KR/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/ko-KR/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/ko-KR/template-clips.mdx +3 -4
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/ko-KR/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/ko-KR/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/ko-KR/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/ko-KR/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/ko-KR/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/ko-KR/workspace.mdx +19 -18
- package/corpus/core/docs/content/locales/pt-BR/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/pt-BR/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/pt-BR/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/pt-BR/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/components.mdx +11 -1
- package/corpus/core/docs/content/locales/pt-BR/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/pt-BR/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/pt-BR/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +3 -7
- package/corpus/core/docs/content/locales/pt-BR/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/pt-BR/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/pt-BR/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/pt-BR/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/pt-BR/server.mdx +17 -10
- package/corpus/core/docs/content/locales/pt-BR/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/pt-BR/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/pt-BR/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/pt-BR/template-clips.mdx +3 -3
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/pt-BR/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/pt-BR/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/pt-BR/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/pt-BR/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/pt-BR/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/pt-BR/workspace.mdx +19 -18
- package/corpus/core/docs/content/locales/zh-CN/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-CN/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/zh-CN/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/zh-CN/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/components.mdx +11 -1
- package/corpus/core/docs/content/locales/zh-CN/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/zh-CN/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/zh-CN/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +2 -7
- package/corpus/core/docs/content/locales/zh-CN/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/zh-CN/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/zh-CN/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/zh-CN/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/zh-CN/server.mdx +16 -10
- package/corpus/core/docs/content/locales/zh-CN/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/zh-CN/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/zh-CN/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/zh-CN/template-clips.mdx +3 -4
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/zh-CN/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/zh-CN/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/zh-CN/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/zh-CN/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/zh-CN/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/zh-CN/workspace.mdx +19 -18
- package/corpus/core/docs/content/locales/zh-TW/actions.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-TW/agent-surfaces.mdx +8 -10
- package/corpus/core/docs/content/locales/zh-TW/agent-teams.mdx +1 -0
- package/corpus/core/docs/content/locales/zh-TW/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/components.mdx +11 -1
- package/corpus/core/docs/content/locales/zh-TW/creating-templates.mdx +3 -7
- package/corpus/core/docs/content/locales/zh-TW/cross-app-sso.mdx +16 -6
- package/corpus/core/docs/content/locales/zh-TW/deployment.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +2 -7
- package/corpus/core/docs/content/locales/zh-TW/key-concepts.mdx +13 -20
- package/corpus/core/docs/content/locales/zh-TW/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/locales/zh-TW/notifications.mdx +18 -10
- package/corpus/core/docs/content/locales/zh-TW/processors.mdx +11 -5
- package/corpus/core/docs/content/locales/zh-TW/server.mdx +16 -10
- package/corpus/core/docs/content/locales/zh-TW/sharing.mdx +10 -10
- package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +34 -17
- package/corpus/core/docs/content/locales/zh-TW/template-assets.mdx +16 -13
- package/corpus/core/docs/content/locales/zh-TW/template-brain.mdx +3 -1
- package/corpus/core/docs/content/locales/zh-TW/template-clips.mdx +3 -4
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +3 -1
- package/corpus/core/docs/content/locales/zh-TW/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/locales/zh-TW/template-mail.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +9 -6
- package/corpus/core/docs/content/locales/zh-TW/using-your-agent.mdx +0 -7
- package/corpus/core/docs/content/locales/zh-TW/voice-input.mdx +6 -0
- package/corpus/core/docs/content/locales/zh-TW/workspace-connections.mdx +9 -2
- package/corpus/core/docs/content/locales/zh-TW/workspace.mdx +19 -18
- package/corpus/core/docs/content/mcp-apps.mdx +14 -32
- package/corpus/core/docs/content/mcp-clients.mdx +48 -54
- package/corpus/core/docs/content/mcp-protocol.mdx +25 -10
- package/corpus/core/docs/content/messaging.mdx +19 -11
- package/corpus/core/docs/content/multi-app-workspace.mdx +11 -96
- package/corpus/core/docs/content/multi-tenancy.mdx +5 -5
- package/corpus/core/docs/content/native-chat-ui.mdx +4 -4
- package/corpus/core/docs/content/notifications.mdx +19 -12
- package/corpus/core/docs/content/observability.mdx +2 -4
- package/corpus/core/docs/content/observational-memory.mdx +7 -3
- package/corpus/core/docs/content/onboarding.mdx +9 -2
- package/corpus/core/docs/content/plan-plugin.mdx +10 -2
- package/corpus/core/docs/content/pr-visual-recap.mdx +1 -1
- package/corpus/core/docs/content/processors.mdx +11 -5
- package/corpus/core/docs/content/pure-agent-apps.mdx +5 -1
- package/corpus/core/docs/content/real-time-collaboration.mdx +30 -67
- package/corpus/core/docs/content/recurring-jobs.mdx +8 -6
- package/corpus/core/docs/content/routing.mdx +3 -4
- package/corpus/core/docs/content/sandbox-adapters.mdx +30 -53
- package/corpus/core/docs/content/security.mdx +8 -0
- package/corpus/core/docs/content/server.mdx +17 -10
- package/corpus/core/docs/content/sharing.mdx +10 -10
- package/corpus/core/docs/content/skills-guide.mdx +35 -16
- package/corpus/core/docs/content/template-analytics.mdx +11 -8
- package/corpus/core/docs/content/template-assets.mdx +16 -13
- package/corpus/core/docs/content/template-brain.mdx +3 -1
- package/corpus/core/docs/content/template-calendar.mdx +12 -4
- package/corpus/core/docs/content/template-chat.mdx +4 -4
- package/corpus/core/docs/content/template-clips.mdx +3 -3
- package/corpus/core/docs/content/template-content.mdx +23 -18
- package/corpus/core/docs/content/template-design.mdx +3 -1
- package/corpus/core/docs/content/template-dispatch.mdx +5 -1
- package/corpus/core/docs/content/template-mail.mdx +14 -2
- package/corpus/core/docs/content/template-plan.mdx +22 -15
- package/corpus/core/docs/content/template-slides.mdx +11 -3
- package/corpus/core/docs/content/toolkit-agent-ux.mdx +46 -3
- package/corpus/core/docs/content/toolkit-collaboration.mdx +58 -4
- package/corpus/core/docs/content/toolkit-command-navigation.mdx +8 -2
- package/corpus/core/docs/content/toolkit-comments-review.mdx +10 -2
- package/corpus/core/docs/content/toolkit-history.mdx +8 -3
- package/corpus/core/docs/content/toolkit-observability.mdx +48 -2
- package/corpus/core/docs/content/toolkit-org-team.mdx +8 -2
- package/corpus/core/docs/content/toolkit-resources.mdx +45 -2
- package/corpus/core/docs/content/toolkit-settings.mdx +8 -2
- package/corpus/core/docs/content/toolkit-setup-connections.mdx +7 -2
- package/corpus/core/docs/content/toolkit-sharing.mdx +46 -3
- package/corpus/core/docs/content/toolkit-ui.mdx +82 -11
- package/corpus/core/docs/content/tracking.mdx +10 -8
- package/corpus/core/docs/content/using-your-agent.mdx +0 -12
- package/corpus/core/docs/content/voice-input.mdx +7 -1
- package/corpus/core/docs/content/what-is-agent-native.mdx +7 -8
- package/corpus/core/docs/content/workspace-connections.mdx +16 -23
- package/corpus/core/docs/content/workspace-management.mdx +16 -4
- package/corpus/core/docs/content/workspace.mdx +19 -18
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/context-xray/tokenize.ts +6 -1
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +9 -5
- package/corpus/core/src/agent/engine/anthropic-engine.ts +2 -4
- package/corpus/core/src/agent/engine/builder-engine.ts +5 -7
- package/corpus/core/src/agent/engine/index.ts +1 -0
- package/corpus/core/src/agent/engine/registry.ts +40 -0
- package/corpus/core/src/agent/harness/ai-sdk-adapter.ts +6 -1
- package/corpus/core/src/agent/harness/background.ts +96 -19
- package/corpus/core/src/agent/harness/index.ts +11 -0
- package/corpus/core/src/agent/harness/lifecycle.ts +498 -0
- package/corpus/core/src/agent/harness/runner.ts +38 -0
- package/corpus/core/src/agent/harness/store.ts +22 -3
- package/corpus/core/src/agent/model-config.ts +4 -1
- package/corpus/core/src/agent/production-agent.ts +190 -6
- package/corpus/core/src/agent/run-manager.ts +5 -1
- package/corpus/core/src/application-state/index.ts +1 -0
- package/corpus/core/src/application-state/store.ts +32 -0
- package/corpus/core/src/cli/code-agent-connector.ts +263 -8
- package/corpus/core/src/cli/code-agent-executor.ts +15 -1
- package/corpus/core/src/client/AgentPanel.tsx +41 -38
- package/corpus/core/src/client/AssistantChat.tsx +98 -6
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +33 -40
- package/corpus/core/src/client/appearance.ts +8 -5
- package/corpus/core/src/client/chat/connectors.ts +293 -29
- package/corpus/core/src/client/chat/message-components.tsx +23 -1
- package/corpus/core/src/client/chat/runtime.ts +126 -25
- package/corpus/core/src/client/chat/tool-call-display.tsx +45 -4
- package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +294 -0
- package/corpus/core/src/client/composer/TiptapComposer.tsx +21 -20
- package/corpus/core/src/client/composer/VoiceButton.tsx +20 -0
- package/corpus/core/src/client/composer/index.ts +22 -0
- package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +640 -0
- package/corpus/core/src/client/guided-questions.tsx +12 -3
- package/corpus/core/src/client/index.ts +18 -0
- package/corpus/core/src/client/settings/DemoModeSection.tsx +4 -3
- package/corpus/core/src/client/settings/SettingsPanel.tsx +4 -0
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +95 -37
- package/corpus/core/src/client/use-chat-models.ts +17 -17
- package/corpus/core/src/client/use-db-sync.ts +108 -7
- package/corpus/core/src/code-agents/background-controller.ts +18 -0
- package/corpus/core/src/collab/ydoc-manager.ts +41 -6
- package/corpus/core/src/db/migrations.ts +17 -1
- package/corpus/core/src/demo/fetch-interceptor.ts +16 -11
- package/corpus/core/src/integrations/adapters/slack.ts +41 -2
- package/corpus/core/src/integrations/awaiting-input-store.ts +130 -0
- package/corpus/core/src/integrations/computer-supervision-store.ts +423 -0
- package/corpus/core/src/integrations/computer-supervision.ts +213 -0
- package/corpus/core/src/integrations/index.ts +29 -1
- package/corpus/core/src/integrations/plugin.ts +231 -2
- package/corpus/core/src/integrations/remote-commands-store.ts +334 -3
- package/corpus/core/src/integrations/remote-devices-store.ts +68 -9
- package/corpus/core/src/integrations/remote-json-safety.ts +127 -0
- package/corpus/core/src/integrations/remote-run-events-store.ts +104 -19
- package/corpus/core/src/integrations/remote-types.ts +66 -3
- package/corpus/core/src/integrations/webhook-handler.ts +161 -2
- package/corpus/core/src/localization/default-messages.ts +28 -0
- package/corpus/core/src/mcp-client/config.ts +48 -2
- package/corpus/core/src/mcp-client/index.ts +35 -2
- package/corpus/core/src/mcp-client/tool-policy.ts +182 -0
- package/corpus/core/src/secrets/register-framework-secrets.ts +27 -4
- package/corpus/core/src/server/agent-chat-plugin.ts +62 -8
- package/corpus/core/src/server/index.ts +16 -0
- package/corpus/core/src/server/realtime-voice.ts +590 -0
- package/corpus/core/src/shared/reasoning-effort.ts +61 -19
- package/corpus/core/src/styles/agent-conversation.css +17 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -5
- package/corpus/templates/brain/app/lib/settings-navigation.ts +22 -0
- package/corpus/templates/brain/app/routes/settings.tsx +367 -252
- package/corpus/templates/brain/changelog/2026-07-10-brain-settings-now-separate-assistant-behavior-publishing-re.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-10-organization-settings-now-opens-directly-from-the-workspace-.md +6 -0
- package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +36 -4
- package/corpus/templates/calendar/AGENTS.md +4 -0
- package/corpus/templates/calendar/actions/create-event.ts +7 -19
- package/corpus/templates/calendar/actions/delete-event.ts +10 -3
- package/corpus/templates/calendar/actions/rsvp-event.ts +1 -1
- package/corpus/templates/calendar/actions/update-event.ts +4 -3
- package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +100 -13
- package/corpus/templates/calendar/app/components/calendar/DayView.tsx +12 -4
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +3 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +86 -8
- package/corpus/templates/calendar/app/components/calendar/EventDialog.tsx +3 -1
- package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +12 -4
- package/corpus/templates/calendar/app/hooks/use-events.ts +1 -0
- package/corpus/templates/calendar/app/lib/event-account-selection.ts +36 -0
- package/corpus/templates/calendar/app/lib/event-form-initialization.ts +21 -0
- package/corpus/templates/calendar/app/lib/event-mutation-inputs.ts +18 -0
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +119 -26
- package/corpus/templates/calendar/changelog/2026-07-10-choose-which-connected-google-account-receives-a-new-event-w.md +6 -0
- package/corpus/templates/calendar/server/db/schema.ts +2 -0
- package/corpus/templates/calendar/server/handlers/bookings.ts +43 -6
- package/corpus/templates/calendar/server/handlers/events.ts +28 -9
- package/corpus/templates/calendar/server/lib/google-calendar.ts +66 -38
- package/corpus/templates/calendar/server/plugins/db.ts +5 -0
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +12 -3
- package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +1 -1
- package/corpus/templates/clips/AGENTS.md +4 -2
- package/corpus/templates/clips/actions/regenerate-title.ts +53 -7
- package/corpus/templates/clips/actions/request-transcript.ts +152 -41
- package/corpus/templates/clips/actions/save-browser-transcript.ts +11 -9
- package/corpus/templates/clips/app/components/player/comments-panel.tsx +101 -53
- package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +102 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +10 -1
- package/corpus/templates/clips/app/hooks/use-auto-title.ts +14 -0
- package/corpus/templates/clips/app/routes/embed.$shareId.tsx +2 -0
- package/corpus/templates/clips/changelog/2026-07-10-comment-replies-now-open-inline-and-focus-immediately-while-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-dismissed-upload-warnings-now-keep-recordings-in-clip-drafts.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-dragging-the-meeting-recorder-no-longer-opens-the-expanded.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-finishing-meeting-notes-no-longer-opens-your-browser.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-meeting-recordings-now-keep-microphone-audio-and-recover-tra.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-recording-pause-and-resume-controls-now-respond-reliably-on-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-starting-and-joining-a-meeting-now-closes-the-desktop-popover.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-timestamped-comments-now-appear-over-the-video-as-playback-r.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-transcript-backed-titles-and-summaries-now-finish-after-recording.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-10-zoom-meetings-now-open-directly-in-the-desktop-app.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +49 -7
- package/corpus/templates/clips/desktop/src/app.tsx +70 -42
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +8 -14
- package/corpus/templates/clips/desktop/src/lib/meeting-join-url.ts +33 -0
- package/corpus/templates/clips/desktop/src/lib/pause-transition.ts +79 -0
- package/corpus/templates/clips/desktop/src/lib/pill-interaction.ts +19 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +90 -39
- package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +3 -2
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +3 -2
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +32 -6
- package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +50 -5
- package/corpus/templates/clips/desktop/src/styles.css +11 -19
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -1
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +121 -4
- package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +97 -17
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +80 -5
- package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -1
- package/corpus/templates/clips/vitest.config.ts +23 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +28 -9
- package/corpus/templates/content/changelog/2026-07-10-open-documents-no-longer-make-constant-background-requests-w.md +6 -0
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +21 -4
- package/corpus/templates/design/AGENTS.md +7 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +132 -7
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +73 -18
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +6 -1
- package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +135 -5
- package/corpus/templates/design/app/lib/clipboard-content-lineage.ts +64 -0
- package/corpus/templates/design/app/lib/design-clipboard-managed-styles.ts +247 -0
- package/corpus/templates/design/app/lib/design-clipboard.ts +60 -3
- package/corpus/templates/design/app/lib/design-import.ts +31 -3
- package/corpus/templates/design/app/pages/design-editor/latest-write-queue.ts +56 -0
- package/corpus/templates/design/app/pages/design-editor/performance-buffer-guard.ts +80 -0
- package/corpus/templates/design/changelog/2026-07-10-concurrent-agent-and-artboard-edits-no-longer-show-misleadin.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-designs-with-html-examples-inside-alpine-attributes-or-comme.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-interactive-designs-no-longer-appear-blank-in-the-canvas-whe.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-long-overview-editing-sessions-lots-of-pan-zoom-screen-switc.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-rapid-breakpoint-and-edit-scope-changes-no-longer-jump-back-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-responsive-breakpoint-previews-stay-visible-while-panning-ac.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-rich-design-clipboard-markers-are-now-accepted-only-from-the.md +6 -0
- package/corpus/templates/design/e2e/helpers.ts +16 -5
- package/corpus/templates/design/server/source-workspace.ts +28 -2
- package/corpus/templates/design/shared/html-integrity.ts +119 -24
- package/corpus/templates/dispatch/AGENTS.md +10 -2
- package/corpus/templates/dispatch/actions/view-screen.ts +11 -0
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +13 -0
- package/corpus/templates/dispatch/app/i18n/zh-TW.ts +3 -0
- package/corpus/templates/dispatch/app/i18n-data.ts +37 -1
- package/corpus/templates/dispatch/app/routes/operations.tsx +1 -0
- package/corpus/templates/dispatch/changelog/2026-07-10-dispatch-now-has-a-cleaner-chat-history-and-quieter-sidebar-.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-10-operations-console-brings-agent-monitoring-and-database-inspection-tog.md +6 -0
- package/corpus/templates/mail/actions/get-integration-statuses.ts +36 -0
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +3 -2
- package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +3 -3
- package/corpus/templates/mail/app/hooks/use-apollo.ts +5 -71
- package/corpus/templates/mail/app/hooks/use-draft-queue.ts +1 -1
- package/corpus/templates/mail/app/hooks/use-integrations.ts +51 -48
- package/corpus/templates/mail/app/lib/integration-status.ts +31 -0
- package/corpus/templates/mail/app/lib/sync-invalidation.ts +5 -0
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +3 -0
- package/corpus/templates/mail/app/root.tsx +22 -12
- package/corpus/templates/mail/changelog/2026-07-10-email-content-backgrounds-now-blend-cleanly-with-dark-mode.md +6 -0
- package/corpus/templates/mail/changelog/2026-07-10-mail-settings-now-group-drafting-automation-and-connected-se.md +6 -0
- package/corpus/templates/mail/changelog/2026-07-10-organization-settings-now-opens-directly-from-the-workspace-.md +6 -0
- package/dist/agent/context-xray/tokenize.d.ts.map +1 -1
- package/dist/agent/context-xray/tokenize.js +6 -1
- package/dist/agent/context-xray/tokenize.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +8 -3
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +2 -4
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +2 -3
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/index.d.ts +1 -1
- package/dist/agent/engine/index.d.ts.map +1 -1
- package/dist/agent/engine/index.js +1 -1
- package/dist/agent/engine/index.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +13 -0
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +33 -0
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
- package/dist/agent/harness/ai-sdk-adapter.js +3 -1
- package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
- package/dist/agent/harness/background.d.ts +9 -9
- package/dist/agent/harness/background.d.ts.map +1 -1
- package/dist/agent/harness/background.js +77 -19
- package/dist/agent/harness/background.js.map +1 -1
- package/dist/agent/harness/index.d.ts +1 -0
- package/dist/agent/harness/index.d.ts.map +1 -1
- package/dist/agent/harness/index.js +1 -0
- package/dist/agent/harness/index.js.map +1 -1
- package/dist/agent/harness/lifecycle.d.ts +45 -0
- package/dist/agent/harness/lifecycle.d.ts.map +1 -0
- package/dist/agent/harness/lifecycle.js +318 -0
- package/dist/agent/harness/lifecycle.js.map +1 -0
- package/dist/agent/harness/runner.d.ts.map +1 -1
- package/dist/agent/harness/runner.js +29 -1
- package/dist/agent/harness/runner.js.map +1 -1
- package/dist/agent/harness/store.d.ts +2 -0
- package/dist/agent/harness/store.d.ts.map +1 -1
- package/dist/agent/harness/store.js +17 -3
- package/dist/agent/harness/store.js.map +1 -1
- package/dist/agent/model-config.d.ts +2 -2
- package/dist/agent/model-config.d.ts.map +1 -1
- package/dist/agent/model-config.js +4 -1
- package/dist/agent/model-config.js.map +1 -1
- package/dist/agent/production-agent.d.ts +38 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +135 -4
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/application-state/index.d.ts +1 -1
- package/dist/application-state/index.d.ts.map +1 -1
- package/dist/application-state/index.js +1 -1
- package/dist/application-state/index.js.map +1 -1
- package/dist/application-state/store.d.ts +6 -0
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js +31 -0
- package/dist/application-state/store.js.map +1 -1
- package/dist/cli/code-agent-connector.d.ts +9 -0
- package/dist/cli/code-agent-connector.d.ts.map +1 -1
- package/dist/cli/code-agent-connector.js +212 -10
- package/dist/cli/code-agent-connector.js.map +1 -1
- package/dist/cli/code-agent-executor.d.ts +2 -0
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +8 -1
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +6 -5
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +12 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +71 -5
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +16 -37
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/appearance.d.ts +4 -2
- package/dist/client/appearance.d.ts.map +1 -1
- package/dist/client/appearance.js +8 -5
- package/dist/client/appearance.js.map +1 -1
- package/dist/client/chat/connectors.d.ts.map +1 -1
- package/dist/client/chat/connectors.js +206 -28
- package/dist/client/chat/connectors.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +17 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/runtime.d.ts.map +1 -1
- package/dist/client/chat/runtime.js +84 -24
- package/dist/client/chat/runtime.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +8 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +21 -3
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/composer/RealtimeVoiceMode.d.ts +54 -0
- package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -0
- package/dist/client/composer/RealtimeVoiceMode.js +63 -0
- package/dist/client/composer/RealtimeVoiceMode.js.map +1 -0
- package/dist/client/composer/TiptapComposer.d.ts +1 -0
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +17 -20
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts.map +1 -1
- package/dist/client/composer/VoiceButton.js +9 -0
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/composer/index.d.ts +2 -0
- package/dist/client/composer/index.d.ts.map +1 -1
- package/dist/client/composer/index.js +2 -0
- package/dist/client/composer/index.js.map +1 -1
- package/dist/client/composer/useRealtimeVoiceMode.d.ts +56 -0
- package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -0
- package/dist/client/composer/useRealtimeVoiceMode.js +492 -0
- package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -0
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +7 -2
- package/dist/client/guided-questions.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/settings/DemoModeSection.d.ts.map +1 -1
- package/dist/client/settings/DemoModeSection.js +4 -3
- package/dist/client/settings/DemoModeSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +4 -0
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts +10 -3
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/client/settings/SettingsTabsPage.js +49 -11
- package/dist/client/settings/SettingsTabsPage.js.map +1 -1
- package/dist/client/use-chat-models.d.ts.map +1 -1
- package/dist/client/use-chat-models.js +6 -14
- package/dist/client/use-chat-models.js.map +1 -1
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +87 -7
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/code-agents/background-controller.d.ts +1 -1
- package/dist/code-agents/background-controller.d.ts.map +1 -1
- package/dist/code-agents/background-controller.js +17 -1
- package/dist/code-agents/background-controller.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/collab/ydoc-manager.d.ts +9 -1
- package/dist/collab/ydoc-manager.d.ts.map +1 -1
- package/dist/collab/ydoc-manager.js +30 -6
- package/dist/collab/ydoc-manager.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +4 -2
- package/dist/db/migrations.js.map +1 -1
- package/dist/demo/fetch-interceptor.d.ts +5 -1
- package/dist/demo/fetch-interceptor.d.ts.map +1 -1
- package/dist/demo/fetch-interceptor.js +16 -12
- package/dist/demo/fetch-interceptor.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts +2 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +38 -2
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/awaiting-input-store.d.ts +27 -0
- package/dist/integrations/awaiting-input-store.d.ts.map +1 -0
- package/dist/integrations/awaiting-input-store.js +112 -0
- package/dist/integrations/awaiting-input-store.js.map +1 -0
- package/dist/integrations/computer-supervision-store.d.ts +65 -0
- package/dist/integrations/computer-supervision-store.d.ts.map +1 -0
- package/dist/integrations/computer-supervision-store.js +296 -0
- package/dist/integrations/computer-supervision-store.js.map +1 -0
- package/dist/integrations/computer-supervision.d.ts +11 -0
- package/dist/integrations/computer-supervision.d.ts.map +1 -0
- package/dist/integrations/computer-supervision.js +160 -0
- package/dist/integrations/computer-supervision.js.map +1 -0
- package/dist/integrations/index.d.ts +6 -3
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +5 -2
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +205 -3
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/remote-commands-store.d.ts +15 -1
- package/dist/integrations/remote-commands-store.d.ts.map +1 -1
- package/dist/integrations/remote-commands-store.js +273 -3
- package/dist/integrations/remote-commands-store.js.map +1 -1
- package/dist/integrations/remote-devices-store.d.ts +4 -3
- package/dist/integrations/remote-devices-store.d.ts.map +1 -1
- package/dist/integrations/remote-devices-store.js +49 -2
- package/dist/integrations/remote-devices-store.js.map +1 -1
- package/dist/integrations/remote-json-safety.d.ts +6 -0
- package/dist/integrations/remote-json-safety.d.ts.map +1 -0
- package/dist/integrations/remote-json-safety.js +114 -0
- package/dist/integrations/remote-json-safety.js.map +1 -0
- package/dist/integrations/remote-run-events-store.d.ts +11 -1
- package/dist/integrations/remote-run-events-store.d.ts.map +1 -1
- package/dist/integrations/remote-run-events-store.js +85 -17
- package/dist/integrations/remote-run-events-store.js.map +1 -1
- package/dist/integrations/remote-types.d.ts +54 -3
- package/dist/integrations/remote-types.d.ts.map +1 -1
- package/dist/integrations/remote-types.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +133 -4
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/localization/default-messages.d.ts +26 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +26 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp-client/config.d.ts.map +1 -1
- package/dist/mcp-client/config.js +44 -3
- package/dist/mcp-client/config.js.map +1 -1
- package/dist/mcp-client/index.d.ts +6 -1
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +11 -3
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/tool-policy.d.ts +24 -0
- package/dist/mcp-client/tool-policy.d.ts.map +1 -0
- package/dist/mcp-client/tool-policy.js +139 -0
- package/dist/mcp-client/tool-policy.js.map +1 -0
- package/dist/observability/routes.d.ts +5 -5
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/register-framework-secrets.d.ts +3 -4
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +25 -4
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +53 -6
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/realtime-voice.d.ts +53 -0
- package/dist/server/realtime-voice.d.ts.map +1 -0
- package/dist/server/realtime-voice.js +404 -0
- package/dist/server/realtime-voice.js.map +1 -0
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/reasoning-effort.d.ts +20 -0
- package/dist/shared/reasoning-effort.d.ts.map +1 -1
- package/dist/shared/reasoning-effort.js +52 -18
- package/dist/shared/reasoning-effort.js.map +1 -1
- package/dist/styles/agent-conversation.css +17 -0
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -5
- package/docs/content/a2a-protocol.mdx +21 -5
- package/docs/content/actions.mdx +9 -23
- package/docs/content/agent-mentions.mdx +31 -29
- package/docs/content/agent-native-toolkit.mdx +15 -6
- package/docs/content/agent-surfaces.mdx +9 -13
- package/docs/content/agent-teams.mdx +1 -0
- package/docs/content/authentication.mdx +10 -3
- package/docs/content/automation-connectors.mdx +82 -39
- package/docs/content/automations.mdx +17 -3
- package/docs/content/blueprint-installer.mdx +11 -4
- package/docs/content/cli-adapters.mdx +9 -6
- package/docs/content/client.mdx +16 -0
- package/docs/content/cloneable-saas.mdx +14 -11
- package/docs/content/code-agents-ui.mdx +65 -0
- package/docs/content/components.mdx +30 -14
- package/docs/content/context-awareness.mdx +27 -15
- package/docs/content/creating-templates.mdx +15 -9
- package/docs/content/cross-app-sso.mdx +16 -6
- package/docs/content/data-programs.mdx +1 -1
- package/docs/content/database.mdx +17 -5
- package/docs/content/deployment.mdx +19 -18
- package/docs/content/dispatch.mdx +6 -2
- package/docs/content/drop-in-agent.mdx +10 -4
- package/docs/content/durable-background-runs.mdx +9 -5
- package/docs/content/durable-resume.mdx +9 -4
- package/docs/content/embedding-sdk.mdx +26 -8
- package/docs/content/evals.mdx +3 -5
- package/docs/content/extensions.mdx +22 -9
- package/docs/content/external-agents.mdx +25 -34
- package/docs/content/faq.mdx +8 -0
- package/docs/content/file-uploads.mdx +12 -3
- package/docs/content/frames.mdx +16 -0
- package/docs/content/generative-ui.mdx +1 -1
- package/docs/content/getting-started.mdx +34 -21
- package/docs/content/harness-agents.mdx +8 -4
- package/docs/content/human-approval.mdx +8 -3
- package/docs/content/internationalization.mdx +9 -4
- package/docs/content/key-concepts.mdx +13 -20
- package/docs/content/local-file-mode.mdx +14 -8
- package/docs/content/locales/ar-SA/actions.mdx +2 -2
- package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/ar-SA/agent-surfaces.mdx +8 -10
- package/docs/content/locales/ar-SA/agent-teams.mdx +1 -0
- package/docs/content/locales/ar-SA/authentication.mdx +1 -1
- package/docs/content/locales/ar-SA/components.mdx +11 -1
- package/docs/content/locales/ar-SA/creating-templates.mdx +3 -7
- package/docs/content/locales/ar-SA/cross-app-sso.mdx +16 -6
- package/docs/content/locales/ar-SA/deployment.mdx +8 -0
- package/docs/content/locales/ar-SA/external-agents.mdx +2 -7
- package/docs/content/locales/ar-SA/key-concepts.mdx +13 -20
- package/docs/content/locales/ar-SA/multi-tenancy.mdx +5 -5
- package/docs/content/locales/ar-SA/notifications.mdx +18 -10
- package/docs/content/locales/ar-SA/processors.mdx +11 -5
- package/docs/content/locales/ar-SA/server.mdx +17 -10
- package/docs/content/locales/ar-SA/sharing.mdx +10 -10
- package/docs/content/locales/ar-SA/skills-guide.mdx +34 -17
- package/docs/content/locales/ar-SA/template-assets.mdx +16 -13
- package/docs/content/locales/ar-SA/template-brain.mdx +3 -1
- package/docs/content/locales/ar-SA/template-clips.mdx +3 -3
- package/docs/content/locales/ar-SA/template-design.mdx +3 -1
- package/docs/content/locales/ar-SA/template-dispatch.mdx +5 -1
- package/docs/content/locales/ar-SA/template-mail.mdx +8 -0
- package/docs/content/locales/ar-SA/tracking.mdx +9 -6
- package/docs/content/locales/ar-SA/using-your-agent.mdx +0 -7
- package/docs/content/locales/ar-SA/voice-input.mdx +6 -0
- package/docs/content/locales/ar-SA/workspace-connections.mdx +9 -2
- package/docs/content/locales/ar-SA/workspace.mdx +19 -18
- package/docs/content/locales/de-DE/actions.mdx +2 -2
- package/docs/content/locales/de-DE/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/de-DE/agent-surfaces.mdx +8 -10
- package/docs/content/locales/de-DE/agent-teams.mdx +1 -0
- package/docs/content/locales/de-DE/authentication.mdx +1 -1
- package/docs/content/locales/de-DE/components.mdx +11 -1
- package/docs/content/locales/de-DE/creating-templates.mdx +3 -7
- package/docs/content/locales/de-DE/cross-app-sso.mdx +16 -6
- package/docs/content/locales/de-DE/deployment.mdx +8 -0
- package/docs/content/locales/de-DE/external-agents.mdx +3 -7
- package/docs/content/locales/de-DE/key-concepts.mdx +13 -20
- package/docs/content/locales/de-DE/multi-tenancy.mdx +5 -5
- package/docs/content/locales/de-DE/notifications.mdx +18 -10
- package/docs/content/locales/de-DE/processors.mdx +11 -5
- package/docs/content/locales/de-DE/server.mdx +18 -10
- package/docs/content/locales/de-DE/sharing.mdx +10 -10
- package/docs/content/locales/de-DE/skills-guide.mdx +34 -17
- package/docs/content/locales/de-DE/template-assets.mdx +16 -13
- package/docs/content/locales/de-DE/template-brain.mdx +3 -1
- package/docs/content/locales/de-DE/template-clips.mdx +3 -3
- package/docs/content/locales/de-DE/template-design.mdx +3 -1
- package/docs/content/locales/de-DE/template-dispatch.mdx +5 -1
- package/docs/content/locales/de-DE/template-mail.mdx +8 -0
- package/docs/content/locales/de-DE/tracking.mdx +9 -6
- package/docs/content/locales/de-DE/using-your-agent.mdx +0 -7
- package/docs/content/locales/de-DE/voice-input.mdx +6 -0
- package/docs/content/locales/de-DE/workspace-connections.mdx +9 -2
- package/docs/content/locales/de-DE/workspace.mdx +19 -18
- package/docs/content/locales/es-ES/actions.mdx +2 -2
- package/docs/content/locales/es-ES/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/es-ES/agent-surfaces.mdx +8 -10
- package/docs/content/locales/es-ES/agent-teams.mdx +1 -0
- package/docs/content/locales/es-ES/authentication.mdx +1 -1
- package/docs/content/locales/es-ES/components.mdx +11 -1
- package/docs/content/locales/es-ES/creating-templates.mdx +3 -7
- package/docs/content/locales/es-ES/cross-app-sso.mdx +16 -6
- package/docs/content/locales/es-ES/deployment.mdx +8 -0
- package/docs/content/locales/es-ES/external-agents.mdx +3 -7
- package/docs/content/locales/es-ES/key-concepts.mdx +13 -20
- package/docs/content/locales/es-ES/multi-tenancy.mdx +5 -5
- package/docs/content/locales/es-ES/notifications.mdx +18 -10
- package/docs/content/locales/es-ES/processors.mdx +11 -5
- package/docs/content/locales/es-ES/server.mdx +17 -10
- package/docs/content/locales/es-ES/sharing.mdx +10 -10
- package/docs/content/locales/es-ES/skills-guide.mdx +34 -17
- package/docs/content/locales/es-ES/template-assets.mdx +16 -13
- package/docs/content/locales/es-ES/template-brain.mdx +3 -1
- package/docs/content/locales/es-ES/template-clips.mdx +3 -3
- package/docs/content/locales/es-ES/template-design.mdx +3 -1
- package/docs/content/locales/es-ES/template-dispatch.mdx +5 -1
- package/docs/content/locales/es-ES/template-mail.mdx +8 -0
- package/docs/content/locales/es-ES/tracking.mdx +9 -6
- package/docs/content/locales/es-ES/using-your-agent.mdx +0 -7
- package/docs/content/locales/es-ES/voice-input.mdx +6 -0
- package/docs/content/locales/es-ES/workspace-connections.mdx +9 -2
- package/docs/content/locales/es-ES/workspace.mdx +19 -18
- package/docs/content/locales/fr-FR/actions.mdx +2 -2
- package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/fr-FR/agent-surfaces.mdx +8 -10
- package/docs/content/locales/fr-FR/agent-teams.mdx +1 -0
- package/docs/content/locales/fr-FR/authentication.mdx +1 -1
- package/docs/content/locales/fr-FR/components.mdx +11 -1
- package/docs/content/locales/fr-FR/creating-templates.mdx +3 -7
- package/docs/content/locales/fr-FR/cross-app-sso.mdx +16 -6
- package/docs/content/locales/fr-FR/deployment.mdx +8 -0
- package/docs/content/locales/fr-FR/external-agents.mdx +3 -7
- package/docs/content/locales/fr-FR/key-concepts.mdx +13 -20
- package/docs/content/locales/fr-FR/multi-tenancy.mdx +5 -5
- package/docs/content/locales/fr-FR/notifications.mdx +18 -10
- package/docs/content/locales/fr-FR/processors.mdx +11 -5
- package/docs/content/locales/fr-FR/server.mdx +17 -10
- package/docs/content/locales/fr-FR/sharing.mdx +10 -10
- package/docs/content/locales/fr-FR/skills-guide.mdx +34 -17
- package/docs/content/locales/fr-FR/template-assets.mdx +16 -13
- package/docs/content/locales/fr-FR/template-brain.mdx +3 -1
- package/docs/content/locales/fr-FR/template-clips.mdx +3 -3
- package/docs/content/locales/fr-FR/template-design.mdx +3 -1
- package/docs/content/locales/fr-FR/template-dispatch.mdx +5 -1
- package/docs/content/locales/fr-FR/template-mail.mdx +8 -0
- package/docs/content/locales/fr-FR/tracking.mdx +9 -6
- package/docs/content/locales/fr-FR/using-your-agent.mdx +0 -7
- package/docs/content/locales/fr-FR/voice-input.mdx +6 -0
- package/docs/content/locales/fr-FR/workspace-connections.mdx +9 -2
- package/docs/content/locales/fr-FR/workspace.mdx +19 -18
- package/docs/content/locales/hi-IN/actions.mdx +2 -2
- package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/hi-IN/agent-surfaces.mdx +8 -10
- package/docs/content/locales/hi-IN/agent-teams.mdx +1 -0
- package/docs/content/locales/hi-IN/authentication.mdx +1 -1
- package/docs/content/locales/hi-IN/components.mdx +11 -1
- package/docs/content/locales/hi-IN/creating-templates.mdx +3 -7
- package/docs/content/locales/hi-IN/cross-app-sso.mdx +16 -6
- package/docs/content/locales/hi-IN/deployment.mdx +8 -0
- package/docs/content/locales/hi-IN/external-agents.mdx +2 -7
- package/docs/content/locales/hi-IN/key-concepts.mdx +13 -20
- package/docs/content/locales/hi-IN/multi-tenancy.mdx +5 -5
- package/docs/content/locales/hi-IN/notifications.mdx +18 -10
- package/docs/content/locales/hi-IN/processors.mdx +11 -5
- package/docs/content/locales/hi-IN/server.mdx +17 -10
- package/docs/content/locales/hi-IN/sharing.mdx +10 -10
- package/docs/content/locales/hi-IN/skills-guide.mdx +34 -17
- package/docs/content/locales/hi-IN/template-assets.mdx +16 -13
- package/docs/content/locales/hi-IN/template-brain.mdx +3 -1
- package/docs/content/locales/hi-IN/template-clips.mdx +3 -3
- package/docs/content/locales/hi-IN/template-design.mdx +3 -1
- package/docs/content/locales/hi-IN/template-dispatch.mdx +5 -1
- package/docs/content/locales/hi-IN/template-mail.mdx +8 -0
- package/docs/content/locales/hi-IN/tracking.mdx +9 -6
- package/docs/content/locales/hi-IN/using-your-agent.mdx +0 -7
- package/docs/content/locales/hi-IN/voice-input.mdx +6 -0
- package/docs/content/locales/hi-IN/workspace-connections.mdx +9 -2
- package/docs/content/locales/hi-IN/workspace.mdx +19 -18
- package/docs/content/locales/ja-JP/actions.mdx +2 -2
- package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/ja-JP/agent-surfaces.mdx +8 -10
- package/docs/content/locales/ja-JP/agent-teams.mdx +1 -0
- package/docs/content/locales/ja-JP/authentication.mdx +1 -1
- package/docs/content/locales/ja-JP/components.mdx +11 -1
- package/docs/content/locales/ja-JP/creating-templates.mdx +3 -7
- package/docs/content/locales/ja-JP/cross-app-sso.mdx +16 -6
- package/docs/content/locales/ja-JP/deployment.mdx +8 -0
- package/docs/content/locales/ja-JP/external-agents.mdx +2 -7
- package/docs/content/locales/ja-JP/key-concepts.mdx +13 -20
- package/docs/content/locales/ja-JP/multi-tenancy.mdx +5 -5
- package/docs/content/locales/ja-JP/notifications.mdx +18 -10
- package/docs/content/locales/ja-JP/processors.mdx +11 -5
- package/docs/content/locales/ja-JP/server.mdx +17 -10
- package/docs/content/locales/ja-JP/sharing.mdx +10 -10
- package/docs/content/locales/ja-JP/skills-guide.mdx +34 -17
- package/docs/content/locales/ja-JP/template-assets.mdx +16 -13
- package/docs/content/locales/ja-JP/template-brain.mdx +3 -1
- package/docs/content/locales/ja-JP/template-clips.mdx +3 -4
- package/docs/content/locales/ja-JP/template-design.mdx +3 -1
- package/docs/content/locales/ja-JP/template-dispatch.mdx +5 -1
- package/docs/content/locales/ja-JP/template-mail.mdx +8 -0
- package/docs/content/locales/ja-JP/tracking.mdx +9 -6
- package/docs/content/locales/ja-JP/using-your-agent.mdx +0 -7
- package/docs/content/locales/ja-JP/voice-input.mdx +6 -0
- package/docs/content/locales/ja-JP/workspace-connections.mdx +9 -2
- package/docs/content/locales/ja-JP/workspace.mdx +19 -18
- package/docs/content/locales/ko-KR/actions.mdx +2 -2
- package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/ko-KR/agent-surfaces.mdx +8 -10
- package/docs/content/locales/ko-KR/agent-teams.mdx +1 -0
- package/docs/content/locales/ko-KR/authentication.mdx +1 -1
- package/docs/content/locales/ko-KR/components.mdx +11 -1
- package/docs/content/locales/ko-KR/creating-templates.mdx +3 -7
- package/docs/content/locales/ko-KR/cross-app-sso.mdx +16 -6
- package/docs/content/locales/ko-KR/deployment.mdx +8 -0
- package/docs/content/locales/ko-KR/external-agents.mdx +2 -7
- package/docs/content/locales/ko-KR/key-concepts.mdx +13 -20
- package/docs/content/locales/ko-KR/multi-tenancy.mdx +5 -5
- package/docs/content/locales/ko-KR/notifications.mdx +18 -10
- package/docs/content/locales/ko-KR/processors.mdx +11 -5
- package/docs/content/locales/ko-KR/server.mdx +17 -10
- package/docs/content/locales/ko-KR/sharing.mdx +10 -10
- package/docs/content/locales/ko-KR/skills-guide.mdx +34 -17
- package/docs/content/locales/ko-KR/template-assets.mdx +16 -13
- package/docs/content/locales/ko-KR/template-brain.mdx +3 -1
- package/docs/content/locales/ko-KR/template-clips.mdx +3 -4
- package/docs/content/locales/ko-KR/template-design.mdx +3 -1
- package/docs/content/locales/ko-KR/template-dispatch.mdx +5 -1
- package/docs/content/locales/ko-KR/template-mail.mdx +8 -0
- package/docs/content/locales/ko-KR/tracking.mdx +9 -6
- package/docs/content/locales/ko-KR/using-your-agent.mdx +0 -7
- package/docs/content/locales/ko-KR/voice-input.mdx +6 -0
- package/docs/content/locales/ko-KR/workspace-connections.mdx +9 -2
- package/docs/content/locales/ko-KR/workspace.mdx +19 -18
- package/docs/content/locales/pt-BR/actions.mdx +2 -2
- package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/pt-BR/agent-surfaces.mdx +8 -10
- package/docs/content/locales/pt-BR/agent-teams.mdx +1 -0
- package/docs/content/locales/pt-BR/authentication.mdx +1 -1
- package/docs/content/locales/pt-BR/components.mdx +11 -1
- package/docs/content/locales/pt-BR/creating-templates.mdx +3 -7
- package/docs/content/locales/pt-BR/cross-app-sso.mdx +16 -6
- package/docs/content/locales/pt-BR/deployment.mdx +8 -0
- package/docs/content/locales/pt-BR/external-agents.mdx +3 -7
- package/docs/content/locales/pt-BR/key-concepts.mdx +13 -20
- package/docs/content/locales/pt-BR/multi-tenancy.mdx +5 -5
- package/docs/content/locales/pt-BR/notifications.mdx +18 -10
- package/docs/content/locales/pt-BR/processors.mdx +11 -5
- package/docs/content/locales/pt-BR/server.mdx +17 -10
- package/docs/content/locales/pt-BR/sharing.mdx +10 -10
- package/docs/content/locales/pt-BR/skills-guide.mdx +34 -17
- package/docs/content/locales/pt-BR/template-assets.mdx +16 -13
- package/docs/content/locales/pt-BR/template-brain.mdx +3 -1
- package/docs/content/locales/pt-BR/template-clips.mdx +3 -3
- package/docs/content/locales/pt-BR/template-design.mdx +3 -1
- package/docs/content/locales/pt-BR/template-dispatch.mdx +5 -1
- package/docs/content/locales/pt-BR/template-mail.mdx +8 -0
- package/docs/content/locales/pt-BR/tracking.mdx +9 -6
- package/docs/content/locales/pt-BR/using-your-agent.mdx +0 -7
- package/docs/content/locales/pt-BR/voice-input.mdx +6 -0
- package/docs/content/locales/pt-BR/workspace-connections.mdx +9 -2
- package/docs/content/locales/pt-BR/workspace.mdx +19 -18
- package/docs/content/locales/zh-CN/actions.mdx +2 -2
- package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/zh-CN/agent-surfaces.mdx +8 -10
- package/docs/content/locales/zh-CN/agent-teams.mdx +1 -0
- package/docs/content/locales/zh-CN/authentication.mdx +1 -1
- package/docs/content/locales/zh-CN/components.mdx +11 -1
- package/docs/content/locales/zh-CN/creating-templates.mdx +3 -7
- package/docs/content/locales/zh-CN/cross-app-sso.mdx +16 -6
- package/docs/content/locales/zh-CN/deployment.mdx +8 -0
- package/docs/content/locales/zh-CN/external-agents.mdx +2 -7
- package/docs/content/locales/zh-CN/key-concepts.mdx +13 -20
- package/docs/content/locales/zh-CN/multi-tenancy.mdx +5 -5
- package/docs/content/locales/zh-CN/notifications.mdx +18 -10
- package/docs/content/locales/zh-CN/processors.mdx +11 -5
- package/docs/content/locales/zh-CN/server.mdx +16 -10
- package/docs/content/locales/zh-CN/sharing.mdx +10 -10
- package/docs/content/locales/zh-CN/skills-guide.mdx +34 -17
- package/docs/content/locales/zh-CN/template-assets.mdx +16 -13
- package/docs/content/locales/zh-CN/template-brain.mdx +3 -1
- package/docs/content/locales/zh-CN/template-clips.mdx +3 -4
- package/docs/content/locales/zh-CN/template-design.mdx +3 -1
- package/docs/content/locales/zh-CN/template-dispatch.mdx +5 -1
- package/docs/content/locales/zh-CN/template-mail.mdx +8 -0
- package/docs/content/locales/zh-CN/tracking.mdx +9 -6
- package/docs/content/locales/zh-CN/using-your-agent.mdx +0 -7
- package/docs/content/locales/zh-CN/voice-input.mdx +6 -0
- package/docs/content/locales/zh-CN/workspace-connections.mdx +9 -2
- package/docs/content/locales/zh-CN/workspace.mdx +19 -18
- package/docs/content/locales/zh-TW/actions.mdx +2 -2
- package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +2 -2
- package/docs/content/locales/zh-TW/agent-surfaces.mdx +8 -10
- package/docs/content/locales/zh-TW/agent-teams.mdx +1 -0
- package/docs/content/locales/zh-TW/authentication.mdx +1 -1
- package/docs/content/locales/zh-TW/components.mdx +11 -1
- package/docs/content/locales/zh-TW/creating-templates.mdx +3 -7
- package/docs/content/locales/zh-TW/cross-app-sso.mdx +16 -6
- package/docs/content/locales/zh-TW/deployment.mdx +8 -0
- package/docs/content/locales/zh-TW/external-agents.mdx +2 -7
- package/docs/content/locales/zh-TW/key-concepts.mdx +13 -20
- package/docs/content/locales/zh-TW/multi-tenancy.mdx +5 -5
- package/docs/content/locales/zh-TW/notifications.mdx +18 -10
- package/docs/content/locales/zh-TW/processors.mdx +11 -5
- package/docs/content/locales/zh-TW/server.mdx +16 -10
- package/docs/content/locales/zh-TW/sharing.mdx +10 -10
- package/docs/content/locales/zh-TW/skills-guide.mdx +34 -17
- package/docs/content/locales/zh-TW/template-assets.mdx +16 -13
- package/docs/content/locales/zh-TW/template-brain.mdx +3 -1
- package/docs/content/locales/zh-TW/template-clips.mdx +3 -4
- package/docs/content/locales/zh-TW/template-design.mdx +3 -1
- package/docs/content/locales/zh-TW/template-dispatch.mdx +5 -1
- package/docs/content/locales/zh-TW/template-mail.mdx +8 -0
- package/docs/content/locales/zh-TW/tracking.mdx +9 -6
- package/docs/content/locales/zh-TW/using-your-agent.mdx +0 -7
- package/docs/content/locales/zh-TW/voice-input.mdx +6 -0
- package/docs/content/locales/zh-TW/workspace-connections.mdx +9 -2
- package/docs/content/locales/zh-TW/workspace.mdx +19 -18
- package/docs/content/mcp-apps.mdx +14 -32
- package/docs/content/mcp-clients.mdx +48 -54
- package/docs/content/mcp-protocol.mdx +25 -10
- package/docs/content/messaging.mdx +19 -11
- package/docs/content/multi-app-workspace.mdx +11 -96
- package/docs/content/multi-tenancy.mdx +5 -5
- package/docs/content/native-chat-ui.mdx +4 -4
- package/docs/content/notifications.mdx +19 -12
- package/docs/content/observability.mdx +2 -4
- package/docs/content/observational-memory.mdx +7 -3
- package/docs/content/onboarding.mdx +9 -2
- package/docs/content/plan-plugin.mdx +10 -2
- package/docs/content/pr-visual-recap.mdx +1 -1
- package/docs/content/processors.mdx +11 -5
- package/docs/content/pure-agent-apps.mdx +5 -1
- package/docs/content/real-time-collaboration.mdx +30 -67
- package/docs/content/recurring-jobs.mdx +8 -6
- package/docs/content/routing.mdx +3 -4
- package/docs/content/sandbox-adapters.mdx +30 -53
- package/docs/content/security.mdx +8 -0
- package/docs/content/server.mdx +17 -10
- package/docs/content/sharing.mdx +10 -10
- package/docs/content/skills-guide.mdx +35 -16
- package/docs/content/template-analytics.mdx +11 -8
- package/docs/content/template-assets.mdx +16 -13
- package/docs/content/template-brain.mdx +3 -1
- package/docs/content/template-calendar.mdx +12 -4
- package/docs/content/template-chat.mdx +4 -4
- package/docs/content/template-clips.mdx +3 -3
- package/docs/content/template-content.mdx +23 -18
- package/docs/content/template-design.mdx +3 -1
- package/docs/content/template-dispatch.mdx +5 -1
- package/docs/content/template-mail.mdx +14 -2
- package/docs/content/template-plan.mdx +22 -15
- package/docs/content/template-slides.mdx +11 -3
- package/docs/content/toolkit-agent-ux.mdx +46 -3
- package/docs/content/toolkit-collaboration.mdx +58 -4
- package/docs/content/toolkit-command-navigation.mdx +8 -2
- package/docs/content/toolkit-comments-review.mdx +10 -2
- package/docs/content/toolkit-history.mdx +8 -3
- package/docs/content/toolkit-observability.mdx +48 -2
- package/docs/content/toolkit-org-team.mdx +8 -2
- package/docs/content/toolkit-resources.mdx +45 -2
- package/docs/content/toolkit-settings.mdx +8 -2
- package/docs/content/toolkit-setup-connections.mdx +7 -2
- package/docs/content/toolkit-sharing.mdx +46 -3
- package/docs/content/toolkit-ui.mdx +82 -11
- package/docs/content/tracking.mdx +10 -8
- package/docs/content/using-your-agent.mdx +0 -12
- package/docs/content/voice-input.mdx +7 -1
- package/docs/content/what-is-agent-native.mdx +7 -8
- package/docs/content/workspace-connections.mdx +16 -23
- package/docs/content/workspace-management.mdx +16 -4
- package/docs/content/workspace.mdx +19 -18
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -5
- package/corpus/core/docs/content/locales/ar-SA/migration-workbench.mdx +0 -76
- package/corpus/core/docs/content/locales/de-DE/migration-workbench.mdx +0 -76
- package/corpus/core/docs/content/locales/es-ES/migration-workbench.mdx +0 -76
- package/corpus/core/docs/content/locales/fr-FR/migration-workbench.mdx +0 -76
- package/corpus/core/docs/content/locales/hi-IN/migration-workbench.mdx +0 -74
- package/corpus/core/docs/content/locales/ja-JP/migration-workbench.mdx +0 -76
- package/corpus/core/docs/content/locales/ko-KR/migration-workbench.mdx +0 -74
- package/corpus/core/docs/content/locales/pt-BR/migration-workbench.mdx +0 -76
- package/corpus/core/docs/content/locales/zh-CN/migration-workbench.mdx +0 -74
- package/corpus/core/docs/content/locales/zh-TW/migration-workbench.mdx +0 -74
- package/corpus/core/docs/content/migration-workbench.mdx +0 -74
- package/corpus/core/docs/content/toolkit-app-adapters.mdx +0 -55
- package/corpus/core/docs/content/toolkit-collaboration-ui.mdx +0 -60
- package/corpus/core/docs/content/toolkit-sharing-ui.mdx +0 -45
- package/corpus/core/docs/content/toolkit-shell-hooks.mdx +0 -36
- package/docs/content/locales/ar-SA/migration-workbench.mdx +0 -76
- package/docs/content/locales/de-DE/migration-workbench.mdx +0 -76
- package/docs/content/locales/es-ES/migration-workbench.mdx +0 -76
- package/docs/content/locales/fr-FR/migration-workbench.mdx +0 -76
- package/docs/content/locales/hi-IN/migration-workbench.mdx +0 -74
- package/docs/content/locales/ja-JP/migration-workbench.mdx +0 -76
- package/docs/content/locales/ko-KR/migration-workbench.mdx +0 -74
- package/docs/content/locales/pt-BR/migration-workbench.mdx +0 -76
- package/docs/content/locales/zh-CN/migration-workbench.mdx +0 -74
- package/docs/content/locales/zh-TW/migration-workbench.mdx +0 -74
- package/docs/content/migration-workbench.mdx +0 -74
- package/docs/content/toolkit-app-adapters.mdx +0 -55
- package/docs/content/toolkit-collaboration-ui.mdx +0 -60
- package/docs/content/toolkit-sharing-ui.mdx +0 -45
- package/docs/content/toolkit-shell-hooks.mdx +0 -36
|
@@ -109,6 +109,12 @@ export function toPublicRemoteDevice(device) {
|
|
|
109
109
|
updatedAt: device.updatedAt,
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
|
+
export function getRemoteComputerCapabilities(device) {
|
|
113
|
+
const value = device.metadata?.computerCapabilities;
|
|
114
|
+
if (!value || typeof value !== "object")
|
|
115
|
+
return null;
|
|
116
|
+
return normalizeComputerCapabilities(value);
|
|
117
|
+
}
|
|
112
118
|
export async function createRemoteDevice(input) {
|
|
113
119
|
await ensureTable();
|
|
114
120
|
const client = getDbExec();
|
|
@@ -129,7 +135,7 @@ export async function createRemoteDevice(input) {
|
|
|
129
135
|
sanitizeOptionalString(input.platform, 80),
|
|
130
136
|
sanitizeOptionalString(input.appVersion, 120),
|
|
131
137
|
sanitizeOptionalString(input.hostName, 200),
|
|
132
|
-
|
|
138
|
+
serializeRemoteDeviceMetadata(input.metadata),
|
|
133
139
|
tokenHash,
|
|
134
140
|
now,
|
|
135
141
|
"active",
|
|
@@ -251,7 +257,7 @@ export async function updateRemoteDeviceDetails(input) {
|
|
|
251
257
|
}
|
|
252
258
|
if (input.metadata !== undefined) {
|
|
253
259
|
updates.push("metadata_json = ?");
|
|
254
|
-
args.push(
|
|
260
|
+
args.push(serializeRemoteDeviceMetadata(input.metadata));
|
|
255
261
|
}
|
|
256
262
|
if (updates.length === 0)
|
|
257
263
|
return getRemoteDevice(input.id);
|
|
@@ -321,6 +327,47 @@ function parseJson(value, fallback) {
|
|
|
321
327
|
return fallback;
|
|
322
328
|
}
|
|
323
329
|
}
|
|
330
|
+
function serializeRemoteDeviceMetadata(metadata) {
|
|
331
|
+
if (!metadata)
|
|
332
|
+
return null;
|
|
333
|
+
const normalized = { ...metadata };
|
|
334
|
+
if (metadata.computerCapabilities !== undefined) {
|
|
335
|
+
normalized.computerCapabilities = normalizeComputerCapabilities(metadata.computerCapabilities);
|
|
336
|
+
}
|
|
337
|
+
const json = JSON.stringify(normalized);
|
|
338
|
+
if (new TextEncoder().encode(json).byteLength > 32_768) {
|
|
339
|
+
throw new Error("Remote device metadata exceeds 32 KiB");
|
|
340
|
+
}
|
|
341
|
+
if (/"data:[^"]*"/i.test(json) || looksLikeLargeBase64(json)) {
|
|
342
|
+
throw new Error("Remote device metadata cannot contain binary payloads");
|
|
343
|
+
}
|
|
344
|
+
return json;
|
|
345
|
+
}
|
|
346
|
+
function normalizeComputerCapabilities(value) {
|
|
347
|
+
const result = {};
|
|
348
|
+
if (value.browser && typeof value.browser === "object") {
|
|
349
|
+
result.browser = {
|
|
350
|
+
observe: value.browser.observe === true,
|
|
351
|
+
control: value.browser.control === true,
|
|
352
|
+
provider: sanitizeOptionalString(value.browser.provider, 120),
|
|
353
|
+
version: sanitizeOptionalString(value.browser.version, 120),
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
if (value.desktop && typeof value.desktop === "object") {
|
|
357
|
+
result.desktop = {
|
|
358
|
+
observe: value.desktop.observe === true,
|
|
359
|
+
control: value.desktop.control === true,
|
|
360
|
+
accessibility: value.desktop.accessibility === true,
|
|
361
|
+
screenCapture: value.desktop.screenCapture === true,
|
|
362
|
+
provider: sanitizeOptionalString(value.desktop.provider, 120),
|
|
363
|
+
version: sanitizeOptionalString(value.desktop.version, 120),
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
return result;
|
|
367
|
+
}
|
|
368
|
+
function looksLikeLargeBase64(value) {
|
|
369
|
+
return value.length > 4_096 && /[A-Za-z0-9+/]{4_096,}={0,2}/.test(value);
|
|
370
|
+
}
|
|
324
371
|
function randomHex(byteLength) {
|
|
325
372
|
const bytes = new Uint8Array(byteLength);
|
|
326
373
|
globalThis.crypto.getRandomValues(bytes);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-devices-store.js","sourceRoot":"","sources":["../../src/integrations/remote-devices-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getDbExec,\n intType,\n isPostgres,\n retryOnDdlRace,\n} from \"../db/client.js\";\nimport {\n ensureColumnExists,\n ensureIndexExists,\n ensureTableExists,\n} from \"../db/ddl-guard.js\";\nimport type { PublicRemoteDevice, RemoteDevice } from \"./remote-types.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createSql = `\n CREATE TABLE IF NOT EXISTS integration_remote_devices (\n id TEXT PRIMARY KEY,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n label TEXT NOT NULL,\n platform TEXT,\n app_version TEXT,\n host_name TEXT,\n metadata_json TEXT,\n device_token_hash TEXT NOT NULL,\n last_seen_at ${intType()},\n status TEXT NOT NULL,\n revoked_at ${intType()},\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n `;\n\n if (isPostgres()) {\n // PG guard: probe via information_schema, only issue DDL if missing, bounded lock_timeout\n await ensureTableExists(\"integration_remote_devices\", createSql);\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"platform\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS platform TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"app_version\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS app_version TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"host_name\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS host_name TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"metadata_json\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS metadata_json TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"revoked_at\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS revoked_at ${intType()}`,\n );\n await ensureIndexExists(\n \"idx_remote_devices_token_hash\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_devices_token_hash ON integration_remote_devices(device_token_hash)`,\n );\n await ensureIndexExists(\n \"idx_remote_devices_owner\",\n `CREATE INDEX IF NOT EXISTS idx_remote_devices_owner ON integration_remote_devices(owner_email, org_id)`,\n );\n return;\n }\n // SQLite (local dev): keep existing behavior verbatim\n await retryOnDdlRace(() => client.execute(createSql));\n await addColumnIfMissing(\"platform\", \"TEXT\");\n await addColumnIfMissing(\"app_version\", \"TEXT\");\n await addColumnIfMissing(\"host_name\", \"TEXT\");\n await addColumnIfMissing(\"metadata_json\", \"TEXT\");\n await addColumnIfMissing(\"revoked_at\", intType());\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_devices_token_hash ON integration_remote_devices(device_token_hash)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_devices_owner ON integration_remote_devices(owner_email, org_id)`,\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 addColumnIfMissing(\n name: string,\n definition: string,\n): Promise<void> {\n const sql = isPostgres()\n ? `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS ${name} ${definition}`\n : `ALTER TABLE integration_remote_devices ADD COLUMN ${name} ${definition}`;\n try {\n await retryOnDdlRace(() => getDbExec().execute(sql));\n } catch (err) {\n if (isDuplicateColumnError(err)) return;\n throw err;\n }\n}\n\nfunction isDuplicateColumnError(err: unknown): boolean {\n const code = String((err as { code?: unknown })?.code ?? \"\");\n const message = String((err as { message?: unknown })?.message ?? err)\n .toLowerCase()\n .trim();\n return (\n code === \"42701\" ||\n message.includes(\"duplicate column\") ||\n message.includes(\"already exists\")\n );\n}\n\nfunction rowToDevice(row: Record<string, unknown>): RemoteDevice {\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 label: row.label as string,\n platform: (row.platform as string | null) ?? null,\n appVersion: (row.app_version as string | null) ?? null,\n hostName: (row.host_name as string | null) ?? null,\n metadata: parseJson(row.metadata_json, null) as Record<\n string,\n unknown\n > | null,\n deviceTokenHash: row.device_token_hash as string,\n lastSeenAt:\n row.last_seen_at == null ? null : Number(row.last_seen_at as number),\n status: row.status as RemoteDevice[\"status\"],\n revokedAt: row.revoked_at == null ? null : Number(row.revoked_at as number),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\nexport function toPublicRemoteDevice(device: RemoteDevice): PublicRemoteDevice {\n return {\n id: device.id,\n ownerEmail: device.ownerEmail,\n orgId: device.orgId,\n label: device.label,\n platform: device.platform,\n appVersion: device.appVersion,\n hostName: device.hostName,\n metadata: device.metadata,\n lastSeenAt: device.lastSeenAt,\n status: device.status,\n revokedAt: device.revokedAt,\n createdAt: device.createdAt,\n updatedAt: device.updatedAt,\n };\n}\n\nexport async function createRemoteDevice(input: {\n ownerEmail: string;\n orgId?: string | null;\n label: string;\n platform?: string | null;\n appVersion?: string | null;\n hostName?: string | null;\n metadata?: Record<string, unknown> | null;\n}): Promise<{ device: RemoteDevice; token: string }> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const id = `remote-device-${now}-${randomHex(8)}`;\n const token = `anr_${randomHex(32)}`;\n const tokenHash = await hashRemoteDeviceToken(token);\n\n await client.execute({\n sql: `INSERT INTO integration_remote_devices\n (id, owner_email, org_id, label, platform, app_version, host_name, metadata_json,\n device_token_hash, last_seen_at, status, revoked_at, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n input.ownerEmail,\n input.orgId ?? null,\n input.label.trim() || \"Remote device\",\n sanitizeOptionalString(input.platform, 80),\n sanitizeOptionalString(input.appVersion, 120),\n sanitizeOptionalString(input.hostName, 200),\n input.metadata ? JSON.stringify(input.metadata) : null,\n tokenHash,\n now,\n \"active\",\n null,\n now,\n now,\n ],\n });\n\n const device = await getRemoteDevice(id);\n if (!device) throw new Error(\"remote device insert failed\");\n return { device, token };\n}\n\nexport async function getRemoteDevice(\n id: string,\n): Promise<RemoteDevice | null> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_devices WHERE id = ? LIMIT 1`,\n args: [id],\n });\n return rows[0] ? rowToDevice(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function getRemoteDeviceForOwner(input: {\n id: string;\n ownerEmail: string;\n orgId?: string | null;\n}): Promise<RemoteDevice | null> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_devices\n WHERE id = ?\n AND owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)\n LIMIT 1`,\n args: [\n input.id,\n input.ownerEmail,\n input.orgId ?? null,\n input.orgId ?? null,\n ],\n });\n return rows[0] ? rowToDevice(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function listRemoteDevicesForOwner(input: {\n ownerEmail: string;\n orgId?: string | null;\n status?: RemoteDevice[\"status\"];\n limit?: number;\n}): Promise<RemoteDevice[]> {\n await ensureTable();\n const limit = Math.max(1, Math.min(input.limit ?? 50, 100));\n const statusClause = input.status ? \" AND status = ?\" : \"\";\n if (!Object.prototype.hasOwnProperty.call(input, \"orgId\")) {\n const args: Array<string | number> = [input.ownerEmail];\n if (input.status) args.push(input.status);\n args.push(limit);\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_devices\n WHERE owner_email = ?${statusClause}\n ORDER BY COALESCE(last_seen_at, updated_at) DESC\n LIMIT ?`,\n args,\n });\n return rows.map((row) => rowToDevice(row as Record<string, unknown>));\n }\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_devices\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,\n });\n return rows.map((row) => rowToDevice(row as Record<string, unknown>));\n}\n\nexport async function authenticateRemoteDeviceToken(\n rawToken: string | null | undefined,\n): Promise<RemoteDevice | null> {\n if (!rawToken) return null;\n await ensureTable();\n const tokenHash = await hashRemoteDeviceToken(rawToken);\n const now = Date.now();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM integration_remote_devices\n WHERE device_token_hash = ? AND status = 'active'\n LIMIT 1`,\n args: [tokenHash],\n });\n if (!rows[0]) return null;\n const device = rowToDevice(rows[0] as Record<string, unknown>);\n await client.execute({\n sql: `UPDATE integration_remote_devices\n SET last_seen_at = ?, updated_at = ?\n WHERE id = ?`,\n args: [now, now, device.id],\n });\n return { ...device, lastSeenAt: now, updatedAt: now };\n}\n\nexport async function updateRemoteDeviceDetails(input: {\n id: string;\n label?: string | null;\n platform?: string | null;\n appVersion?: string | null;\n hostName?: string | null;\n metadata?: Record<string, unknown> | null;\n}): Promise<RemoteDevice | null> {\n await ensureTable();\n const now = Date.now();\n const updates: string[] = [];\n const args: Array<string | number | null> = [];\n if (input.label !== undefined) {\n updates.push(\"label = ?\");\n args.push(sanitizeOptionalString(input.label, 200) ?? \"Remote device\");\n }\n if (input.platform !== undefined) {\n updates.push(\"platform = ?\");\n args.push(sanitizeOptionalString(input.platform, 80));\n }\n if (input.appVersion !== undefined) {\n updates.push(\"app_version = ?\");\n args.push(sanitizeOptionalString(input.appVersion, 120));\n }\n if (input.hostName !== undefined) {\n updates.push(\"host_name = ?\");\n args.push(sanitizeOptionalString(input.hostName, 200));\n }\n if (input.metadata !== undefined) {\n updates.push(\"metadata_json = ?\");\n args.push(input.metadata ? JSON.stringify(input.metadata) : null);\n }\n if (updates.length === 0) return getRemoteDevice(input.id);\n\n updates.push(\"updated_at = ?\");\n args.push(now, input.id);\n await getDbExec().execute({\n sql: `UPDATE integration_remote_devices\n SET ${updates.join(\", \")}\n WHERE id = ? AND status = 'active'`,\n args,\n });\n return getRemoteDevice(input.id);\n}\n\nexport async function revokeRemoteDeviceForOwner(input: {\n id: string;\n ownerEmail: string;\n orgId?: string | null;\n}): Promise<RemoteDevice | null> {\n await ensureTable();\n const now = Date.now();\n await getDbExec().execute({\n sql: `UPDATE integration_remote_devices\n SET status = 'inactive',\n revoked_at = COALESCE(revoked_at, ?),\n updated_at = ?\n WHERE id = ?\n AND owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)`,\n args: [\n now,\n now,\n input.id,\n input.ownerEmail,\n input.orgId ?? null,\n input.orgId ?? null,\n ],\n });\n return getRemoteDeviceForOwner(input);\n}\n\nexport async function unregisterRemoteDevice(id: string): Promise<boolean> {\n await ensureTable();\n const now = Date.now();\n const result = await getDbExec().execute({\n sql: `UPDATE integration_remote_devices\n SET status = 'inactive',\n revoked_at = COALESCE(revoked_at, ?),\n updated_at = ?\n WHERE id = ? AND status = 'active'`,\n args: [now, now, id],\n });\n return (result.rowsAffected ?? (result as any).rowCount ?? 0) > 0;\n}\n\nexport async function hashRemoteDeviceToken(token: string): Promise<string> {\n const bytes = new TextEncoder().encode(token);\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", bytes);\n return bytesToHex(new Uint8Array(digest));\n}\n\nfunction sanitizeOptionalString(\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\nfunction randomHex(byteLength: number): string {\n const bytes = new Uint8Array(byteLength);\n globalThis.crypto.getRandomValues(bytes);\n return bytesToHex(bytes);\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remote-devices-store.js","sourceRoot":"","sources":["../../src/integrations/remote-devices-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getDbExec,\n intType,\n isPostgres,\n retryOnDdlRace,\n} from \"../db/client.js\";\nimport {\n ensureColumnExists,\n ensureIndexExists,\n ensureTableExists,\n} from \"../db/ddl-guard.js\";\nimport type {\n PublicRemoteDevice,\n RemoteComputerCapabilities,\n RemoteDevice,\n RemoteDeviceMetadata,\n} from \"./remote-types.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createSql = `\n CREATE TABLE IF NOT EXISTS integration_remote_devices (\n id TEXT PRIMARY KEY,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n label TEXT NOT NULL,\n platform TEXT,\n app_version TEXT,\n host_name TEXT,\n metadata_json TEXT,\n device_token_hash TEXT NOT NULL,\n last_seen_at ${intType()},\n status TEXT NOT NULL,\n revoked_at ${intType()},\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n `;\n\n if (isPostgres()) {\n // PG guard: probe via information_schema, only issue DDL if missing, bounded lock_timeout\n await ensureTableExists(\"integration_remote_devices\", createSql);\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"platform\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS platform TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"app_version\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS app_version TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"host_name\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS host_name TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"metadata_json\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS metadata_json TEXT`,\n );\n await ensureColumnExists(\n \"integration_remote_devices\",\n \"revoked_at\",\n `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS revoked_at ${intType()}`,\n );\n await ensureIndexExists(\n \"idx_remote_devices_token_hash\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_devices_token_hash ON integration_remote_devices(device_token_hash)`,\n );\n await ensureIndexExists(\n \"idx_remote_devices_owner\",\n `CREATE INDEX IF NOT EXISTS idx_remote_devices_owner ON integration_remote_devices(owner_email, org_id)`,\n );\n return;\n }\n // SQLite (local dev): keep existing behavior verbatim\n await retryOnDdlRace(() => client.execute(createSql));\n await addColumnIfMissing(\"platform\", \"TEXT\");\n await addColumnIfMissing(\"app_version\", \"TEXT\");\n await addColumnIfMissing(\"host_name\", \"TEXT\");\n await addColumnIfMissing(\"metadata_json\", \"TEXT\");\n await addColumnIfMissing(\"revoked_at\", intType());\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_devices_token_hash ON integration_remote_devices(device_token_hash)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_devices_owner ON integration_remote_devices(owner_email, org_id)`,\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 addColumnIfMissing(\n name: string,\n definition: string,\n): Promise<void> {\n const sql = isPostgres()\n ? `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS ${name} ${definition}`\n : `ALTER TABLE integration_remote_devices ADD COLUMN ${name} ${definition}`;\n try {\n await retryOnDdlRace(() => getDbExec().execute(sql));\n } catch (err) {\n if (isDuplicateColumnError(err)) return;\n throw err;\n }\n}\n\nfunction isDuplicateColumnError(err: unknown): boolean {\n const code = String((err as { code?: unknown })?.code ?? \"\");\n const message = String((err as { message?: unknown })?.message ?? err)\n .toLowerCase()\n .trim();\n return (\n code === \"42701\" ||\n message.includes(\"duplicate column\") ||\n message.includes(\"already exists\")\n );\n}\n\nfunction rowToDevice(row: Record<string, unknown>): RemoteDevice {\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 label: row.label as string,\n platform: (row.platform as string | null) ?? null,\n appVersion: (row.app_version as string | null) ?? null,\n hostName: (row.host_name as string | null) ?? null,\n metadata: parseJson(row.metadata_json, null) as RemoteDeviceMetadata | null,\n deviceTokenHash: row.device_token_hash as string,\n lastSeenAt:\n row.last_seen_at == null ? null : Number(row.last_seen_at as number),\n status: row.status as RemoteDevice[\"status\"],\n revokedAt: row.revoked_at == null ? null : Number(row.revoked_at as number),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\nexport function toPublicRemoteDevice(device: RemoteDevice): PublicRemoteDevice {\n return {\n id: device.id,\n ownerEmail: device.ownerEmail,\n orgId: device.orgId,\n label: device.label,\n platform: device.platform,\n appVersion: device.appVersion,\n hostName: device.hostName,\n metadata: device.metadata,\n lastSeenAt: device.lastSeenAt,\n status: device.status,\n revokedAt: device.revokedAt,\n createdAt: device.createdAt,\n updatedAt: device.updatedAt,\n };\n}\n\nexport function getRemoteComputerCapabilities(\n device: Pick<RemoteDevice, \"metadata\">,\n): RemoteComputerCapabilities | null {\n const value = device.metadata?.computerCapabilities;\n if (!value || typeof value !== \"object\") return null;\n return normalizeComputerCapabilities(value);\n}\n\nexport async function createRemoteDevice(input: {\n ownerEmail: string;\n orgId?: string | null;\n label: string;\n platform?: string | null;\n appVersion?: string | null;\n hostName?: string | null;\n metadata?: RemoteDeviceMetadata | null;\n}): Promise<{ device: RemoteDevice; token: string }> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const id = `remote-device-${now}-${randomHex(8)}`;\n const token = `anr_${randomHex(32)}`;\n const tokenHash = await hashRemoteDeviceToken(token);\n\n await client.execute({\n sql: `INSERT INTO integration_remote_devices\n (id, owner_email, org_id, label, platform, app_version, host_name, metadata_json,\n device_token_hash, last_seen_at, status, revoked_at, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n input.ownerEmail,\n input.orgId ?? null,\n input.label.trim() || \"Remote device\",\n sanitizeOptionalString(input.platform, 80),\n sanitizeOptionalString(input.appVersion, 120),\n sanitizeOptionalString(input.hostName, 200),\n serializeRemoteDeviceMetadata(input.metadata),\n tokenHash,\n now,\n \"active\",\n null,\n now,\n now,\n ],\n });\n\n const device = await getRemoteDevice(id);\n if (!device) throw new Error(\"remote device insert failed\");\n return { device, token };\n}\n\nexport async function getRemoteDevice(\n id: string,\n): Promise<RemoteDevice | null> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_devices WHERE id = ? LIMIT 1`,\n args: [id],\n });\n return rows[0] ? rowToDevice(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function getRemoteDeviceForOwner(input: {\n id: string;\n ownerEmail: string;\n orgId?: string | null;\n}): Promise<RemoteDevice | null> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_devices\n WHERE id = ?\n AND owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)\n LIMIT 1`,\n args: [\n input.id,\n input.ownerEmail,\n input.orgId ?? null,\n input.orgId ?? null,\n ],\n });\n return rows[0] ? rowToDevice(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function listRemoteDevicesForOwner(input: {\n ownerEmail: string;\n orgId?: string | null;\n status?: RemoteDevice[\"status\"];\n limit?: number;\n}): Promise<RemoteDevice[]> {\n await ensureTable();\n const limit = Math.max(1, Math.min(input.limit ?? 50, 100));\n const statusClause = input.status ? \" AND status = ?\" : \"\";\n if (!Object.prototype.hasOwnProperty.call(input, \"orgId\")) {\n const args: Array<string | number> = [input.ownerEmail];\n if (input.status) args.push(input.status);\n args.push(limit);\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_devices\n WHERE owner_email = ?${statusClause}\n ORDER BY COALESCE(last_seen_at, updated_at) DESC\n LIMIT ?`,\n args,\n });\n return rows.map((row) => rowToDevice(row as Record<string, unknown>));\n }\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_devices\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,\n });\n return rows.map((row) => rowToDevice(row as Record<string, unknown>));\n}\n\nexport async function authenticateRemoteDeviceToken(\n rawToken: string | null | undefined,\n): Promise<RemoteDevice | null> {\n if (!rawToken) return null;\n await ensureTable();\n const tokenHash = await hashRemoteDeviceToken(rawToken);\n const now = Date.now();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM integration_remote_devices\n WHERE device_token_hash = ? AND status = 'active'\n LIMIT 1`,\n args: [tokenHash],\n });\n if (!rows[0]) return null;\n const device = rowToDevice(rows[0] as Record<string, unknown>);\n await client.execute({\n sql: `UPDATE integration_remote_devices\n SET last_seen_at = ?, updated_at = ?\n WHERE id = ?`,\n args: [now, now, device.id],\n });\n return { ...device, lastSeenAt: now, updatedAt: now };\n}\n\nexport async function updateRemoteDeviceDetails(input: {\n id: string;\n label?: string | null;\n platform?: string | null;\n appVersion?: string | null;\n hostName?: string | null;\n metadata?: RemoteDeviceMetadata | null;\n}): Promise<RemoteDevice | null> {\n await ensureTable();\n const now = Date.now();\n const updates: string[] = [];\n const args: Array<string | number | null> = [];\n if (input.label !== undefined) {\n updates.push(\"label = ?\");\n args.push(sanitizeOptionalString(input.label, 200) ?? \"Remote device\");\n }\n if (input.platform !== undefined) {\n updates.push(\"platform = ?\");\n args.push(sanitizeOptionalString(input.platform, 80));\n }\n if (input.appVersion !== undefined) {\n updates.push(\"app_version = ?\");\n args.push(sanitizeOptionalString(input.appVersion, 120));\n }\n if (input.hostName !== undefined) {\n updates.push(\"host_name = ?\");\n args.push(sanitizeOptionalString(input.hostName, 200));\n }\n if (input.metadata !== undefined) {\n updates.push(\"metadata_json = ?\");\n args.push(serializeRemoteDeviceMetadata(input.metadata));\n }\n if (updates.length === 0) return getRemoteDevice(input.id);\n\n updates.push(\"updated_at = ?\");\n args.push(now, input.id);\n await getDbExec().execute({\n sql: `UPDATE integration_remote_devices\n SET ${updates.join(\", \")}\n WHERE id = ? AND status = 'active'`,\n args,\n });\n return getRemoteDevice(input.id);\n}\n\nexport async function revokeRemoteDeviceForOwner(input: {\n id: string;\n ownerEmail: string;\n orgId?: string | null;\n}): Promise<RemoteDevice | null> {\n await ensureTable();\n const now = Date.now();\n await getDbExec().execute({\n sql: `UPDATE integration_remote_devices\n SET status = 'inactive',\n revoked_at = COALESCE(revoked_at, ?),\n updated_at = ?\n WHERE id = ?\n AND owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)`,\n args: [\n now,\n now,\n input.id,\n input.ownerEmail,\n input.orgId ?? null,\n input.orgId ?? null,\n ],\n });\n return getRemoteDeviceForOwner(input);\n}\n\nexport async function unregisterRemoteDevice(id: string): Promise<boolean> {\n await ensureTable();\n const now = Date.now();\n const result = await getDbExec().execute({\n sql: `UPDATE integration_remote_devices\n SET status = 'inactive',\n revoked_at = COALESCE(revoked_at, ?),\n updated_at = ?\n WHERE id = ? AND status = 'active'`,\n args: [now, now, id],\n });\n return (result.rowsAffected ?? (result as any).rowCount ?? 0) > 0;\n}\n\nexport async function hashRemoteDeviceToken(token: string): Promise<string> {\n const bytes = new TextEncoder().encode(token);\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", bytes);\n return bytesToHex(new Uint8Array(digest));\n}\n\nfunction sanitizeOptionalString(\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\nfunction serializeRemoteDeviceMetadata(\n metadata: RemoteDeviceMetadata | null | undefined,\n): string | null {\n if (!metadata) return null;\n const normalized: RemoteDeviceMetadata = { ...metadata };\n if (metadata.computerCapabilities !== undefined) {\n normalized.computerCapabilities = normalizeComputerCapabilities(\n metadata.computerCapabilities,\n );\n }\n const json = JSON.stringify(normalized);\n if (new TextEncoder().encode(json).byteLength > 32_768) {\n throw new Error(\"Remote device metadata exceeds 32 KiB\");\n }\n if (/\"data:[^\"]*\"/i.test(json) || looksLikeLargeBase64(json)) {\n throw new Error(\"Remote device metadata cannot contain binary payloads\");\n }\n return json;\n}\n\nfunction normalizeComputerCapabilities(\n value: RemoteComputerCapabilities,\n): RemoteComputerCapabilities {\n const result: RemoteComputerCapabilities = {};\n if (value.browser && typeof value.browser === \"object\") {\n result.browser = {\n observe: value.browser.observe === true,\n control: value.browser.control === true,\n provider: sanitizeOptionalString(value.browser.provider, 120),\n version: sanitizeOptionalString(value.browser.version, 120),\n };\n }\n if (value.desktop && typeof value.desktop === \"object\") {\n result.desktop = {\n observe: value.desktop.observe === true,\n control: value.desktop.control === true,\n accessibility: value.desktop.accessibility === true,\n screenCapture: value.desktop.screenCapture === true,\n provider: sanitizeOptionalString(value.desktop.provider, 120),\n version: sanitizeOptionalString(value.desktop.version, 120),\n };\n }\n return result;\n}\n\nfunction looksLikeLargeBase64(value: string): boolean {\n return value.length > 4_096 && /[A-Za-z0-9+/]{4_096,}={0,2}/.test(value);\n}\n\nfunction randomHex(byteLength: number): string {\n const bytes = new Uint8Array(byteLength);\n globalThis.crypto.getRandomValues(bytes);\n return bytesToHex(bytes);\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-json-safety.d.ts","sourceRoot":"","sources":["../../src/integrations/remote-json-safety.ts"],"names":[],"mappings":"AAkBA,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC3C,MAAM,CAgBR;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAuEzE"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const DATA_URL_PATTERN = /data:[a-z][^;,]{0,100}[;,]/i;
|
|
2
|
+
const BASE64_PREFIX_PATTERN = /(?:^|[,;])base64,/i;
|
|
3
|
+
const MAX_TRAVERSAL_DEPTH = 20;
|
|
4
|
+
const MAX_TRAVERSAL_NODES = 25_000;
|
|
5
|
+
const BINARY_FIELD_NAMES = new Set([
|
|
6
|
+
"base64",
|
|
7
|
+
"dataurl",
|
|
8
|
+
"image",
|
|
9
|
+
"imagebase64",
|
|
10
|
+
"imagedata",
|
|
11
|
+
"imagebytes",
|
|
12
|
+
"screenshot",
|
|
13
|
+
"screenshotbase64",
|
|
14
|
+
"screenshotdata",
|
|
15
|
+
"bytes",
|
|
16
|
+
"buffer",
|
|
17
|
+
]);
|
|
18
|
+
export function serializeBoundedRemoteJson(value, options) {
|
|
19
|
+
assertNoBinaryPayload(value, options.label);
|
|
20
|
+
let json;
|
|
21
|
+
try {
|
|
22
|
+
json = JSON.stringify(value);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
throw new Error(`${options.label} must contain only serializable JSON`);
|
|
26
|
+
}
|
|
27
|
+
if (json === undefined) {
|
|
28
|
+
throw new Error(`${options.label} must contain a JSON value`);
|
|
29
|
+
}
|
|
30
|
+
const bytes = new TextEncoder().encode(json).byteLength;
|
|
31
|
+
if (bytes > options.maxBytes) {
|
|
32
|
+
throw new Error(`${options.label} exceeds ${options.maxBytes} JSON bytes`);
|
|
33
|
+
}
|
|
34
|
+
return json;
|
|
35
|
+
}
|
|
36
|
+
export function assertNoBinaryPayload(value, label) {
|
|
37
|
+
let visited = 0;
|
|
38
|
+
const seen = new Set();
|
|
39
|
+
const visit = (entry, depth, key) => {
|
|
40
|
+
visited++;
|
|
41
|
+
if (visited > MAX_TRAVERSAL_NODES || depth > MAX_TRAVERSAL_DEPTH) {
|
|
42
|
+
throw new Error(`${label} is too deeply nested or complex`);
|
|
43
|
+
}
|
|
44
|
+
if (typeof entry === "string") {
|
|
45
|
+
const trimmed = entry.trim();
|
|
46
|
+
if (DATA_URL_PATTERN.test(trimmed) ||
|
|
47
|
+
BASE64_PREFIX_PATTERN.test(trimmed) ||
|
|
48
|
+
looksLikeBase64(trimmed) ||
|
|
49
|
+
(isBinaryFieldName(key) && trimmed.length > 0)) {
|
|
50
|
+
throw new Error(`${label} cannot contain screenshots, images, base64, or data URLs`);
|
|
51
|
+
}
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (entry == null ||
|
|
55
|
+
typeof entry === "number" ||
|
|
56
|
+
typeof entry === "boolean") {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (typeof entry === "bigint" ||
|
|
60
|
+
typeof entry === "function" ||
|
|
61
|
+
typeof entry === "symbol" ||
|
|
62
|
+
typeof entry === "undefined") {
|
|
63
|
+
throw new Error(`${label} must contain only serializable JSON`);
|
|
64
|
+
}
|
|
65
|
+
if (ArrayBuffer.isView(entry) || entry instanceof ArrayBuffer) {
|
|
66
|
+
throw new Error(`${label} cannot contain binary buffers`);
|
|
67
|
+
}
|
|
68
|
+
if (typeof Blob !== "undefined" && entry instanceof Blob) {
|
|
69
|
+
throw new Error(`${label} cannot contain binary blobs`);
|
|
70
|
+
}
|
|
71
|
+
if (typeof entry !== "object")
|
|
72
|
+
return;
|
|
73
|
+
if (seen.has(entry)) {
|
|
74
|
+
throw new Error(`${label} must not contain circular values`);
|
|
75
|
+
}
|
|
76
|
+
seen.add(entry);
|
|
77
|
+
if (Array.isArray(entry)) {
|
|
78
|
+
if (isBinaryFieldName(key) && entry.length > 0) {
|
|
79
|
+
throw new Error(`${label} cannot contain binary arrays`);
|
|
80
|
+
}
|
|
81
|
+
for (const item of entry)
|
|
82
|
+
visit(item, depth + 1, key);
|
|
83
|
+
seen.delete(entry);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const record = entry;
|
|
87
|
+
if (record.type === "Buffer" && Array.isArray(record.data)) {
|
|
88
|
+
throw new Error(`${label} cannot contain serialized buffers`);
|
|
89
|
+
}
|
|
90
|
+
for (const [childKey, child] of Object.entries(record)) {
|
|
91
|
+
if (isBinaryFieldName(childKey) && child != null) {
|
|
92
|
+
throw new Error(`${label} cannot contain screenshots, images, base64, or data URLs`);
|
|
93
|
+
}
|
|
94
|
+
visit(child, depth + 1, childKey);
|
|
95
|
+
}
|
|
96
|
+
seen.delete(entry);
|
|
97
|
+
};
|
|
98
|
+
visit(value, 0);
|
|
99
|
+
}
|
|
100
|
+
function isBinaryFieldName(key) {
|
|
101
|
+
if (!key)
|
|
102
|
+
return false;
|
|
103
|
+
const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
104
|
+
return BINARY_FIELD_NAMES.has(normalized);
|
|
105
|
+
}
|
|
106
|
+
function looksLikeBase64(value) {
|
|
107
|
+
if (value.length < 512)
|
|
108
|
+
return false;
|
|
109
|
+
const compact = value.replace(/[\r\n]/g, "");
|
|
110
|
+
return (compact.length >= 512 &&
|
|
111
|
+
compact.length % 4 === 0 &&
|
|
112
|
+
/^[A-Za-z0-9+/]+={0,2}$/.test(compact));
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=remote-json-safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-json-safety.js","sourceRoot":"","sources":["../../src/integrations/remote-json-safety.ts"],"names":[],"mappings":"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","sourcesContent":["const DATA_URL_PATTERN = /data:[a-z][^;,]{0,100}[;,]/i;\nconst BASE64_PREFIX_PATTERN = /(?:^|[,;])base64,/i;\nconst MAX_TRAVERSAL_DEPTH = 20;\nconst MAX_TRAVERSAL_NODES = 25_000;\nconst BINARY_FIELD_NAMES = new Set([\n \"base64\",\n \"dataurl\",\n \"image\",\n \"imagebase64\",\n \"imagedata\",\n \"imagebytes\",\n \"screenshot\",\n \"screenshotbase64\",\n \"screenshotdata\",\n \"bytes\",\n \"buffer\",\n]);\n\nexport function serializeBoundedRemoteJson(\n value: unknown,\n options: { label: string; maxBytes: number },\n): string {\n assertNoBinaryPayload(value, options.label);\n let json: string | undefined;\n try {\n json = JSON.stringify(value);\n } catch {\n throw new Error(`${options.label} must contain only serializable JSON`);\n }\n if (json === undefined) {\n throw new Error(`${options.label} must contain a JSON value`);\n }\n const bytes = new TextEncoder().encode(json).byteLength;\n if (bytes > options.maxBytes) {\n throw new Error(`${options.label} exceeds ${options.maxBytes} JSON bytes`);\n }\n return json;\n}\n\nexport function assertNoBinaryPayload(value: unknown, label: string): void {\n let visited = 0;\n const seen = new Set<object>();\n const visit = (entry: unknown, depth: number, key?: string): void => {\n visited++;\n if (visited > MAX_TRAVERSAL_NODES || depth > MAX_TRAVERSAL_DEPTH) {\n throw new Error(`${label} is too deeply nested or complex`);\n }\n if (typeof entry === \"string\") {\n const trimmed = entry.trim();\n if (\n DATA_URL_PATTERN.test(trimmed) ||\n BASE64_PREFIX_PATTERN.test(trimmed) ||\n looksLikeBase64(trimmed) ||\n (isBinaryFieldName(key) && trimmed.length > 0)\n ) {\n throw new Error(\n `${label} cannot contain screenshots, images, base64, or data URLs`,\n );\n }\n return;\n }\n if (\n entry == null ||\n typeof entry === \"number\" ||\n typeof entry === \"boolean\"\n ) {\n return;\n }\n if (\n typeof entry === \"bigint\" ||\n typeof entry === \"function\" ||\n typeof entry === \"symbol\" ||\n typeof entry === \"undefined\"\n ) {\n throw new Error(`${label} must contain only serializable JSON`);\n }\n if (ArrayBuffer.isView(entry) || entry instanceof ArrayBuffer) {\n throw new Error(`${label} cannot contain binary buffers`);\n }\n if (typeof Blob !== \"undefined\" && entry instanceof Blob) {\n throw new Error(`${label} cannot contain binary blobs`);\n }\n if (typeof entry !== \"object\") return;\n if (seen.has(entry)) {\n throw new Error(`${label} must not contain circular values`);\n }\n seen.add(entry);\n if (Array.isArray(entry)) {\n if (isBinaryFieldName(key) && entry.length > 0) {\n throw new Error(`${label} cannot contain binary arrays`);\n }\n for (const item of entry) visit(item, depth + 1, key);\n seen.delete(entry);\n return;\n }\n const record = entry as Record<string, unknown>;\n if (record.type === \"Buffer\" && Array.isArray(record.data)) {\n throw new Error(`${label} cannot contain serialized buffers`);\n }\n for (const [childKey, child] of Object.entries(record)) {\n if (isBinaryFieldName(childKey) && child != null) {\n throw new Error(\n `${label} cannot contain screenshots, images, base64, or data URLs`,\n );\n }\n visit(child, depth + 1, childKey);\n }\n seen.delete(entry);\n };\n visit(value, 0);\n}\n\nfunction isBinaryFieldName(key: string | undefined): boolean {\n if (!key) return false;\n const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n return BINARY_FIELD_NAMES.has(normalized);\n}\n\nfunction looksLikeBase64(value: string): boolean {\n if (value.length < 512) return false;\n const compact = value.replace(/[\\r\\n]/g, \"\");\n return (\n compact.length >= 512 &&\n compact.length % 4 === 0 &&\n /^[A-Za-z0-9+/]+={0,2}$/.test(compact)\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RemoteRunEvent } from "./remote-types.js";
|
|
1
|
+
import type { RemoteLiveViewEvent, RemoteRunEvent } from "./remote-types.js";
|
|
2
2
|
export declare function insertRemoteRunEvents(input: {
|
|
3
3
|
deviceId: string;
|
|
4
4
|
remoteRunId: string;
|
|
@@ -9,6 +9,16 @@ export declare function insertRemoteRunEvents(input: {
|
|
|
9
9
|
}): Promise<{
|
|
10
10
|
inserted: number;
|
|
11
11
|
}>;
|
|
12
|
+
export declare function insertRemoteLiveViewEvents(input: {
|
|
13
|
+
deviceId: string;
|
|
14
|
+
remoteRunId: string;
|
|
15
|
+
events: Array<{
|
|
16
|
+
seq: number;
|
|
17
|
+
event: RemoteLiveViewEvent;
|
|
18
|
+
}>;
|
|
19
|
+
}): Promise<{
|
|
20
|
+
inserted: number;
|
|
21
|
+
}>;
|
|
12
22
|
export declare function listRemoteRunEvents(input: {
|
|
13
23
|
deviceId: string;
|
|
14
24
|
remoteRunId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-run-events-store.d.ts","sourceRoot":"","sources":["../../src/integrations/remote-run-events-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remote-run-events-store.d.ts","sourceRoot":"","sources":["../../src/integrations/remote-run-events-store.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAuE7E,wBAAsB,qBAAqB,CAAC,KAAK,EAAE;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAChD,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAsChC;AAED,wBAAsB,0BAA0B,CAAC,KAAK,EAAE;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,mBAAmB,CAAA;KAAE,CAAC,CAAC;CAC5D,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAQhC;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAiB5B"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { getDbExec, isPostgres, intType, retryOnDdlRace, } from "../db/client.js";
|
|
2
2
|
import { ensureTableExists, ensureIndexExists } from "../db/ddl-guard.js";
|
|
3
|
+
import { serializeBoundedRemoteJson } from "./remote-json-safety.js";
|
|
4
|
+
const MAX_EVENT_JSON_BYTES = 256_000;
|
|
5
|
+
const MAX_EVENT_BATCH_JSON_BYTES = 1_000_000;
|
|
3
6
|
let _initPromise;
|
|
4
7
|
// Build the CREATE SQL lazily (not at module scope) so intType() runs at
|
|
5
8
|
// RUNTIME, not import time — a module-scope call breaks any consumer whose
|
|
@@ -50,26 +53,49 @@ function rowToRunEvent(row) {
|
|
|
50
53
|
}
|
|
51
54
|
export async function insertRemoteRunEvents(input) {
|
|
52
55
|
await ensureTable();
|
|
56
|
+
if (input.events.length === 0)
|
|
57
|
+
return { inserted: 0 };
|
|
58
|
+
if (input.events.length > 1_000) {
|
|
59
|
+
throw new Error("A remote run event batch cannot exceed 1,000 events");
|
|
60
|
+
}
|
|
53
61
|
const client = getDbExec();
|
|
54
62
|
const now = Date.now();
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
input.remoteRunId,
|
|
65
|
-
event.seq,
|
|
66
|
-
JSON.stringify(event.event ?? null),
|
|
67
|
-
now,
|
|
68
|
-
],
|
|
63
|
+
const values = input.events.map(() => "(?, ?, ?, ?, ?)").join(", ");
|
|
64
|
+
let batchBytes = 0;
|
|
65
|
+
const args = input.events.flatMap((event) => {
|
|
66
|
+
const value = isLiveViewEvent(event.event)
|
|
67
|
+
? normalizeLiveViewEvent(event.event)
|
|
68
|
+
: (event.event ?? null);
|
|
69
|
+
const eventJson = serializeBoundedRemoteJson(value, {
|
|
70
|
+
label: "Remote run event",
|
|
71
|
+
maxBytes: MAX_EVENT_JSON_BYTES,
|
|
69
72
|
});
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
batchBytes += new TextEncoder().encode(eventJson).byteLength;
|
|
74
|
+
if (batchBytes > MAX_EVENT_BATCH_JSON_BYTES) {
|
|
75
|
+
throw new Error(`Remote run event batch exceeds ${MAX_EVENT_BATCH_JSON_BYTES} JSON bytes`);
|
|
76
|
+
}
|
|
77
|
+
return [input.deviceId, input.remoteRunId, event.seq, eventJson, now];
|
|
78
|
+
});
|
|
79
|
+
const result = await client.execute({
|
|
80
|
+
sql: `INSERT INTO integration_remote_run_events
|
|
81
|
+
(device_id, remote_run_id, seq, event_json, created_at)
|
|
82
|
+
VALUES ${values}
|
|
83
|
+
ON CONFLICT(device_id, remote_run_id, seq) DO NOTHING`,
|
|
84
|
+
args,
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
inserted: result.rowsAffected ??
|
|
88
|
+
Number(result.rowCount ?? 0),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export async function insertRemoteLiveViewEvents(input) {
|
|
92
|
+
return insertRemoteRunEvents({
|
|
93
|
+
...input,
|
|
94
|
+
events: input.events.map(({ seq, event }) => ({
|
|
95
|
+
seq,
|
|
96
|
+
event: normalizeLiveViewEvent(event),
|
|
97
|
+
})),
|
|
98
|
+
});
|
|
73
99
|
}
|
|
74
100
|
export async function listRemoteRunEvents(input) {
|
|
75
101
|
await ensureTable();
|
|
@@ -99,4 +125,46 @@ function parseJson(value, fallback) {
|
|
|
99
125
|
return fallback;
|
|
100
126
|
}
|
|
101
127
|
}
|
|
128
|
+
function normalizeLiveViewEvent(event) {
|
|
129
|
+
if (!event || event.type !== "computer.live-view") {
|
|
130
|
+
throw new Error("Invalid computer live-view event");
|
|
131
|
+
}
|
|
132
|
+
const frameHandle = sanitizeString(event.frameHandle, 240);
|
|
133
|
+
if (/^data:/i.test(frameHandle) || looksLikeLargeBase64(frameHandle)) {
|
|
134
|
+
throw new Error("Live-view frames must use ephemeral handles, not image data");
|
|
135
|
+
}
|
|
136
|
+
if (!Number.isSafeInteger(event.capturedAt) || event.capturedAt < 0) {
|
|
137
|
+
throw new Error("Live-view capturedAt must be an epoch timestamp");
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
type: "computer.live-view",
|
|
141
|
+
frameHandle,
|
|
142
|
+
capturedAt: event.capturedAt,
|
|
143
|
+
width: boundedDimension(event.width),
|
|
144
|
+
height: boundedDimension(event.height),
|
|
145
|
+
targetLabel: event.targetLabel == null ? null : sanitizeString(event.targetLabel, 240),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function isLiveViewEvent(value) {
|
|
149
|
+
return (Boolean(value) &&
|
|
150
|
+
typeof value === "object" &&
|
|
151
|
+
value.type === "computer.live-view");
|
|
152
|
+
}
|
|
153
|
+
function boundedDimension(value) {
|
|
154
|
+
if (value == null)
|
|
155
|
+
return null;
|
|
156
|
+
if (!Number.isInteger(value) || value < 1 || value > 100_000) {
|
|
157
|
+
throw new Error("Live-view dimensions must be positive integers");
|
|
158
|
+
}
|
|
159
|
+
return value;
|
|
160
|
+
}
|
|
161
|
+
function sanitizeString(value, max) {
|
|
162
|
+
if (typeof value !== "string" || !value.trim() || value.length > max) {
|
|
163
|
+
throw new Error(`Expected a non-empty string of at most ${max} chars`);
|
|
164
|
+
}
|
|
165
|
+
return value.trim();
|
|
166
|
+
}
|
|
167
|
+
function looksLikeLargeBase64(value) {
|
|
168
|
+
return value.length > 512 && /^[A-Za-z0-9+/]+={0,2}$/.test(value);
|
|
169
|
+
}
|
|
102
170
|
//# sourceMappingURL=remote-run-events-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-run-events-store.js","sourceRoot":"","sources":["../../src/integrations/remote-run-events-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 { RemoteRunEvent } 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 buildCreateSql(): string {\n return `\n CREATE TABLE IF NOT EXISTS integration_remote_run_events (\n device_id TEXT NOT NULL,\n remote_run_id TEXT NOT NULL,\n seq ${intType()} NOT NULL,\n event_json TEXT NOT NULL,\n created_at ${intType()} NOT NULL\n )\n`;\n}\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createSql = buildCreateSql();\n if (isPostgres()) {\n // PG guard: probe via information_schema, only issue DDL if missing, bounded lock_timeout\n await ensureTableExists(\"integration_remote_run_events\", createSql);\n await ensureIndexExists(\n \"idx_remote_run_events_unique\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_run_events_unique ON integration_remote_run_events(device_id, remote_run_id, seq)`,\n );\n await ensureIndexExists(\n \"idx_remote_run_events_run\",\n `CREATE INDEX IF NOT EXISTS idx_remote_run_events_run ON integration_remote_run_events(device_id, remote_run_id, seq)`,\n );\n return;\n }\n // SQLite (local dev): keep existing behavior\n await retryOnDdlRace(() => client.execute(createSql));\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_run_events_unique ON integration_remote_run_events(device_id, remote_run_id, seq)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_run_events_run ON integration_remote_run_events(device_id, remote_run_id, seq)`,\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 rowToRunEvent(row: Record<string, unknown>): RemoteRunEvent {\n return {\n deviceId: row.device_id as string,\n remoteRunId: row.remote_run_id as string,\n seq: Number(row.seq ?? 0),\n event: parseJson(row.event_json, null),\n createdAt: Number(row.created_at ?? 0),\n };\n}\n\nexport async function insertRemoteRunEvents(input: {\n deviceId: string;\n remoteRunId: string;\n events: Array<{ seq: number; event: unknown }>;\n}): Promise<{ inserted: number }> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n let inserted = 0;\n\n for (const event of input.events) {\n const result = await client.execute({\n sql: `INSERT INTO integration_remote_run_events\n (device_id, remote_run_id, seq, event_json, created_at)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(device_id, remote_run_id, seq) DO NOTHING`,\n args: [\n input.deviceId,\n input.remoteRunId,\n event.seq,\n JSON.stringify(event.event ?? null),\n now,\n ],\n });\n inserted += result.rowsAffected ?? (result as any).rowCount ?? 0;\n }\n\n return { inserted };\n}\n\nexport async function listRemoteRunEvents(input: {\n deviceId: string;\n remoteRunId: string;\n afterSeq?: number;\n limit?: number;\n}): Promise<RemoteRunEvent[]> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_run_events\n WHERE device_id = ?\n AND remote_run_id = ?\n AND seq > ?\n ORDER BY seq ASC\n LIMIT ?`,\n args: [\n input.deviceId,\n input.remoteRunId,\n input.afterSeq ?? -1,\n input.limit ?? 500,\n ],\n });\n return rows.map((row) => rowToRunEvent(row as Record<string, unknown>));\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-run-events-store.js","sourceRoot":"","sources":["../../src/integrations/remote-run-events-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 { serializeBoundedRemoteJson } from \"./remote-json-safety.js\";\nimport type { RemoteLiveViewEvent, RemoteRunEvent } from \"./remote-types.js\";\n\nconst MAX_EVENT_JSON_BYTES = 256_000;\nconst MAX_EVENT_BATCH_JSON_BYTES = 1_000_000;\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 buildCreateSql(): string {\n return `\n CREATE TABLE IF NOT EXISTS integration_remote_run_events (\n device_id TEXT NOT NULL,\n remote_run_id TEXT NOT NULL,\n seq ${intType()} NOT NULL,\n event_json TEXT NOT NULL,\n created_at ${intType()} NOT NULL\n )\n`;\n}\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const createSql = buildCreateSql();\n if (isPostgres()) {\n // PG guard: probe via information_schema, only issue DDL if missing, bounded lock_timeout\n await ensureTableExists(\"integration_remote_run_events\", createSql);\n await ensureIndexExists(\n \"idx_remote_run_events_unique\",\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_run_events_unique ON integration_remote_run_events(device_id, remote_run_id, seq)`,\n );\n await ensureIndexExists(\n \"idx_remote_run_events_run\",\n `CREATE INDEX IF NOT EXISTS idx_remote_run_events_run ON integration_remote_run_events(device_id, remote_run_id, seq)`,\n );\n return;\n }\n // SQLite (local dev): keep existing behavior\n await retryOnDdlRace(() => client.execute(createSql));\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_run_events_unique ON integration_remote_run_events(device_id, remote_run_id, seq)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_run_events_run ON integration_remote_run_events(device_id, remote_run_id, seq)`,\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 rowToRunEvent(row: Record<string, unknown>): RemoteRunEvent {\n return {\n deviceId: row.device_id as string,\n remoteRunId: row.remote_run_id as string,\n seq: Number(row.seq ?? 0),\n event: parseJson(row.event_json, null),\n createdAt: Number(row.created_at ?? 0),\n };\n}\n\nexport async function insertRemoteRunEvents(input: {\n deviceId: string;\n remoteRunId: string;\n events: Array<{ seq: number; event: unknown }>;\n}): Promise<{ inserted: number }> {\n await ensureTable();\n if (input.events.length === 0) return { inserted: 0 };\n if (input.events.length > 1_000) {\n throw new Error(\"A remote run event batch cannot exceed 1,000 events\");\n }\n const client = getDbExec();\n const now = Date.now();\n const values = input.events.map(() => \"(?, ?, ?, ?, ?)\").join(\", \");\n let batchBytes = 0;\n const args = input.events.flatMap((event) => {\n const value = isLiveViewEvent(event.event)\n ? normalizeLiveViewEvent(event.event)\n : (event.event ?? null);\n const eventJson = serializeBoundedRemoteJson(value, {\n label: \"Remote run event\",\n maxBytes: MAX_EVENT_JSON_BYTES,\n });\n batchBytes += new TextEncoder().encode(eventJson).byteLength;\n if (batchBytes > MAX_EVENT_BATCH_JSON_BYTES) {\n throw new Error(\n `Remote run event batch exceeds ${MAX_EVENT_BATCH_JSON_BYTES} JSON bytes`,\n );\n }\n return [input.deviceId, input.remoteRunId, event.seq, eventJson, now];\n });\n const result = await client.execute({\n sql: `INSERT INTO integration_remote_run_events\n (device_id, remote_run_id, seq, event_json, created_at)\n VALUES ${values}\n ON CONFLICT(device_id, remote_run_id, seq) DO NOTHING`,\n args,\n });\n return {\n inserted:\n result.rowsAffected ??\n Number((result as { rowCount?: unknown }).rowCount ?? 0),\n };\n}\n\nexport async function insertRemoteLiveViewEvents(input: {\n deviceId: string;\n remoteRunId: string;\n events: Array<{ seq: number; event: RemoteLiveViewEvent }>;\n}): Promise<{ inserted: number }> {\n return insertRemoteRunEvents({\n ...input,\n events: input.events.map(({ seq, event }) => ({\n seq,\n event: normalizeLiveViewEvent(event),\n })),\n });\n}\n\nexport async function listRemoteRunEvents(input: {\n deviceId: string;\n remoteRunId: string;\n afterSeq?: number;\n limit?: number;\n}): Promise<RemoteRunEvent[]> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_run_events\n WHERE device_id = ?\n AND remote_run_id = ?\n AND seq > ?\n ORDER BY seq ASC\n LIMIT ?`,\n args: [\n input.deviceId,\n input.remoteRunId,\n input.afterSeq ?? -1,\n input.limit ?? 500,\n ],\n });\n return rows.map((row) => rowToRunEvent(row as Record<string, unknown>));\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\nfunction normalizeLiveViewEvent(\n event: RemoteLiveViewEvent,\n): RemoteLiveViewEvent {\n if (!event || event.type !== \"computer.live-view\") {\n throw new Error(\"Invalid computer live-view event\");\n }\n const frameHandle = sanitizeString(event.frameHandle, 240);\n if (/^data:/i.test(frameHandle) || looksLikeLargeBase64(frameHandle)) {\n throw new Error(\n \"Live-view frames must use ephemeral handles, not image data\",\n );\n }\n if (!Number.isSafeInteger(event.capturedAt) || event.capturedAt < 0) {\n throw new Error(\"Live-view capturedAt must be an epoch timestamp\");\n }\n return {\n type: \"computer.live-view\",\n frameHandle,\n capturedAt: event.capturedAt,\n width: boundedDimension(event.width),\n height: boundedDimension(event.height),\n targetLabel:\n event.targetLabel == null ? null : sanitizeString(event.targetLabel, 240),\n };\n}\n\nfunction isLiveViewEvent(value: unknown): value is RemoteLiveViewEvent {\n return (\n Boolean(value) &&\n typeof value === \"object\" &&\n (value as { type?: unknown }).type === \"computer.live-view\"\n );\n}\n\nfunction boundedDimension(value: number | null | undefined): number | null {\n if (value == null) return null;\n if (!Number.isInteger(value) || value < 1 || value > 100_000) {\n throw new Error(\"Live-view dimensions must be positive integers\");\n }\n return value;\n}\n\nfunction sanitizeString(value: unknown, max: number): string {\n if (typeof value !== \"string\" || !value.trim() || value.length > max) {\n throw new Error(`Expected a non-empty string of at most ${max} chars`);\n }\n return value.trim();\n}\n\nfunction looksLikeLargeBase64(value: string): boolean {\n return value.length > 512 && /^[A-Za-z0-9+/]+={0,2}$/.test(value);\n}\n"]}
|
|
@@ -1,4 +1,46 @@
|
|
|
1
|
-
export type RemoteCommandKind = "create-run" | "list-runs" | "get-run" | "append-followup" | "approve" | "deny" | "stop" | "status";
|
|
1
|
+
export type RemoteCommandKind = "create-run" | "list-runs" | "get-run" | "append-followup" | "approve" | "deny" | "stop" | "status" | "computer-operation";
|
|
2
|
+
export type ComputerOperationClass = "browser.observe" | "browser.control" | "desktop.observe" | "desktop.control";
|
|
3
|
+
export type ComputerApprovalScope = "once" | "run" | "task";
|
|
4
|
+
export interface ComputerCommandAction {
|
|
5
|
+
type: string;
|
|
6
|
+
target?: Record<string, unknown> | null;
|
|
7
|
+
input?: unknown;
|
|
8
|
+
}
|
|
9
|
+
export interface ComputerCommandEnvelope {
|
|
10
|
+
version: 1;
|
|
11
|
+
taskId: string;
|
|
12
|
+
runId: string;
|
|
13
|
+
sequence: number;
|
|
14
|
+
idempotencyKey: string;
|
|
15
|
+
operationClass: ComputerOperationClass;
|
|
16
|
+
action: ComputerCommandAction;
|
|
17
|
+
approval: {
|
|
18
|
+
id?: string | null;
|
|
19
|
+
scope: ComputerApprovalScope;
|
|
20
|
+
actionHash: string;
|
|
21
|
+
};
|
|
22
|
+
issuedAt: number;
|
|
23
|
+
leaseExpiresAt: number;
|
|
24
|
+
}
|
|
25
|
+
export interface RemoteComputerCapabilities {
|
|
26
|
+
browser?: {
|
|
27
|
+
observe: boolean;
|
|
28
|
+
control: boolean;
|
|
29
|
+
provider?: string | null;
|
|
30
|
+
version?: string | null;
|
|
31
|
+
};
|
|
32
|
+
desktop?: {
|
|
33
|
+
observe: boolean;
|
|
34
|
+
control: boolean;
|
|
35
|
+
accessibility?: boolean;
|
|
36
|
+
screenCapture?: boolean;
|
|
37
|
+
provider?: string | null;
|
|
38
|
+
version?: string | null;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export interface RemoteDeviceMetadata extends Record<string, unknown> {
|
|
42
|
+
computerCapabilities?: RemoteComputerCapabilities;
|
|
43
|
+
}
|
|
2
44
|
export type RemoteCommandStatus = "pending" | "claimed" | "running" | "completed" | "failed";
|
|
3
45
|
export type RemoteDeviceStatus = "active" | "inactive";
|
|
4
46
|
export interface RemoteDevice {
|
|
@@ -9,7 +51,7 @@ export interface RemoteDevice {
|
|
|
9
51
|
platform: string | null;
|
|
10
52
|
appVersion: string | null;
|
|
11
53
|
hostName: string | null;
|
|
12
|
-
metadata:
|
|
54
|
+
metadata: RemoteDeviceMetadata | null;
|
|
13
55
|
deviceTokenHash: string;
|
|
14
56
|
lastSeenAt: number | null;
|
|
15
57
|
status: RemoteDeviceStatus;
|
|
@@ -25,7 +67,7 @@ export interface PublicRemoteDevice {
|
|
|
25
67
|
platform: string | null;
|
|
26
68
|
appVersion: string | null;
|
|
27
69
|
hostName: string | null;
|
|
28
|
-
metadata:
|
|
70
|
+
metadata: RemoteDeviceMetadata | null;
|
|
29
71
|
lastSeenAt: number | null;
|
|
30
72
|
status: RemoteDeviceStatus;
|
|
31
73
|
revokedAt: number | null;
|
|
@@ -43,6 +85,7 @@ export interface RemoteCommand {
|
|
|
43
85
|
result: unknown;
|
|
44
86
|
platform: string | null;
|
|
45
87
|
externalThreadId: string | null;
|
|
88
|
+
computerOperation?: ComputerCommandEnvelope | null;
|
|
46
89
|
attempts: number;
|
|
47
90
|
nextCheckAt: number;
|
|
48
91
|
claimedAt: number | null;
|
|
@@ -58,6 +101,14 @@ export interface RemoteRunEvent {
|
|
|
58
101
|
event: unknown;
|
|
59
102
|
createdAt: number;
|
|
60
103
|
}
|
|
104
|
+
export interface RemoteLiveViewEvent {
|
|
105
|
+
type: "computer.live-view";
|
|
106
|
+
frameHandle: string;
|
|
107
|
+
capturedAt: number;
|
|
108
|
+
width?: number | null;
|
|
109
|
+
height?: number | null;
|
|
110
|
+
targetLabel?: string | null;
|
|
111
|
+
}
|
|
61
112
|
export type RemotePushRegistrationStatus = "active" | "inactive";
|
|
62
113
|
export interface RemotePushRegistration {
|
|
63
114
|
id: string;
|