@songsid/agend 2.3.5-alpha.4 → 2.3.5-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.md +52 -0
- package/dist/accounts-view.d.ts +97 -0
- package/dist/accounts-view.js +116 -0
- package/dist/accounts-view.js.map +1 -0
- package/dist/agent-cli-instructions.md +1 -1
- package/dist/agent-credentials.d.ts +24 -0
- package/dist/agent-credentials.js +66 -0
- package/dist/agent-credentials.js.map +1 -0
- package/dist/agent-endpoint.d.ts +3 -1
- package/dist/agent-endpoint.js +13 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.js +1 -1
- package/dist/agent-file-read.js.map +1 -1
- package/dist/agent-runtime-change.d.ts +3 -1
- package/dist/agent-runtime-change.js +15 -3
- package/dist/agent-runtime-change.js.map +1 -1
- package/dist/agent-workspace.d.ts +93 -0
- package/dist/agent-workspace.js +353 -0
- package/dist/agent-workspace.js.map +1 -0
- package/dist/auth-api.d.ts +27 -0
- package/dist/auth-api.js +164 -3
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/session-authorizations.d.ts +28 -4
- package/dist/authority/session-authorizations.js +63 -17
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/backend/antigravity.js +3 -1
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/codex-footer-hints.d.ts +3 -0
- package/dist/backend/codex-footer-hints.js +14 -0
- package/dist/backend/codex-footer-hints.js.map +1 -1
- package/dist/backend/codex-metadata.d.ts +14 -0
- package/dist/backend/codex-metadata.js +45 -0
- package/dist/backend/codex-metadata.js.map +1 -1
- package/dist/backend/codex-quota-history.d.ts +7 -0
- package/dist/backend/codex-quota-history.js +57 -0
- package/dist/backend/codex-quota-history.js.map +1 -0
- package/dist/backend/codex-session-lookup.d.ts +6 -0
- package/dist/backend/codex-session-lookup.js +1 -1
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex-speed.d.ts +14 -0
- package/dist/backend/codex-speed.js +35 -0
- package/dist/backend/codex-speed.js.map +1 -0
- package/dist/backend/codex.d.ts +7 -0
- package/dist/backend/codex.js +78 -15
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/grok-weekly-reset.d.ts +24 -0
- package/dist/backend/grok-weekly-reset.js +95 -0
- package/dist/backend/grok-weekly-reset.js.map +1 -0
- package/dist/backend/grok.d.ts +30 -1
- package/dist/backend/grok.js +301 -54
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro.d.ts +3 -0
- package/dist/backend/kiro.js +50 -2
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/muse.js +5 -3
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/native-pane.d.ts +3 -1
- package/dist/backend/native-pane.js +2 -2
- package/dist/backend/native-pane.js.map +1 -1
- package/dist/backend/types.d.ts +13 -1
- package/dist/backend/types.js +3 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/build-provenance-cli.d.ts +3 -0
- package/dist/build-provenance-cli.js +11 -0
- package/dist/build-provenance-cli.js.map +1 -0
- package/dist/build-provenance.d.ts +20 -0
- package/dist/build-provenance.js +67 -0
- package/dist/build-provenance.js.map +1 -0
- package/dist/build-provenance.json +1 -0
- package/dist/cache-ledger.d.ts +95 -0
- package/dist/cache-ledger.js +276 -4
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-service.d.ts +5 -0
- package/dist/cache-service.js +16 -4
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.js +11 -3
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +51 -0
- package/dist/channel/adapters/telegram.js +235 -17
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +3 -3
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +2 -0
- package/dist/claude-auth-status.d.ts +48 -0
- package/dist/claude-auth-status.js +149 -0
- package/dist/claude-auth-status.js.map +1 -0
- package/dist/cli.js +138 -37
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.js +21 -1
- package/dist/config-validator.js.map +1 -1
- package/dist/cross-instance-notice.d.ts +10 -0
- package/dist/cross-instance-notice.js +67 -5
- package/dist/cross-instance-notice.js.map +1 -1
- package/dist/daemon.d.ts +70 -1
- package/dist/daemon.js +547 -25
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard-permissions.d.ts +8 -0
- package/dist/dashboard-permissions.js +16 -0
- package/dist/dashboard-permissions.js.map +1 -1
- package/dist/delivery-consumed-watch.d.ts +23 -1
- package/dist/delivery-consumed-watch.js +30 -3
- package/dist/delivery-consumed-watch.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +1 -1
- package/dist/delivery-reconciliation.js +1 -1
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/doctor.js +20 -9
- package/dist/doctor.js.map +1 -1
- package/dist/export-import.d.ts +7 -0
- package/dist/export-import.js +44 -10
- package/dist/export-import.js.map +1 -1
- package/dist/fleet-context.d.ts +2 -0
- package/dist/fleet-manager.d.ts +359 -7
- package/dist/fleet-manager.js +1365 -90
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-windows-runtime.d.ts +2 -1
- package/dist/fleet-windows-runtime.js +25 -7
- package/dist/fleet-windows-runtime.js.map +1 -1
- package/dist/general-knowledge/skills/concepts/SKILL.md +425 -0
- package/dist/general-knowledge/skills/credential-profiles/SKILL.md +5 -2
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +1 -0
- package/dist/general-knowledge/skills/fleet-health/SKILL.md +2 -2
- package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +3 -1
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +41 -4
- package/dist/general-knowledge/skills/session-management/SKILL.md +1 -1
- package/dist/general-knowledge/skills/tui-effort/SKILL.md +10 -10
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +31 -15
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/general-role.d.ts +1 -1
- package/dist/general-role.js +1 -0
- package/dist/general-role.js.map +1 -1
- package/dist/hub/admission.d.ts +28 -0
- package/dist/hub/admission.js +62 -0
- package/dist/hub/admission.js.map +1 -0
- package/dist/hub/attachments/limits.d.ts +20 -0
- package/dist/hub/attachments/limits.js +48 -0
- package/dist/hub/attachments/limits.js.map +1 -0
- package/dist/hub/attachments/store.d.ts +116 -0
- package/dist/hub/attachments/store.js +246 -0
- package/dist/hub/attachments/store.js.map +1 -0
- package/dist/hub/audit/index.d.ts +62 -0
- package/dist/hub/audit/index.js +344 -0
- package/dist/hub/audit/index.js.map +1 -0
- package/dist/hub/browser-certificate.d.ts +38 -0
- package/dist/hub/browser-certificate.js +247 -0
- package/dist/hub/browser-certificate.js.map +1 -0
- package/dist/hub/buttons-model.d.ts +9 -0
- package/dist/hub/buttons-model.js +42 -0
- package/dist/hub/buttons-model.js.map +1 -0
- package/dist/hub/buttons.d.ts +54 -0
- package/dist/hub/buttons.js +346 -0
- package/dist/hub/buttons.js.map +1 -0
- package/dist/hub/catalog.d.ts +74 -0
- package/dist/hub/catalog.js +195 -0
- package/dist/hub/catalog.js.map +1 -0
- package/dist/hub/client.d.ts +69 -0
- package/dist/hub/client.js +300 -0
- package/dist/hub/client.js.map +1 -0
- package/dist/hub/compose/member.d.ts +139 -0
- package/dist/hub/compose/member.js +450 -0
- package/dist/hub/compose/member.js.map +1 -0
- package/dist/hub/compose/server.d.ts +77 -0
- package/dist/hub/compose/server.js +349 -0
- package/dist/hub/compose/server.js.map +1 -0
- package/dist/hub/compose/views.d.ts +12 -0
- package/dist/hub/compose/views.js +4 -0
- package/dist/hub/compose/views.js.map +1 -0
- package/dist/hub/db.d.ts +56 -0
- package/dist/hub/db.js +188 -0
- package/dist/hub/db.js.map +1 -0
- package/dist/hub/directory/config.d.ts +39 -0
- package/dist/hub/directory/config.js +108 -0
- package/dist/hub/directory/config.js.map +1 -0
- package/dist/hub/directory/directory.d.ts +18 -0
- package/dist/hub/directory/directory.js +320 -0
- package/dist/hub/directory/directory.js.map +1 -0
- package/dist/hub/directory/index.d.ts +7 -0
- package/dist/hub/directory/index.js +4 -0
- package/dist/hub/directory/index.js.map +1 -0
- package/dist/hub/directory/profiles.d.ts +41 -0
- package/dist/hub/directory/profiles.js +90 -0
- package/dist/hub/directory/profiles.js.map +1 -0
- package/dist/hub/directory/types.d.ts +71 -0
- package/dist/hub/directory/types.js +14 -0
- package/dist/hub/directory/types.js.map +1 -0
- package/dist/hub/execution/cli-provider.d.ts +23 -0
- package/dist/hub/execution/cli-provider.js +341 -0
- package/dist/hub/execution/cli-provider.js.map +1 -0
- package/dist/hub/execution/index.d.ts +13 -0
- package/dist/hub/execution/index.js +8 -0
- package/dist/hub/execution/index.js.map +1 -0
- package/dist/hub/execution/model-broker.d.ts +24 -0
- package/dist/hub/execution/model-broker.js +208 -0
- package/dist/hub/execution/model-broker.js.map +1 -0
- package/dist/hub/execution/provider-setup.d.ts +11 -0
- package/dist/hub/execution/provider-setup.js +21 -0
- package/dist/hub/execution/provider-setup.js.map +1 -0
- package/dist/hub/execution/sandbox-runner.d.ts +1 -0
- package/dist/hub/execution/sandbox-runner.js +221 -0
- package/dist/hub/execution/sandbox-runner.js.map +1 -0
- package/dist/hub/execution/service.d.ts +136 -0
- package/dist/hub/execution/service.js +459 -0
- package/dist/hub/execution/service.js.map +1 -0
- package/dist/hub/execution/store.d.ts +61 -0
- package/dist/hub/execution/store.js +182 -0
- package/dist/hub/execution/store.js.map +1 -0
- package/dist/hub/execution/views.d.ts +20 -0
- package/dist/hub/execution/views.js +48 -0
- package/dist/hub/execution/views.js.map +1 -0
- package/dist/hub/http/compose.d.ts +20 -0
- package/dist/hub/http/compose.js +518 -0
- package/dist/hub/http/compose.js.map +1 -0
- package/dist/hub/http/core.d.ts +49 -0
- package/dist/hub/http/core.js +124 -0
- package/dist/hub/http/core.js.map +1 -0
- package/dist/hub/http/deps.d.ts +61 -0
- package/dist/hub/http/deps.js +2 -0
- package/dist/hub/http/deps.js.map +1 -0
- package/dist/hub/http/schema.d.ts +14 -0
- package/dist/hub/http/schema.js +80 -0
- package/dist/hub/http/schema.js.map +1 -0
- package/dist/hub/identity.d.ts +32 -0
- package/dist/hub/identity.js +80 -0
- package/dist/hub/identity.js.map +1 -0
- package/dist/hub/init/browser-certificate.d.ts +9 -0
- package/dist/hub/init/browser-certificate.js +78 -0
- package/dist/hub/init/browser-certificate.js.map +1 -0
- package/dist/hub/init/browser-tls.d.ts +18 -0
- package/dist/hub/init/browser-tls.js +62 -0
- package/dist/hub/init/browser-tls.js.map +1 -0
- package/dist/hub/init/cli.d.ts +3 -0
- package/dist/hub/init/cli.js +83 -0
- package/dist/hub/init/cli.js.map +1 -0
- package/dist/hub/init/directory-certificate.d.ts +24 -0
- package/dist/hub/init/directory-certificate.js +222 -0
- package/dist/hub/init/directory-certificate.js.map +1 -0
- package/dist/hub/init/existing-fleet.d.ts +6 -0
- package/dist/hub/init/existing-fleet.js +58 -0
- package/dist/hub/init/existing-fleet.js.map +1 -0
- package/dist/hub/init/handoff.d.ts +8 -0
- package/dist/hub/init/handoff.js +36 -0
- package/dist/hub/init/handoff.js.map +1 -0
- package/dist/hub/init/identity.d.ts +5 -0
- package/dist/hub/init/identity.js +24 -0
- package/dist/hub/init/identity.js.map +1 -0
- package/dist/hub/init/initializer.d.ts +24 -0
- package/dist/hub/init/initializer.js +385 -0
- package/dist/hub/init/initializer.js.map +1 -0
- package/dist/hub/init/inventory.d.ts +17 -0
- package/dist/hub/init/inventory.js +33 -0
- package/dist/hub/init/inventory.js.map +1 -0
- package/dist/hub/init/layout.d.ts +32 -0
- package/dist/hub/init/layout.js +53 -0
- package/dist/hub/init/layout.js.map +1 -0
- package/dist/hub/init/network.d.ts +18 -0
- package/dist/hub/init/network.js +104 -0
- package/dist/hub/init/network.js.map +1 -0
- package/dist/hub/init/plan-digest.d.ts +5 -0
- package/dist/hub/init/plan-digest.js +47 -0
- package/dist/hub/init/plan-digest.js.map +1 -0
- package/dist/hub/init/prompt.d.ts +26 -0
- package/dist/hub/init/prompt.js +110 -0
- package/dist/hub/init/prompt.js.map +1 -0
- package/dist/hub/init/secret-file.d.ts +1 -0
- package/dist/hub/init/secret-file.js +59 -0
- package/dist/hub/init/secret-file.js.map +1 -0
- package/dist/hub/init/text.d.ts +127 -0
- package/dist/hub/init/text.js +247 -0
- package/dist/hub/init/text.js.map +1 -0
- package/dist/hub/init/types.d.ts +114 -0
- package/dist/hub/init/types.js +9 -0
- package/dist/hub/init/types.js.map +1 -0
- package/dist/hub/init/wizard.d.ts +34 -0
- package/dist/hub/init/wizard.js +554 -0
- package/dist/hub/init/wizard.js.map +1 -0
- package/dist/hub/initialization.d.ts +23 -0
- package/dist/hub/initialization.js +28 -0
- package/dist/hub/initialization.js.map +1 -0
- package/dist/hub/member/agent-mode.d.ts +6 -0
- package/dist/hub/member/agent-mode.js +23 -0
- package/dist/hub/member/agent-mode.js.map +1 -0
- package/dist/hub/member/attachments.d.ts +29 -0
- package/dist/hub/member/attachments.js +107 -0
- package/dist/hub/member/attachments.js.map +1 -0
- package/dist/hub/member/exposure-api.d.ts +87 -0
- package/dist/hub/member/exposure-api.js +64 -0
- package/dist/hub/member/exposure-api.js.map +1 -0
- package/dist/hub/member/exposures.d.ts +123 -0
- package/dist/hub/member/exposures.js +282 -0
- package/dist/hub/member/exposures.js.map +1 -0
- package/dist/hub/member/pairing-api.d.ts +85 -0
- package/dist/hub/member/pairing-api.js +385 -0
- package/dist/hub/member/pairing-api.js.map +1 -0
- package/dist/hub/member/quota.d.ts +20 -0
- package/dist/hub/member/quota.js +98 -0
- package/dist/hub/member/quota.js.map +1 -0
- package/dist/hub/member-journal.d.ts +104 -0
- package/dist/hub/member-journal.js +336 -0
- package/dist/hub/member-journal.js.map +1 -0
- package/dist/hub/member-reconciliation.d.ts +14 -0
- package/dist/hub/member-reconciliation.js +97 -0
- package/dist/hub/member-reconciliation.js.map +1 -0
- package/dist/hub/mount.d.ts +39 -0
- package/dist/hub/mount.js +123 -0
- package/dist/hub/mount.js.map +1 -0
- package/dist/hub/pairing-client.d.ts +17 -0
- package/dist/hub/pairing-client.js +108 -0
- package/dist/hub/pairing-client.js.map +1 -0
- package/dist/hub/pairing.d.ts +65 -0
- package/dist/hub/pairing.js +211 -0
- package/dist/hub/pairing.js.map +1 -0
- package/dist/hub/policy.d.ts +63 -0
- package/dist/hub/policy.js +147 -0
- package/dist/hub/policy.js.map +1 -0
- package/dist/hub/preview.d.ts +32 -0
- package/dist/hub/preview.js +64 -0
- package/dist/hub/preview.js.map +1 -0
- package/dist/hub/private-files.d.ts +5 -0
- package/dist/hub/private-files.js +44 -0
- package/dist/hub/private-files.js.map +1 -0
- package/dist/hub/profile.d.ts +59 -0
- package/dist/hub/profile.js +73 -0
- package/dist/hub/profile.js.map +1 -0
- package/dist/hub/protocol.d.ts +779 -0
- package/dist/hub/protocol.js +93 -0
- package/dist/hub/protocol.js.map +1 -0
- package/dist/hub/quota.d.ts +24 -0
- package/dist/hub/quota.js +112 -0
- package/dist/hub/quota.js.map +1 -0
- package/dist/hub/representative.d.ts +141 -0
- package/dist/hub/representative.js +528 -0
- package/dist/hub/representative.js.map +1 -0
- package/dist/hub/retention.d.ts +17 -0
- package/dist/hub/retention.js +45 -0
- package/dist/hub/retention.js.map +1 -0
- package/dist/hub/rooms.d.ts +120 -0
- package/dist/hub/rooms.js +535 -0
- package/dist/hub/rooms.js.map +1 -0
- package/dist/hub/runtime.d.ts +106 -0
- package/dist/hub/runtime.js +298 -0
- package/dist/hub/runtime.js.map +1 -0
- package/dist/hub/server.d.ts +56 -0
- package/dist/hub/server.js +202 -0
- package/dist/hub/server.js.map +1 -0
- package/dist/hub/service-start.d.ts +17 -0
- package/dist/hub/service-start.js +109 -0
- package/dist/hub/service-start.js.map +1 -0
- package/dist/hub/sessions.d.ts +53 -0
- package/dist/hub/sessions.js +196 -0
- package/dist/hub/sessions.js.map +1 -0
- package/dist/hub/socket.d.ts +24 -0
- package/dist/hub/socket.js +79 -0
- package/dist/hub/socket.js.map +1 -0
- package/dist/hub/store.d.ts +77 -0
- package/dist/hub/store.js +88 -0
- package/dist/hub/store.js.map +1 -0
- package/dist/hub/tls.d.ts +31 -0
- package/dist/hub/tls.js +135 -0
- package/dist/hub/tls.js.map +1 -0
- package/dist/hub/types.d.ts +401 -0
- package/dist/hub/types.js +2 -0
- package/dist/hub/types.js.map +1 -0
- package/dist/hub/validation.d.ts +33 -0
- package/dist/hub/validation.js +136 -0
- package/dist/hub/validation.js.map +1 -0
- package/dist/hub/version-floor.d.ts +10 -0
- package/dist/hub/version-floor.js +45 -0
- package/dist/hub/version-floor.js.map +1 -0
- package/dist/hub-browser-certificate-policy.d.ts +31 -0
- package/dist/hub-browser-certificate-policy.js +25 -0
- package/dist/hub-browser-certificate-policy.js.map +1 -0
- package/dist/hub-membership-settings.d.ts +6 -0
- package/dist/hub-membership-settings.js +21 -0
- package/dist/hub-membership-settings.js.map +1 -0
- package/dist/hub-mode.d.ts +15 -0
- package/dist/hub-mode.js +17 -0
- package/dist/hub-mode.js.map +1 -0
- package/dist/hub-pairing-summary.d.ts +48 -0
- package/dist/hub-pairing-summary.js +36 -0
- package/dist/hub-pairing-summary.js.map +1 -0
- package/dist/hub-report-target.d.ts +32 -0
- package/dist/hub-report-target.js +33 -0
- package/dist/hub-report-target.js.map +1 -0
- package/dist/hub-retention-policy.d.ts +14 -0
- package/dist/hub-retention-policy.js +15 -0
- package/dist/hub-retention-policy.js.map +1 -0
- package/dist/instance-config-impact.js +3 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +17 -2
- package/dist/instance-lifecycle.js +58 -8
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instance-topic-delete.d.ts +77 -0
- package/dist/instance-topic-delete.js +123 -0
- package/dist/instance-topic-delete.js.map +1 -0
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.js +1 -1
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-engine-status.d.ts +11 -0
- package/dist/kiro-engine-status.js +6 -0
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/launchd-service-domain.d.ts +5 -0
- package/dist/launchd-service-domain.js +21 -0
- package/dist/launchd-service-domain.js.map +1 -0
- package/dist/locale.js +125 -3
- package/dist/locale.js.map +1 -1
- package/dist/log-service.d.ts +28 -0
- package/dist/log-service.js +29 -0
- package/dist/log-service.js.map +1 -1
- package/dist/log-steps.d.ts +4 -3
- package/dist/log-steps.js +32 -7
- package/dist/log-steps.js.map +1 -1
- package/dist/logger.d.ts +16 -2
- package/dist/logger.js +346 -66
- package/dist/logger.js.map +1 -1
- package/dist/login-flows.d.ts +15 -7
- package/dist/login-flows.js +29 -3
- package/dist/login-flows.js.map +1 -1
- package/dist/login-manager.js +25 -4
- package/dist/login-manager.js.map +1 -1
- package/dist/ls-rows.js +3 -4
- package/dist/ls-rows.js.map +1 -1
- package/dist/missed-offline.d.ts +25 -0
- package/dist/missed-offline.js +79 -0
- package/dist/missed-offline.js.map +1 -0
- package/dist/native-instance-api.d.ts +0 -1
- package/dist/native-instance-api.js +15 -3
- package/dist/native-instance-api.js.map +1 -1
- package/dist/native-instance-input.d.ts +3 -0
- package/dist/native-instance-input.js +6 -1
- package/dist/native-instance-input.js.map +1 -1
- package/dist/native-instance-registry.d.ts +6 -0
- package/dist/native-instance-registry.js +24 -0
- package/dist/native-instance-registry.js.map +1 -1
- package/dist/native-mcp.d.ts +3 -0
- package/dist/native-mcp.js +15 -2
- package/dist/native-mcp.js.map +1 -1
- package/dist/native-pane-lifecycle.d.ts +8 -0
- package/dist/native-pane-lifecycle.js +13 -4
- package/dist/native-pane-lifecycle.js.map +1 -1
- package/dist/native-pane-manager.js +17 -9
- package/dist/native-pane-manager.js.map +1 -1
- package/dist/needs-you-hub.d.ts +9 -1
- package/dist/needs-you-hub.js +46 -8
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +47 -2
- package/dist/needs-you.js +31 -3
- package/dist/needs-you.js.map +1 -1
- package/dist/office-share-page.js +2 -2
- package/dist/office-share-page.js.map +1 -1
- package/dist/office-share.d.ts +11 -0
- package/dist/office-share.js +14 -0
- package/dist/office-share.js.map +1 -1
- package/dist/office-talk.d.ts +26 -0
- package/dist/office-talk.js +50 -0
- package/dist/office-talk.js.map +1 -0
- package/dist/outbound-handlers.d.ts +14 -0
- package/dist/outbound-handlers.js +49 -6
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +33 -1
- package/dist/outbound-schemas.js +29 -16
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/pane-quota-history.d.ts +9 -0
- package/dist/pane-quota-history.js +67 -0
- package/dist/pane-quota-history.js.map +1 -0
- package/dist/pause-marker.d.ts +1 -1
- package/dist/pause-marker.js +1 -1
- package/dist/pause-marker.js.map +1 -1
- package/dist/platform-general.d.ts +46 -0
- package/dist/platform-general.js +91 -0
- package/dist/platform-general.js.map +1 -0
- package/dist/public-web-gateway.js +7 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/queued-handoffs.d.ts +33 -0
- package/dist/queued-handoffs.js +75 -0
- package/dist/queued-handoffs.js.map +1 -0
- package/dist/quickstart.d.ts +13 -0
- package/dist/quickstart.js +81 -5
- package/dist/quickstart.js.map +1 -1
- package/dist/quota-notice.d.ts +7 -0
- package/dist/quota-notice.js +40 -0
- package/dist/quota-notice.js.map +1 -1
- package/dist/reply-buttons-controller.js +10 -6
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/reply-polls.d.ts +2 -2
- package/dist/reply-polls.js +3 -3
- package/dist/reply-polls.js.map +1 -1
- package/dist/runtime-api.d.ts +2 -0
- package/dist/runtime-api.js +25 -7
- package/dist/runtime-api.js.map +1 -1
- package/dist/runtime-build-info.js +5 -3
- package/dist/runtime-build-info.js.map +1 -1
- package/dist/runtime-bundle.d.ts +3 -0
- package/dist/runtime-bundle.js +3 -1
- package/dist/runtime-bundle.js.map +1 -1
- package/dist/runtime-cli.d.ts +8 -1
- package/dist/runtime-cli.js +127 -8
- package/dist/runtime-cli.js.map +1 -1
- package/dist/runtime-client-store.d.ts +7 -0
- package/dist/runtime-client-store.js +30 -2
- package/dist/runtime-client-store.js.map +1 -1
- package/dist/runtime-client.d.ts +63 -1
- package/dist/runtime-client.js +295 -21
- package/dist/runtime-client.js.map +1 -1
- package/dist/runtime-coordinator.d.ts +7 -0
- package/dist/runtime-coordinator.js +213 -35
- package/dist/runtime-coordinator.js.map +1 -1
- package/dist/runtime-credential-profiles.d.ts +78 -0
- package/dist/runtime-credential-profiles.js +280 -0
- package/dist/runtime-credential-profiles.js.map +1 -0
- package/dist/runtime-install.d.ts +50 -0
- package/dist/runtime-install.js +186 -0
- package/dist/runtime-install.js.map +1 -0
- package/dist/runtime-pane-assets.d.ts +1 -1
- package/dist/runtime-pane-assets.js +1 -1
- package/dist/runtime-pane-assets.js.map +1 -1
- package/dist/runtime-pane-codex-index.d.ts +10 -1
- package/dist/runtime-pane-codex-index.js +131 -27
- package/dist/runtime-pane-codex-index.js.map +1 -1
- package/dist/runtime-pane-host.d.ts +19 -0
- package/dist/runtime-pane-host.js +50 -7
- package/dist/runtime-pane-host.js.map +1 -1
- package/dist/runtime-pane-link.d.ts +7 -0
- package/dist/runtime-pane-link.js +93 -2
- package/dist/runtime-pane-link.js.map +1 -1
- package/dist/runtime-pane-mcp-relay.d.ts +1 -0
- package/dist/runtime-pane-mcp-relay.js +10 -0
- package/dist/runtime-pane-mcp-relay.js.map +1 -1
- package/dist/runtime-pane-mcp.d.ts +4 -0
- package/dist/runtime-pane-mcp.js +6 -3
- package/dist/runtime-pane-mcp.js.map +1 -1
- package/dist/runtime-pane-native.d.ts +32 -2
- package/dist/runtime-pane-native.js +55 -6
- package/dist/runtime-pane-native.js.map +1 -1
- package/dist/runtime-pane-port.d.ts +5 -0
- package/dist/runtime-pane-port.js +17 -1
- package/dist/runtime-pane-port.js.map +1 -1
- package/dist/runtime-pane-process.d.ts +1 -1
- package/dist/runtime-pane-process.js +11 -2
- package/dist/runtime-pane-process.js.map +1 -1
- package/dist/runtime-pane-protocol.d.ts +11 -1
- package/dist/runtime-pane-protocol.js +27 -5
- package/dist/runtime-pane-protocol.js.map +1 -1
- package/dist/runtime-pane-quota-history.d.ts +6 -0
- package/dist/runtime-pane-quota-history.js +44 -0
- package/dist/runtime-pane-quota-history.js.map +1 -0
- package/dist/runtime-pane-service.d.ts +5 -0
- package/dist/runtime-pane-service.js +47 -12
- package/dist/runtime-pane-service.js.map +1 -1
- package/dist/runtime-pane-transcript.d.ts +5 -0
- package/dist/runtime-pane-transcript.js +66 -5
- package/dist/runtime-pane-transcript.js.map +1 -1
- package/dist/runtime-pane-worker.js +19 -6
- package/dist/runtime-pane-worker.js.map +1 -1
- package/dist/runtime-protocol.d.ts +17 -2
- package/dist/runtime-protocol.js +12 -0
- package/dist/runtime-protocol.js.map +1 -1
- package/dist/runtime-update-activity.d.ts +21 -0
- package/dist/runtime-update-activity.js +51 -0
- package/dist/runtime-update-activity.js.map +1 -0
- package/dist/runtime-update-artifact.d.ts +31 -0
- package/dist/runtime-update-artifact.js +252 -0
- package/dist/runtime-update-artifact.js.map +1 -0
- package/dist/runtime-update-install.d.ts +31 -0
- package/dist/runtime-update-install.js +205 -0
- package/dist/runtime-update-install.js.map +1 -0
- package/dist/runtime-update-journal.d.ts +44 -0
- package/dist/runtime-update-journal.js +121 -0
- package/dist/runtime-update-journal.js.map +1 -0
- package/dist/runtime-update-lock.d.ts +48 -0
- package/dist/runtime-update-lock.js +217 -0
- package/dist/runtime-update-lock.js.map +1 -0
- package/dist/runtime-update-owners.d.ts +29 -0
- package/dist/runtime-update-owners.js +240 -0
- package/dist/runtime-update-owners.js.map +1 -0
- package/dist/runtime-update-protocol.d.ts +15 -0
- package/dist/runtime-update-protocol.js +13 -0
- package/dist/runtime-update-protocol.js.map +1 -0
- package/dist/runtime-windows-bridge.d.ts +2 -1
- package/dist/runtime-windows-bridge.js +11 -1
- package/dist/runtime-windows-bridge.js.map +1 -1
- package/dist/scheduler/db.d.ts +2 -1
- package/dist/scheduler/db.js +23 -9
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/task-board-text.js +1 -1
- package/dist/scheduler/task-board-text.js.map +1 -1
- package/dist/scheduler/task-board.d.ts +13 -0
- package/dist/scheduler/task-board.js +28 -3
- package/dist/scheduler/task-board.js.map +1 -1
- package/dist/service-drain.d.ts +19 -0
- package/dist/service-drain.js +64 -0
- package/dist/service-drain.js.map +1 -0
- package/dist/service-installer.d.ts +7 -2
- package/dist/service-installer.js +13 -10
- package/dist/service-installer.js.map +1 -1
- package/dist/settings-api.d.ts +20 -0
- package/dist/settings-api.js +414 -4
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.d.ts +6 -0
- package/dist/settings-baseline.js +3 -1
- package/dist/settings-baseline.js.map +1 -1
- package/dist/settings-change.js +29 -6
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.d.ts +13 -0
- package/dist/settings-effect.js +97 -0
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.js +13 -1
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/settings-instance-patch.js +27 -0
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/setup-wizard.js +6 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/task-board-tool.d.ts +13 -1
- package/dist/task-board-tool.js +104 -4
- package/dist/task-board-tool.js.map +1 -1
- package/dist/task-board-waker.d.ts +6 -0
- package/dist/task-board-waker.js +4 -0
- package/dist/task-board-waker.js.map +1 -1
- package/dist/tmux-binary.d.ts +59 -0
- package/dist/tmux-binary.js +200 -0
- package/dist/tmux-binary.js.map +1 -0
- package/dist/tmux-control.js +4 -4
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-exec-helper.js +32 -1
- package/dist/tmux-exec-helper.js.map +1 -1
- package/dist/tmux-manager.d.ts +1 -1
- package/dist/tmux-manager.js +45 -36
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.js +4 -3
- package/dist/tmux-read.js.map +1 -1
- package/dist/tool-permissions.d.ts +5 -2
- package/dist/tool-permissions.js +6 -5
- package/dist/tool-permissions.js.map +1 -1
- package/dist/tool-progress.d.ts +2 -0
- package/dist/tool-progress.js +19 -3
- package/dist/tool-progress.js.map +1 -1
- package/dist/topic-commands.js +10 -5
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-monitor.d.ts +20 -0
- package/dist/transcript-monitor.js +47 -3
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-needles.d.ts +7 -0
- package/dist/transcript-needles.js +9 -1
- package/dist/transcript-needles.js.map +1 -1
- package/dist/transcript-records.d.ts +1 -1
- package/dist/transcript-records.js +2 -1
- package/dist/transcript-records.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/ui/account-identity.js +27 -0
- package/dist/ui/accounts-view.js +214 -0
- package/dist/ui/agent-runtime-settings.js +9 -8
- package/dist/ui/backend-signin.js +4 -1
- package/dist/ui/chat-ambient.js +1 -1
- package/dist/ui/chat-md-strings.js +3 -0
- package/dist/ui/chat-render.js +3 -670
- package/dist/ui/chat-store.js +1 -1
- package/dist/ui/chat-strings.js +3 -333
- package/dist/ui/chat-thread.js +3 -919
- package/dist/ui/chat-time.js +3 -80
- package/dist/ui/chat-tour.js +1 -1
- package/dist/ui/credential-profile-select.js +54 -0
- package/dist/ui/fleet-office-dialogue.d.ts +30 -0
- package/dist/ui/fleet-office-dialogue.js +382 -0
- package/dist/ui/fleet-office-pack.d.ts +9 -0
- package/dist/ui/fleet-office-pack.js +76 -4
- package/dist/ui/fleet-office-skin.js +23 -5
- package/dist/ui/fleet-office-store.js +5 -0
- package/dist/ui/fleet-office.js +173 -6
- package/dist/ui/fleet-task-card.js +10 -6
- package/dist/ui/fleet-task-common.js +12 -2
- package/dist/ui/fleet-task-menu.js +188 -0
- package/dist/ui/fleet-task-stats.js +124 -0
- package/dist/ui/fleet-task-view.js +340 -0
- package/dist/ui/fleet-tasks.js +131 -43
- package/dist/ui/fleet-usage.js +90 -27
- package/dist/ui/html-attachment.js +3 -40
- package/dist/ui/hub-agent-copy.js +23 -0
- package/dist/ui/hub-button-actions.js +65 -0
- package/dist/ui/hub-chat-store.js +158 -0
- package/dist/ui/hub-chat-strings.js +77 -0
- package/dist/ui/hub-client.js +329 -0
- package/dist/ui/hub-owner-strings.js +51 -0
- package/dist/ui/hub-provider-guidance.js +31 -0
- package/dist/ui/hub-quota.js +85 -0
- package/dist/ui/hub-strings.js +162 -0
- package/dist/ui/hub-switcher.js +27 -0
- package/dist/ui/native-pane-recovery.js +1 -1
- package/dist/ui/office-share-page.js +4 -2
- package/dist/ui/panel-chat.js +34 -48
- package/dist/ui/panel-details.js +1 -1
- package/dist/ui/panel-fleet.js +78 -10
- package/dist/ui/panel-hub.js +619 -0
- package/dist/ui/panel-log.js +2 -2
- package/dist/ui/panel-needs.js +24 -8
- package/dist/ui/panel-runtimes.js +114 -23
- package/dist/ui/panel-settings.js +69 -80
- package/dist/ui/panel-windows-cli.js +12 -2
- package/dist/ui/preview-pages.js +1 -1
- package/dist/ui/preview-panel.js +92 -6
- package/dist/ui/preview-versions.js +1 -1
- package/dist/ui/preview.js +3 -476
- package/dist/ui/runtime-commands.d.ts +4 -0
- package/dist/ui/runtime-commands.js +59 -0
- package/dist/ui/search-dialog.js +2 -0
- package/dist/ui/settings-access-strings.js +42 -0
- package/dist/ui/settings-build-version.js +35 -0
- package/dist/ui/settings-codex-copy.js +19 -0
- package/dist/ui/settings-devices.js +253 -0
- package/dist/ui/settings-dialogs.js +28 -7
- package/dist/ui/settings-hub-browser-certificate.js +74 -0
- package/dist/ui/settings-hub-membership.js +72 -0
- package/dist/ui/settings-hub-retention.js +52 -0
- package/dist/ui/settings-hub.js +196 -0
- package/dist/ui/settings-layout.js +8 -11
- package/dist/ui/settings-model.js +16 -2
- package/dist/ui/settings-outside.js +104 -38
- package/dist/ui/settings-registry.js +4 -1
- package/dist/ui/settings-shared-strings.js +143 -0
- package/dist/ui/settings-shared.js +345 -0
- package/dist/ui/settings-strings.js +10 -46
- package/dist/ui/settings-web-authority.js +5 -2
- package/dist/ui/shared/accounts.css +15 -0
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-needs.js +1 -1
- package/dist/ui/shared/app-route.js +6 -1
- package/dist/ui/shared/app-session.js +6 -2
- package/dist/ui/shared/app-shell.js +64 -8
- package/dist/ui/shared/app.css +121 -30
- package/dist/ui/shared/app.js +12 -3
- package/dist/ui/shared/chat-composer.js +68 -0
- package/dist/ui/shared/chat-md-strings.js +9 -0
- package/dist/ui/shared/chat-render.js +682 -0
- package/dist/ui/shared/chat-strings.js +333 -0
- package/dist/ui/shared/chat-thread.js +969 -0
- package/dist/ui/shared/chat-time.js +80 -0
- package/dist/ui/shared/header-tools.js +3 -5
- package/dist/ui/shared/html-attachment.js +42 -0
- package/dist/ui/shared/hub-chat.css +85 -0
- package/dist/ui/shared/hub-owner.css +33 -0
- package/dist/ui/shared/hub-quota.css +8 -0
- package/dist/ui/shared/hub.css +71 -0
- package/dist/ui/shared/page-head.js +8 -0
- package/dist/ui/shared/panel-view.js +77 -4
- package/dist/ui/shared/preview.js +476 -0
- package/dist/ui/shared/runtime-install.css +26 -0
- package/dist/ui/shared/side-rail.js +15 -0
- package/dist/ui/shared/signin.js +172 -0
- package/dist/ui/shared/task-board.css +95 -0
- package/dist/ui/shared/usage-dialog.js +18 -1
- package/dist/ui/shared/view-history.css +17 -0
- package/dist/ui/shared/view-history.js +438 -0
- package/dist/ui/shared/view-strings.js +16 -0
- package/dist/ui/shared/workspace.css +20 -0
- package/dist/ui/signin.html +21 -0
- package/dist/ui/workspace-panel.js +189 -0
- package/dist/ui/workspace-strings.js +35 -0
- package/dist/unattended-install.d.ts +11 -2
- package/dist/unattended-install.js +41 -6
- package/dist/unattended-install.js.map +1 -1
- package/dist/usage/capacity.d.ts +69 -0
- package/dist/usage/capacity.js +119 -0
- package/dist/usage/capacity.js.map +1 -0
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +3 -0
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/profile-timeline.d.ts +16 -0
- package/dist/usage/profile-timeline.js +58 -0
- package/dist/usage/profile-timeline.js.map +1 -0
- package/dist/usage/providers.js +2 -1
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/quota-history.d.ts +43 -0
- package/dist/usage/quota-history.js +168 -0
- package/dist/usage/quota-history.js.map +1 -0
- package/dist/usage/usage-api.d.ts +31 -0
- package/dist/usage/usage-api.js +80 -1
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/usage-report.d.ts +25 -1
- package/dist/usage-report.js +55 -4
- package/dist/usage-report.js.map +1 -1
- package/dist/usage-rollup.d.ts +6 -1
- package/dist/usage-rollup.js +16 -4
- package/dist/usage-rollup.js.map +1 -1
- package/dist/view-api.d.ts +16 -0
- package/dist/view-api.js +105 -23
- package/dist/view-api.js.map +1 -1
- package/dist/view-history.d.ts +84 -0
- package/dist/view-history.js +116 -0
- package/dist/view-history.js.map +1 -0
- package/dist/web-api.d.ts +48 -2
- package/dist/web-api.js +276 -8
- package/dist/web-api.js.map +1 -1
- package/dist/web-backend-login.d.ts +23 -1
- package/dist/web-backend-login.js +11 -17
- package/dist/web-backend-login.js.map +1 -1
- package/dist/web-device-login.d.ts +153 -0
- package/dist/web-device-login.js +278 -0
- package/dist/web-device-login.js.map +1 -0
- package/dist/web-office-skins.d.ts +9 -0
- package/dist/web-office-skins.js +16 -1
- package/dist/web-office-skins.js.map +1 -1
- package/dist/web-session-authorization.d.ts +13 -2
- package/dist/web-session-authorization.js +10 -3
- package/dist/web-session-authorization.js.map +1 -1
- package/dist/web-session.d.ts +35 -0
- package/dist/web-session.js +7 -0
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -1
- package/dist/web-settings-patch.js +4 -1
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-shell-routes.d.ts +6 -0
- package/dist/web-shell-routes.js +7 -0
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/web-terminal.d.ts +4 -30
- package/dist/web-terminal.js +9 -6
- package/dist/web-terminal.js.map +1 -1
- package/dist/windows-agents.d.ts +1 -0
- package/dist/windows-agents.js +1 -0
- package/dist/windows-agents.js.map +1 -1
- package/dist/windows-cli-api.d.ts +12 -1
- package/dist/windows-cli-api.js +27 -1
- package/dist/windows-cli-api.js.map +1 -1
- package/dist/windows-cli-providers.d.ts +0 -9
- package/dist/windows-cli-providers.js +4 -9
- package/dist/windows-cli-providers.js.map +1 -1
- package/dist/windows-cli-worker.d.ts +24 -0
- package/dist/windows-cli-worker.js +96 -5
- package/dist/windows-cli-worker.js.map +1 -1
- package/dist/windows-cli.d.ts +10 -0
- package/dist/windows-cli.js +10 -1
- package/dist/windows-cli.js.map +1 -1
- package/dist/yaml-shared-nodes.js +8 -3
- package/dist/yaml-shared-nodes.js.map +1 -1
- package/launcher/agend-install.cjs +8 -1
- package/launcher/launchd-session-type.cjs +14 -0
- package/launcher/postinstall.cjs +27 -2
- package/launcher/private-home.cjs +1 -1
- package/launcher/tmux-bundle.cjs +247 -0
- package/package.json +3 -2
- package/templates/launchd.plist.ejs +3 -1
- package/templates/runtime-install/install.ps1 +270 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
import { HubProtocolError } from "../validation.js";
|
|
3
|
+
import type { HubAttachmentRef } from "../types.js";
|
|
4
|
+
import { type HubAttachmentLimits } from "./limits.js";
|
|
5
|
+
export declare const UPLOAD_TTL_MS: number;
|
|
6
|
+
/** Files waiting to be used (an asker's uploads; a fleet's staged answer files) are budgeted, not only aged: per owner of
|
|
7
|
+
* the wait, and in all. A full budget refuses (backpressure) before anything is stored. */
|
|
8
|
+
export declare const HUB_PENDING_BUDGET: Readonly<{
|
|
9
|
+
files: 20;
|
|
10
|
+
bytes: number;
|
|
11
|
+
totalBytes: number;
|
|
12
|
+
}>;
|
|
13
|
+
declare function migrate(db: Database.Database): void;
|
|
14
|
+
/** Its own component (an older build that meets it refuses to open the state, as for every Hub component). */
|
|
15
|
+
export declare const HUB_ATTACHMENTS_MIGRATION: Readonly<{
|
|
16
|
+
component: "s7-attachments";
|
|
17
|
+
version: 1;
|
|
18
|
+
up: typeof migrate;
|
|
19
|
+
}>;
|
|
20
|
+
interface Row {
|
|
21
|
+
id: string;
|
|
22
|
+
sha256: string;
|
|
23
|
+
name: string;
|
|
24
|
+
size: number;
|
|
25
|
+
mime: string;
|
|
26
|
+
direction: "question" | "answer";
|
|
27
|
+
state: "pending" | "staged" | "bound";
|
|
28
|
+
fleet_id: string | null;
|
|
29
|
+
room_id: string | null;
|
|
30
|
+
uploader: string | null;
|
|
31
|
+
message_id: string | null;
|
|
32
|
+
position: number | null;
|
|
33
|
+
created_at: number;
|
|
34
|
+
expires_at: number | null;
|
|
35
|
+
}
|
|
36
|
+
export type HubAttachmentRow = Readonly<Row>;
|
|
37
|
+
export declare const refOf: (r: Row) => HubAttachmentRef;
|
|
38
|
+
export interface HubAttachmentStoreOptions {
|
|
39
|
+
contentKey: Buffer;
|
|
40
|
+
now?: () => number;
|
|
41
|
+
limits?: Partial<HubAttachmentLimits> | null;
|
|
42
|
+
/** Tests only: a smaller pending budget. */
|
|
43
|
+
budget?: Partial<{
|
|
44
|
+
files: number;
|
|
45
|
+
bytes: number;
|
|
46
|
+
totalBytes: number;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
export declare class HubAttachmentStore {
|
|
50
|
+
private readonly options;
|
|
51
|
+
private readonly key;
|
|
52
|
+
readonly limits: HubAttachmentLimits;
|
|
53
|
+
constructor(options: HubAttachmentStoreOptions);
|
|
54
|
+
private now;
|
|
55
|
+
private budget;
|
|
56
|
+
/** What is physically waiting now (after the sweep): every remaining upload/staged file of one owner (uploader or fleet),
|
|
57
|
+
* staging in progress, and in all — no age filter, so a row the sweep did not delete is always charged. */
|
|
58
|
+
private waiting;
|
|
59
|
+
/** Expired uploads/staged files and stale staging, deleted with any blob nothing uses any more (caller's transaction). */
|
|
60
|
+
private sweepExpired;
|
|
61
|
+
private dropOrphans;
|
|
62
|
+
/** Room for one more waiting file of `size` bytes for this owner (backpressure otherwise). Capacity held by an expired
|
|
63
|
+
* file returns only once its bytes are actually deleted — here, in the same transaction — never by age alone. */
|
|
64
|
+
admit(db: Database.Database, owner: {
|
|
65
|
+
uploader?: string;
|
|
66
|
+
fleetId?: string;
|
|
67
|
+
}, size: number): void;
|
|
68
|
+
private seal;
|
|
69
|
+
private open;
|
|
70
|
+
/** Store whole-file bytes under their digest (once per digest); returns the digest. */
|
|
71
|
+
storeBlob(db: Database.Database, bytes: Buffer): string;
|
|
72
|
+
/** One chunk of a stored file, at a chunk-aligned offset. */
|
|
73
|
+
chunk(db: Database.Database, digest: string, offset: number): {
|
|
74
|
+
data: Buffer;
|
|
75
|
+
total: number;
|
|
76
|
+
};
|
|
77
|
+
/** A whole stored file (downloads; bounded by the file limit). */
|
|
78
|
+
read(db: Database.Database, digest: string): Buffer;
|
|
79
|
+
/** The asker's upload: classified by name and (for an image) magic bytes, stored, pending for one hour. */
|
|
80
|
+
createUpload(db: Database.Database, input: {
|
|
81
|
+
roomId: string;
|
|
82
|
+
uploader: string;
|
|
83
|
+
name: string;
|
|
84
|
+
bytes: Buffer;
|
|
85
|
+
}): HubAttachmentRef;
|
|
86
|
+
/** The uploader's own unexpired pending files in this room, in the order named; refused as a whole otherwise. */
|
|
87
|
+
pending(db: Database.Database, roomId: string, uploader: string, ids: readonly string[]): HubAttachmentRef[];
|
|
88
|
+
bindQuestion(db: Database.Database, refs: readonly HubAttachmentRef[], messageId: string, fleetId: string): void;
|
|
89
|
+
/** A message's files in one direction, in order. */
|
|
90
|
+
forMessage(db: Database.Database, messageId: string, direction: "question" | "answer"): HubAttachmentRef[];
|
|
91
|
+
row(db: Database.Database, id: string): HubAttachmentRow | undefined;
|
|
92
|
+
/** One chunk of an answer's file from the member, in order. Returns the next offset; the last chunk checks the digest. */
|
|
93
|
+
stage(db: Database.Database, fleetId: string, c: {
|
|
94
|
+
id: string;
|
|
95
|
+
offset: number;
|
|
96
|
+
total: number;
|
|
97
|
+
sha256: string;
|
|
98
|
+
data: Buffer;
|
|
99
|
+
}): {
|
|
100
|
+
complete: boolean;
|
|
101
|
+
discarded?: true;
|
|
102
|
+
};
|
|
103
|
+
/** Bind an answer's files: each must be a complete file this fleet sent, matching the ref's digest and size; its
|
|
104
|
+
* name decides its type and an image must carry its magic bytes, exactly as for an asker's upload. */
|
|
105
|
+
bindAnswer(db: Database.Database, refs: readonly HubAttachmentRef[], messageId: string, roomId: string, fleetId: string): void;
|
|
106
|
+
/** Retention: bound files older than `contentCut`, expired uploads and staging, then blobs nothing uses. */
|
|
107
|
+
purge(db: Database.Database, contentCut: number): {
|
|
108
|
+
files: number;
|
|
109
|
+
blobs: number;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export declare class HubAttachmentRefused extends HubProtocolError {
|
|
113
|
+
readonly refusal: "type-not-allowed" | "image-mismatch" | "empty";
|
|
114
|
+
constructor(refusal: "type-not-allowed" | "image-mismatch" | "empty");
|
|
115
|
+
}
|
|
116
|
+
export {};
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hub attachments (attachments-v1): files stored by digest, each 180 KiB segment AES-256-GCM under the Hub content key
|
|
3
|
+
* (the audit content key), so serving one chunk decrypts one segment. Rows say which room and message a file belongs
|
|
4
|
+
* to and in which direction it travelled. Every method runs inside the caller's transaction (`db` is that tx's DB).
|
|
5
|
+
*
|
|
6
|
+
* - A question's file starts as the asker's pending upload (one hour), then is bound to the question that names it.
|
|
7
|
+
* - An answer's file arrives from the member in chunks (`attachment.put`), staged under its id until the whole file is
|
|
8
|
+
* in and its SHA-256 matches; the answer that names it binds it, re-checking name, type and size.
|
|
9
|
+
* - Retention deletes rows older than `contentDays`, expired uploads and staging, then blobs no row uses.
|
|
10
|
+
*/
|
|
11
|
+
import { createCipheriv, createDecipheriv, createHash, randomBytes, randomUUID } from "node:crypto";
|
|
12
|
+
import { HUB_ATTACHMENT_CHUNK } from "../protocol.js";
|
|
13
|
+
import { HubProtocolError } from "../validation.js";
|
|
14
|
+
import { attachmentLimits, classifyAttachment } from "./limits.js";
|
|
15
|
+
export const UPLOAD_TTL_MS = 60 * 60 * 1000;
|
|
16
|
+
/** Files waiting to be used (an asker's uploads; a fleet's staged answer files) are budgeted, not only aged: per owner of
|
|
17
|
+
* the wait, and in all. A full budget refuses (backpressure) before anything is stored. */
|
|
18
|
+
export const HUB_PENDING_BUDGET = Object.freeze({ files: 20, bytes: 100 * 1024 * 1024, totalBytes: 1024 * 1024 * 1024 });
|
|
19
|
+
const STAGING_TTL_MS = 60 * 60 * 1000;
|
|
20
|
+
const sha = (b) => createHash("sha256").update(b).digest("hex");
|
|
21
|
+
function migrate(db) {
|
|
22
|
+
db.exec(`CREATE TABLE IF NOT EXISTS hub_attachment_blobs(sha256 TEXT PRIMARY KEY, size INTEGER NOT NULL, created_at INTEGER NOT NULL);
|
|
23
|
+
CREATE TABLE IF NOT EXISTS hub_attachment_segments(sha256 TEXT NOT NULL, idx INTEGER NOT NULL, nonce BLOB NOT NULL, ciphertext BLOB NOT NULL, PRIMARY KEY(sha256, idx));
|
|
24
|
+
CREATE TABLE IF NOT EXISTS hub_attachments(id TEXT PRIMARY KEY, sha256 TEXT NOT NULL, name TEXT NOT NULL, size INTEGER NOT NULL, mime TEXT NOT NULL,
|
|
25
|
+
direction TEXT NOT NULL CHECK(direction IN ('question','answer')), state TEXT NOT NULL CHECK(state IN ('pending','staged','bound')),
|
|
26
|
+
fleet_id TEXT, room_id TEXT, uploader TEXT, message_id TEXT, position INTEGER, created_at INTEGER NOT NULL, expires_at INTEGER);
|
|
27
|
+
CREATE INDEX IF NOT EXISTS hub_attachments_message ON hub_attachments(message_id, direction, position);
|
|
28
|
+
CREATE TABLE IF NOT EXISTS hub_attachment_staging(id TEXT NOT NULL, idx INTEGER NOT NULL, fleet_id TEXT NOT NULL, total INTEGER NOT NULL, sha256 TEXT NOT NULL,
|
|
29
|
+
nonce BLOB NOT NULL, ciphertext BLOB NOT NULL, created_at INTEGER NOT NULL, PRIMARY KEY(id, idx));`);
|
|
30
|
+
}
|
|
31
|
+
/** Its own component (an older build that meets it refuses to open the state, as for every Hub component). */
|
|
32
|
+
export const HUB_ATTACHMENTS_MIGRATION = Object.freeze({ component: "s7-attachments", version: 1, up: migrate });
|
|
33
|
+
export const refOf = (r) => ({ id: r.id, name: r.name, size: r.size, mime: r.mime, sha256: r.sha256 });
|
|
34
|
+
export class HubAttachmentStore {
|
|
35
|
+
options;
|
|
36
|
+
key;
|
|
37
|
+
limits;
|
|
38
|
+
constructor(options) {
|
|
39
|
+
this.options = options;
|
|
40
|
+
if (!Buffer.isBuffer(options.contentKey) || options.contentKey.length !== 32)
|
|
41
|
+
throw new Error("the Hub content key must be 32 bytes");
|
|
42
|
+
this.key = Buffer.from(options.contentKey);
|
|
43
|
+
this.limits = attachmentLimits(options.limits);
|
|
44
|
+
}
|
|
45
|
+
now() { return this.options.now?.() ?? Date.now(); }
|
|
46
|
+
budget() { return { ...HUB_PENDING_BUDGET, ...this.options.budget }; }
|
|
47
|
+
/** What is physically waiting now (after the sweep): every remaining upload/staged file of one owner (uploader or fleet),
|
|
48
|
+
* staging in progress, and in all — no age filter, so a row the sweep did not delete is always charged. */
|
|
49
|
+
waiting(db, owner) {
|
|
50
|
+
const rows = db.prepare(`SELECT COUNT(*) AS n, COALESCE(SUM(size),0) AS b FROM hub_attachments WHERE state IN ('pending','staged')
|
|
51
|
+
AND ${owner.uploader !== undefined ? "uploader=?" : "fleet_id=?"}`).get(owner.uploader ?? owner.fleetId);
|
|
52
|
+
const staging = owner.fleetId !== undefined ? db.prepare("SELECT COUNT(*) AS n, COALESCE(SUM(t),0) AS b FROM (SELECT MAX(total) AS t FROM hub_attachment_staging WHERE fleet_id=? GROUP BY id)").get(owner.fleetId) : { n: 0, b: 0 };
|
|
53
|
+
const all = db.prepare("SELECT COALESCE(SUM(size),0) AS b FROM hub_attachments WHERE state IN ('pending','staged')").get().b
|
|
54
|
+
+ db.prepare("SELECT COALESCE(SUM(t),0) AS b FROM (SELECT MAX(total) AS t FROM hub_attachment_staging GROUP BY id)").get().b;
|
|
55
|
+
return { files: rows.n + staging.n, bytes: rows.b + staging.b, total: all };
|
|
56
|
+
}
|
|
57
|
+
/** Expired uploads/staged files and stale staging, deleted with any blob nothing uses any more (caller's transaction). */
|
|
58
|
+
sweepExpired(db) {
|
|
59
|
+
const now = this.now();
|
|
60
|
+
db.prepare("DELETE FROM hub_attachments WHERE state <> 'bound' AND expires_at IS NOT NULL AND expires_at <= ?").run(now);
|
|
61
|
+
db.prepare("DELETE FROM hub_attachment_staging WHERE created_at <= ?").run(now - STAGING_TTL_MS);
|
|
62
|
+
this.dropOrphans(db);
|
|
63
|
+
}
|
|
64
|
+
dropOrphans(db) {
|
|
65
|
+
const orphans = db.prepare("SELECT sha256 FROM hub_attachment_blobs b WHERE NOT EXISTS (SELECT 1 FROM hub_attachments a WHERE a.sha256 = b.sha256)").all();
|
|
66
|
+
for (const o of orphans) {
|
|
67
|
+
db.prepare("DELETE FROM hub_attachment_segments WHERE sha256=?").run(o.sha256);
|
|
68
|
+
db.prepare("DELETE FROM hub_attachment_blobs WHERE sha256=?").run(o.sha256);
|
|
69
|
+
}
|
|
70
|
+
return orphans.length;
|
|
71
|
+
}
|
|
72
|
+
/** Room for one more waiting file of `size` bytes for this owner (backpressure otherwise). Capacity held by an expired
|
|
73
|
+
* file returns only once its bytes are actually deleted — here, in the same transaction — never by age alone. */
|
|
74
|
+
admit(db, owner, size) {
|
|
75
|
+
this.sweepExpired(db);
|
|
76
|
+
const b = this.budget(), w = this.waiting(db, owner);
|
|
77
|
+
if (w.files + 1 > b.files || w.bytes + size > b.bytes || w.total + size > b.totalBytes)
|
|
78
|
+
throw new HubProtocolError("backpressure");
|
|
79
|
+
}
|
|
80
|
+
seal(aad, plain) {
|
|
81
|
+
const nonce = randomBytes(12), c = createCipheriv("aes-256-gcm", this.key, nonce);
|
|
82
|
+
c.setAAD(Buffer.from(aad));
|
|
83
|
+
return { nonce, body: Buffer.concat([c.update(plain), c.final(), c.getAuthTag()]) };
|
|
84
|
+
}
|
|
85
|
+
open(aad, nonce, body) {
|
|
86
|
+
const d = createDecipheriv("aes-256-gcm", this.key, nonce);
|
|
87
|
+
d.setAAD(Buffer.from(aad));
|
|
88
|
+
d.setAuthTag(body.subarray(body.length - 16));
|
|
89
|
+
return Buffer.concat([d.update(body.subarray(0, body.length - 16)), d.final()]);
|
|
90
|
+
}
|
|
91
|
+
/** Store whole-file bytes under their digest (once per digest); returns the digest. */
|
|
92
|
+
storeBlob(db, bytes) {
|
|
93
|
+
if (bytes.length === 0 || bytes.length > this.limits.fileBytes)
|
|
94
|
+
throw new HubProtocolError("invalid");
|
|
95
|
+
const digest = sha(bytes);
|
|
96
|
+
if (db.prepare("SELECT 1 FROM hub_attachment_blobs WHERE sha256=?").get(digest))
|
|
97
|
+
return digest;
|
|
98
|
+
db.prepare("INSERT INTO hub_attachment_blobs(sha256, size, created_at) VALUES(?,?,?)").run(digest, bytes.length, this.now());
|
|
99
|
+
const insert = db.prepare("INSERT INTO hub_attachment_segments(sha256, idx, nonce, ciphertext) VALUES(?,?,?,?)");
|
|
100
|
+
for (let idx = 0, at = 0; at < bytes.length; idx++, at += HUB_ATTACHMENT_CHUNK) {
|
|
101
|
+
const s = this.seal(`agend-hub-attachment-v1\n${digest}\n${idx}`, bytes.subarray(at, at + HUB_ATTACHMENT_CHUNK));
|
|
102
|
+
insert.run(digest, idx, s.nonce, s.body);
|
|
103
|
+
}
|
|
104
|
+
return digest;
|
|
105
|
+
}
|
|
106
|
+
/** One chunk of a stored file, at a chunk-aligned offset. */
|
|
107
|
+
chunk(db, digest, offset) {
|
|
108
|
+
const blob = db.prepare("SELECT size FROM hub_attachment_blobs WHERE sha256=?").get(digest);
|
|
109
|
+
if (!blob)
|
|
110
|
+
throw new HubProtocolError("expired");
|
|
111
|
+
if (!Number.isSafeInteger(offset) || offset < 0 || offset >= blob.size || offset % HUB_ATTACHMENT_CHUNK !== 0)
|
|
112
|
+
throw new HubProtocolError("invalid");
|
|
113
|
+
const idx = offset / HUB_ATTACHMENT_CHUNK, seg = db.prepare("SELECT nonce, ciphertext FROM hub_attachment_segments WHERE sha256=? AND idx=?").get(digest, idx);
|
|
114
|
+
if (!seg)
|
|
115
|
+
throw new HubProtocolError("expired");
|
|
116
|
+
return { data: this.open(`agend-hub-attachment-v1\n${digest}\n${idx}`, seg.nonce, seg.ciphertext), total: blob.size };
|
|
117
|
+
}
|
|
118
|
+
/** A whole stored file (downloads; bounded by the file limit). */
|
|
119
|
+
read(db, digest) {
|
|
120
|
+
const parts = [];
|
|
121
|
+
let total = 0;
|
|
122
|
+
for (let offset = 0; offset === 0 || offset < total; offset += HUB_ATTACHMENT_CHUNK) {
|
|
123
|
+
const c = this.chunk(db, digest, offset);
|
|
124
|
+
total = c.total;
|
|
125
|
+
parts.push(c.data);
|
|
126
|
+
}
|
|
127
|
+
const all = Buffer.concat(parts);
|
|
128
|
+
if (all.length !== total || sha(all) !== digest)
|
|
129
|
+
throw new HubProtocolError("uncertain");
|
|
130
|
+
return all;
|
|
131
|
+
}
|
|
132
|
+
/** The asker's upload: classified by name and (for an image) magic bytes, stored, pending for one hour. */
|
|
133
|
+
createUpload(db, input) {
|
|
134
|
+
if (input.bytes.length > this.limits.fileBytes)
|
|
135
|
+
throw new HubProtocolError("invalid");
|
|
136
|
+
const kind = classifyAttachment(input.name, input.bytes.subarray(0, 64));
|
|
137
|
+
if ("refused" in kind)
|
|
138
|
+
throw new HubAttachmentRefused(kind.refused);
|
|
139
|
+
this.admit(db, { uploader: input.uploader }, input.bytes.length);
|
|
140
|
+
const digest = this.storeBlob(db, input.bytes), now = this.now(), id = randomUUID();
|
|
141
|
+
db.prepare(`INSERT INTO hub_attachments(id, sha256, name, size, mime, direction, state, room_id, uploader, created_at, expires_at)
|
|
142
|
+
VALUES(?,?,?,?,?,'question','pending',?,?,?,?)`).run(id, digest, input.name, input.bytes.length, kind.mime, input.roomId, input.uploader, now, now + UPLOAD_TTL_MS);
|
|
143
|
+
return { id, name: input.name, size: input.bytes.length, mime: kind.mime, sha256: digest };
|
|
144
|
+
}
|
|
145
|
+
/** The uploader's own unexpired pending files in this room, in the order named; refused as a whole otherwise. */
|
|
146
|
+
pending(db, roomId, uploader, ids) {
|
|
147
|
+
if (ids.length > this.limits.files || new Set(ids).size !== ids.length)
|
|
148
|
+
throw new HubProtocolError("invalid");
|
|
149
|
+
const now = this.now(), rows = ids.map(id => db.prepare("SELECT * FROM hub_attachments WHERE id=?").get(id));
|
|
150
|
+
if (rows.some(r => !r || r.direction !== "question" || r.state !== "pending" || r.room_id !== roomId || r.uploader !== uploader || (r.expires_at ?? 0) <= now))
|
|
151
|
+
throw new HubProtocolError("not-found");
|
|
152
|
+
const refs = rows.map(r => refOf(r));
|
|
153
|
+
if (refs.reduce((n, r) => n + r.size, 0) > this.limits.messageBytes)
|
|
154
|
+
throw new HubProtocolError("invalid");
|
|
155
|
+
return refs;
|
|
156
|
+
}
|
|
157
|
+
bindQuestion(db, refs, messageId, fleetId) {
|
|
158
|
+
const bind = db.prepare("UPDATE hub_attachments SET state='bound', message_id=?, fleet_id=?, position=?, expires_at=NULL WHERE id=? AND state='pending'");
|
|
159
|
+
refs.forEach((r, i) => { if (bind.run(messageId, fleetId, i, r.id).changes !== 1)
|
|
160
|
+
throw new HubProtocolError("conflict"); });
|
|
161
|
+
}
|
|
162
|
+
/** A message's files in one direction, in order. */
|
|
163
|
+
forMessage(db, messageId, direction) {
|
|
164
|
+
return db.prepare("SELECT * FROM hub_attachments WHERE message_id=? AND direction=? AND state='bound' ORDER BY position").all(messageId, direction).map(refOf);
|
|
165
|
+
}
|
|
166
|
+
row(db, id) { return db.prepare("SELECT * FROM hub_attachments WHERE id=?").get(id); }
|
|
167
|
+
/** One chunk of an answer's file from the member, in order. Returns the next offset; the last chunk checks the digest. */
|
|
168
|
+
stage(db, fleetId, c) {
|
|
169
|
+
if (c.total > this.limits.fileBytes || c.data.length === 0 || c.data.length > HUB_ATTACHMENT_CHUNK || c.offset % HUB_ATTACHMENT_CHUNK !== 0)
|
|
170
|
+
throw new HubProtocolError("invalid");
|
|
171
|
+
const done = db.prepare("SELECT * FROM hub_attachments WHERE id=?").get(c.id);
|
|
172
|
+
if (done) {
|
|
173
|
+
if (done.direction !== "answer" || done.fleet_id !== fleetId || done.sha256 !== c.sha256 || done.size !== c.total)
|
|
174
|
+
throw new HubProtocolError("conflict");
|
|
175
|
+
return { complete: true }; // a repeat after completion: the same ACK
|
|
176
|
+
}
|
|
177
|
+
const idx = c.offset / HUB_ATTACHMENT_CHUNK, last = c.offset + c.data.length === c.total;
|
|
178
|
+
if (!last && c.data.length !== HUB_ATTACHMENT_CHUNK || c.offset + c.data.length > c.total)
|
|
179
|
+
throw new HubProtocolError("invalid");
|
|
180
|
+
const prior = db.prepare("SELECT fleet_id, total, sha256, COUNT(*) AS n, MAX(idx) AS top FROM hub_attachment_staging WHERE id=?").get(c.id);
|
|
181
|
+
if (prior.n > 0 && (prior.fleet_id !== fleetId || prior.total !== c.total || prior.sha256 !== c.sha256))
|
|
182
|
+
throw new HubProtocolError("conflict");
|
|
183
|
+
const seen = db.prepare("SELECT 1 FROM hub_attachment_staging WHERE id=? AND idx=?").get(c.id, idx);
|
|
184
|
+
if (!seen) {
|
|
185
|
+
if (idx !== prior.n)
|
|
186
|
+
throw new HubProtocolError("stale"); // one chunk in flight, in order
|
|
187
|
+
if (prior.n === 0)
|
|
188
|
+
this.admit(db, { fleetId }, c.total); // a new file: within the fleet's waiting budget
|
|
189
|
+
const s = this.seal(`agend-hub-attachment-staging-v1\n${c.id}\n${idx}`, c.data);
|
|
190
|
+
db.prepare("INSERT INTO hub_attachment_staging(id, idx, fleet_id, total, sha256, nonce, ciphertext, created_at) VALUES(?,?,?,?,?,?,?,?)")
|
|
191
|
+
.run(c.id, idx, fleetId, c.total, c.sha256, s.nonce, s.body, this.now());
|
|
192
|
+
}
|
|
193
|
+
if (!last)
|
|
194
|
+
return { complete: false };
|
|
195
|
+
const parts = db.prepare("SELECT idx, nonce, ciphertext FROM hub_attachment_staging WHERE id=? ORDER BY idx").all(c.id)
|
|
196
|
+
.map(p => this.open(`agend-hub-attachment-staging-v1\n${c.id}\n${p.idx}`, p.nonce, p.ciphertext));
|
|
197
|
+
const bytes = Buffer.concat(parts);
|
|
198
|
+
db.prepare("DELETE FROM hub_attachment_staging WHERE id=?").run(c.id);
|
|
199
|
+
// A file that does not match its digest is discarded — returned, not thrown, so the caller's transaction keeps the delete.
|
|
200
|
+
if (bytes.length !== c.total || sha(bytes) !== c.sha256)
|
|
201
|
+
return { complete: false, discarded: true };
|
|
202
|
+
this.storeBlob(db, bytes);
|
|
203
|
+
// Name and type are unknown until the answer names this file: placeholders, checked and filled at bind.
|
|
204
|
+
db.prepare(`INSERT INTO hub_attachments(id, sha256, name, size, mime, direction, state, fleet_id, created_at, expires_at)
|
|
205
|
+
VALUES(?,?,'',?,'','answer','staged',?,?,?)`).run(c.id, c.sha256, c.total, fleetId, this.now(), this.now() + STAGING_TTL_MS);
|
|
206
|
+
return { complete: true };
|
|
207
|
+
}
|
|
208
|
+
/** Bind an answer's files: each must be a complete file this fleet sent, matching the ref's digest and size; its
|
|
209
|
+
* name decides its type and an image must carry its magic bytes, exactly as for an asker's upload. */
|
|
210
|
+
bindAnswer(db, refs, messageId, roomId, fleetId) {
|
|
211
|
+
if (refs.length > this.limits.files || refs.reduce((n, r) => n + r.size, 0) > this.limits.messageBytes)
|
|
212
|
+
throw new HubProtocolError("invalid");
|
|
213
|
+
refs.forEach((r, i) => {
|
|
214
|
+
const row = db.prepare("SELECT * FROM hub_attachments WHERE id=?").get(r.id);
|
|
215
|
+
if (!row || row.direction !== "answer" || row.fleet_id !== fleetId || row.sha256 !== r.sha256 || row.size !== r.size)
|
|
216
|
+
throw new HubProtocolError("not-found");
|
|
217
|
+
if (row.state === "bound") {
|
|
218
|
+
if (row.message_id !== messageId || row.position !== i || row.name !== r.name || row.mime !== r.mime)
|
|
219
|
+
throw new HubProtocolError("conflict");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if ((row.expires_at ?? 0) <= this.now())
|
|
223
|
+
throw new HubProtocolError("expired"); // never resurrected by a late answer
|
|
224
|
+
const kind = classifyAttachment(r.name, this.chunk(db, r.sha256, 0).data.subarray(0, 64));
|
|
225
|
+
if ("refused" in kind || kind.mime !== r.mime)
|
|
226
|
+
throw new HubProtocolError("invalid");
|
|
227
|
+
db.prepare("UPDATE hub_attachments SET state='bound', name=?, mime=?, message_id=?, room_id=?, position=?, expires_at=NULL WHERE id=? AND state='staged'")
|
|
228
|
+
.run(r.name, r.mime, messageId, roomId, i, r.id);
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
/** Retention: bound files older than `contentCut`, expired uploads and staging, then blobs nothing uses. */
|
|
232
|
+
purge(db, contentCut) {
|
|
233
|
+
const now = this.now();
|
|
234
|
+
const files = db.prepare("DELETE FROM hub_attachments WHERE created_at < ? OR (state <> 'bound' AND expires_at IS NOT NULL AND expires_at <= ?)").run(contentCut, now).changes;
|
|
235
|
+
db.prepare("DELETE FROM hub_attachment_staging WHERE created_at <= ?").run(now - STAGING_TTL_MS);
|
|
236
|
+
return { files, blobs: this.dropOrphans(db) };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
export class HubAttachmentRefused extends HubProtocolError {
|
|
240
|
+
refusal;
|
|
241
|
+
constructor(refusal) {
|
|
242
|
+
super("invalid");
|
|
243
|
+
this.refusal = refusal;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/hub/attachments/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S5b audit (S-51; docs/design/hub-composition.md §4). One hash-chained table per database (the Hub's, or a member's
|
|
3
|
+
* own), written synchronously inside the caller's transaction: if the append fails, the caller's transaction aborts,
|
|
4
|
+
* so nothing is accepted, disclosed or reported as changed without its record.
|
|
5
|
+
*
|
|
6
|
+
* - `sequence` is S5's own monotonic key; a caller's record.sequence (S1's store revision) is kept as component_sequence.
|
|
7
|
+
* - Question/answer text lives in hub_audit_content, AES-256-GCM under content.key; S5 generates every ref.
|
|
8
|
+
* - Reads: only the asked owner (owner_at_event) or an assigned auditor; every read appends its own record first.
|
|
9
|
+
* - Retention deletes a contiguous prefix of events and old content, keeping a checkpoint so the chain still verifies.
|
|
10
|
+
*/
|
|
11
|
+
import type Database from "better-sqlite3";
|
|
12
|
+
import { type HubMigration } from "../db.js";
|
|
13
|
+
import type { HubAuditRecord, HubAuditSink, HubTx, PersonKey } from "../types.js";
|
|
14
|
+
export declare const HUB_AUDIT_MIGRATION: HubMigration;
|
|
15
|
+
export declare class HubAuditAccessError extends Error {
|
|
16
|
+
constructor(message?: string);
|
|
17
|
+
}
|
|
18
|
+
export interface HubContentPayload {
|
|
19
|
+
question?: string;
|
|
20
|
+
answer?: string;
|
|
21
|
+
buttons?: import("../types.js").HubAnswerButtons;
|
|
22
|
+
pollBallot?: import("../types.js").HubPollBallot;
|
|
23
|
+
}
|
|
24
|
+
export interface HubContentStore {
|
|
25
|
+
/** Encrypt and store inside `tx`; returns the S5-generated ref to use as the record's contentRef. */
|
|
26
|
+
put(tx: HubTx, payload: HubContentPayload): string;
|
|
27
|
+
/** For S3's own room projection after its audience check. undefined once retention removed it. */
|
|
28
|
+
get(ref: string): HubContentPayload | undefined;
|
|
29
|
+
}
|
|
30
|
+
export interface HubAuditStore extends HubAuditSink {
|
|
31
|
+
/** S1's store bridge: append inside the caller's own transaction on this exact database. */
|
|
32
|
+
appendInTransaction(record: HubAuditRecord, database: Database.Database): void;
|
|
33
|
+
readonly content: HubContentStore;
|
|
34
|
+
/** Walk the chain from the latest checkpoint; reports the first sequence whose hash does not match. */
|
|
35
|
+
verifyChain(): {
|
|
36
|
+
ok: true;
|
|
37
|
+
checked: number;
|
|
38
|
+
} | {
|
|
39
|
+
ok: false;
|
|
40
|
+
sequence: number;
|
|
41
|
+
};
|
|
42
|
+
/** Assign or remove a security auditor (the change is itself audited, inside the same transaction). */
|
|
43
|
+
setAuditor(tx: HubTx, person: PersonKey, assigned: boolean, by: HubAuditRecord["actor"], requestId: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Apply retention: content older than contentDays; a contiguous prefix of events older than eventDays, stopping at
|
|
46
|
+
* the first one `retained` keeps (unresolved dedup/revocation evidence).
|
|
47
|
+
*/
|
|
48
|
+
purge(retention: {
|
|
49
|
+
contentDays: number;
|
|
50
|
+
eventDays: number;
|
|
51
|
+
}, retained?: (record: HubAuditRecord) => boolean): {
|
|
52
|
+
content: number;
|
|
53
|
+
events: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export interface HubAuditOptions {
|
|
57
|
+
db: Database.Database;
|
|
58
|
+
/** 32 random bytes from the private content key file. */
|
|
59
|
+
contentKey: Buffer;
|
|
60
|
+
now?: () => number;
|
|
61
|
+
}
|
|
62
|
+
export declare function createHubAudit(options: HubAuditOptions): HubAuditStore;
|