openryoko 2026.10.8 → 2026.10.13
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/dist/bin/jimmy.js +51 -1
- package/dist/bin/jimmy.js.map +1 -1
- package/dist/package.json +2 -1
- package/dist/src/backup/archive.d.ts +65 -0
- package/dist/src/backup/archive.d.ts.map +1 -0
- package/dist/src/backup/archive.js +214 -0
- package/dist/src/backup/archive.js.map +1 -0
- package/dist/src/backup/catalog.d.ts +64 -0
- package/dist/src/backup/catalog.d.ts.map +1 -0
- package/dist/src/backup/catalog.js +252 -0
- package/dist/src/backup/catalog.js.map +1 -0
- package/dist/src/backup/database-restore.d.ts +63 -0
- package/dist/src/backup/database-restore.d.ts.map +1 -0
- package/dist/src/backup/database-restore.js +236 -0
- package/dist/src/backup/database-restore.js.map +1 -0
- package/dist/src/backup/database-source.d.ts +70 -0
- package/dist/src/backup/database-source.d.ts.map +1 -0
- package/dist/src/backup/database-source.js +70 -0
- package/dist/src/backup/database-source.js.map +1 -0
- package/dist/src/backup/format.d.ts +4 -0
- package/dist/src/backup/format.d.ts.map +1 -0
- package/dist/src/backup/format.js +15 -0
- package/dist/src/backup/format.js.map +1 -0
- package/dist/src/backup/gateway-liveness.d.ts +44 -0
- package/dist/src/backup/gateway-liveness.d.ts.map +1 -0
- package/dist/src/backup/gateway-liveness.js +120 -0
- package/dist/src/backup/gateway-liveness.js.map +1 -0
- package/dist/src/backup/inspect.d.ts +45 -0
- package/dist/src/backup/inspect.d.ts.map +1 -0
- package/dist/src/backup/inspect.js +291 -0
- package/dist/src/backup/inspect.js.map +1 -0
- package/dist/src/backup/layout.d.ts +11 -0
- package/dist/src/backup/layout.d.ts.map +1 -0
- package/dist/src/backup/layout.js +16 -0
- package/dist/src/backup/layout.js.map +1 -0
- package/dist/src/backup/limits.d.ts +54 -0
- package/dist/src/backup/limits.d.ts.map +1 -0
- package/dist/src/backup/limits.js +59 -0
- package/dist/src/backup/limits.js.map +1 -0
- package/dist/src/backup/manifest.d.ts +45 -0
- package/dist/src/backup/manifest.d.ts.map +1 -0
- package/dist/src/backup/manifest.js +77 -0
- package/dist/src/backup/manifest.js.map +1 -0
- package/dist/src/backup/restore.d.ts +73 -0
- package/dist/src/backup/restore.d.ts.map +1 -0
- package/dist/src/backup/restore.js +685 -0
- package/dist/src/backup/restore.js.map +1 -0
- package/dist/src/backup/run.d.ts +76 -0
- package/dist/src/backup/run.d.ts.map +1 -0
- package/dist/src/backup/run.js +181 -0
- package/dist/src/backup/run.js.map +1 -0
- package/dist/src/backup/scheduler.d.ts +51 -0
- package/dist/src/backup/scheduler.d.ts.map +1 -0
- package/dist/src/backup/scheduler.js +198 -0
- package/dist/src/backup/scheduler.js.map +1 -0
- package/dist/src/backup/settings.d.ts +44 -0
- package/dist/src/backup/settings.d.ts.map +1 -0
- package/dist/src/backup/settings.js +91 -0
- package/dist/src/backup/settings.js.map +1 -0
- package/dist/src/backup/space.d.ts +22 -0
- package/dist/src/backup/space.d.ts.map +1 -0
- package/dist/src/backup/space.js +47 -0
- package/dist/src/backup/space.js.map +1 -0
- package/dist/src/backup/state.d.ts +46 -0
- package/dist/src/backup/state.d.ts.map +1 -0
- package/dist/src/backup/state.js +137 -0
- package/dist/src/backup/state.js.map +1 -0
- package/dist/src/backup/tar.d.ts +64 -0
- package/dist/src/backup/tar.d.ts.map +1 -0
- package/dist/src/backup/tar.js +274 -0
- package/dist/src/backup/tar.js.map +1 -0
- package/dist/src/backup/targets.d.ts +85 -0
- package/dist/src/backup/targets.d.ts.map +1 -0
- package/dist/src/backup/targets.js +104 -0
- package/dist/src/backup/targets.js.map +1 -0
- package/dist/src/backup/walk.d.ts +42 -0
- package/dist/src/backup/walk.d.ts.map +1 -0
- package/dist/src/backup/walk.js +324 -0
- package/dist/src/backup/walk.js.map +1 -0
- package/dist/src/cli/backup.d.ts +45 -0
- package/dist/src/cli/backup.d.ts.map +1 -0
- package/dist/src/cli/backup.js +344 -0
- package/dist/src/cli/backup.js.map +1 -0
- package/dist/src/cli/bundled-skills.d.ts +7 -1
- package/dist/src/cli/bundled-skills.d.ts.map +1 -1
- package/dist/src/cli/bundled-skills.js +12 -2
- package/dist/src/cli/bundled-skills.js.map +1 -1
- package/dist/src/cli/config-failure.d.ts +18 -0
- package/dist/src/cli/config-failure.d.ts.map +1 -0
- package/dist/src/cli/config-failure.js +39 -0
- package/dist/src/cli/config-failure.js.map +1 -0
- package/dist/src/cli/gateway-audit.d.ts +3 -0
- package/dist/src/cli/gateway-audit.d.ts.map +1 -1
- package/dist/src/cli/gateway-audit.js +61 -14
- package/dist/src/cli/gateway-audit.js.map +1 -1
- package/dist/src/cli/gateway-url-backup.d.ts +21 -0
- package/dist/src/cli/gateway-url-backup.d.ts.map +1 -0
- package/dist/src/cli/gateway-url-backup.js +87 -0
- package/dist/src/cli/gateway-url-backup.js.map +1 -0
- package/dist/src/cli/home-copy.d.ts +37 -0
- package/dist/src/cli/home-copy.d.ts.map +1 -0
- package/dist/src/cli/home-copy.js +155 -0
- package/dist/src/cli/home-copy.js.map +1 -0
- package/dist/src/cli/interactive-config.d.ts +5 -0
- package/dist/src/cli/interactive-config.d.ts.map +1 -1
- package/dist/src/cli/interactive-config.js +16 -7
- package/dist/src/cli/interactive-config.js.map +1 -1
- package/dist/src/cli/migrate.d.ts +20 -0
- package/dist/src/cli/migrate.d.ts.map +1 -1
- package/dist/src/cli/migrate.js +365 -68
- package/dist/src/cli/migrate.js.map +1 -1
- package/dist/src/cli/migration-declarations.d.ts +24 -0
- package/dist/src/cli/migration-declarations.d.ts.map +1 -0
- package/dist/src/cli/migration-declarations.js +54 -0
- package/dist/src/cli/migration-declarations.js.map +1 -0
- package/dist/src/cli/start.d.ts.map +1 -1
- package/dist/src/cli/start.js +40 -1
- package/dist/src/cli/start.js.map +1 -1
- package/dist/src/connectors/chunked-send.d.ts +27 -0
- package/dist/src/connectors/chunked-send.d.ts.map +1 -0
- package/dist/src/connectors/chunked-send.js +40 -0
- package/dist/src/connectors/chunked-send.js.map +1 -0
- package/dist/src/connectors/cron/index.d.ts +10 -0
- package/dist/src/connectors/cron/index.d.ts.map +1 -1
- package/dist/src/connectors/cron/index.js +26 -3
- package/dist/src/connectors/cron/index.js.map +1 -1
- package/dist/src/connectors/discord/attachments.d.ts +25 -0
- package/dist/src/connectors/discord/attachments.d.ts.map +1 -0
- package/dist/src/connectors/discord/attachments.js +33 -0
- package/dist/src/connectors/discord/attachments.js.map +1 -0
- package/dist/src/connectors/discord/format.d.ts +17 -1
- package/dist/src/connectors/discord/format.d.ts.map +1 -1
- package/dist/src/connectors/discord/format.js +36 -6
- package/dist/src/connectors/discord/format.js.map +1 -1
- package/dist/src/connectors/discord/index.d.ts +12 -0
- package/dist/src/connectors/discord/index.d.ts.map +1 -1
- package/dist/src/connectors/discord/index.js +47 -40
- package/dist/src/connectors/discord/index.js.map +1 -1
- package/dist/src/connectors/discord/remote.d.ts +45 -1
- package/dist/src/connectors/discord/remote.d.ts.map +1 -1
- package/dist/src/connectors/discord/remote.js +147 -22
- package/dist/src/connectors/discord/remote.js.map +1 -1
- package/dist/src/connectors/slack/attachments.d.ts +25 -0
- package/dist/src/connectors/slack/attachments.d.ts.map +1 -0
- package/dist/src/connectors/slack/attachments.js +32 -0
- package/dist/src/connectors/slack/attachments.js.map +1 -0
- package/dist/src/connectors/slack/auth-test-cache.d.ts +22 -0
- package/dist/src/connectors/slack/auth-test-cache.d.ts.map +1 -0
- package/dist/src/connectors/slack/auth-test-cache.js +34 -0
- package/dist/src/connectors/slack/auth-test-cache.js.map +1 -0
- package/dist/src/connectors/slack/format.d.ts +6 -1
- package/dist/src/connectors/slack/format.d.ts.map +1 -1
- package/dist/src/connectors/slack/format.js +65 -13
- package/dist/src/connectors/slack/format.js.map +1 -1
- package/dist/src/connectors/slack/index.d.ts +4 -0
- package/dist/src/connectors/slack/index.d.ts.map +1 -1
- package/dist/src/connectors/slack/index.js +64 -52
- package/dist/src/connectors/slack/index.js.map +1 -1
- package/dist/src/connectors/slack/provider-auth-blocks.d.ts +62 -0
- package/dist/src/connectors/slack/provider-auth-blocks.d.ts.map +1 -0
- package/dist/src/connectors/slack/provider-auth-blocks.js +204 -0
- package/dist/src/connectors/slack/provider-auth-blocks.js.map +1 -0
- package/dist/src/connectors/slack/provider-auth.d.ts +126 -0
- package/dist/src/connectors/slack/provider-auth.d.ts.map +1 -0
- package/dist/src/connectors/slack/provider-auth.js +357 -0
- package/dist/src/connectors/slack/provider-auth.js.map +1 -0
- package/dist/src/connectors/telegram/index.d.ts +5 -0
- package/dist/src/connectors/telegram/index.d.ts.map +1 -1
- package/dist/src/connectors/telegram/index.js +14 -22
- package/dist/src/connectors/telegram/index.js.map +1 -1
- package/dist/src/connectors/whatsapp/index.d.ts +3 -0
- package/dist/src/connectors/whatsapp/index.d.ts.map +1 -1
- package/dist/src/connectors/whatsapp/index.js +33 -14
- package/dist/src/connectors/whatsapp/index.js.map +1 -1
- package/dist/src/cron/alert-throttle.d.ts +28 -0
- package/dist/src/cron/alert-throttle.d.ts.map +1 -0
- package/dist/src/cron/alert-throttle.js +106 -0
- package/dist/src/cron/alert-throttle.js.map +1 -0
- package/dist/src/cron/jobs.d.ts +8 -0
- package/dist/src/cron/jobs.d.ts.map +1 -1
- package/dist/src/cron/jobs.js +27 -1
- package/dist/src/cron/jobs.js.map +1 -1
- package/dist/src/cron/run-outcome.d.ts +28 -0
- package/dist/src/cron/run-outcome.d.ts.map +1 -0
- package/dist/src/cron/run-outcome.js +66 -0
- package/dist/src/cron/run-outcome.js.map +1 -0
- package/dist/src/cron/runner.d.ts.map +1 -1
- package/dist/src/cron/runner.js +68 -5
- package/dist/src/cron/runner.js.map +1 -1
- package/dist/src/cron/scheduler.d.ts +8 -1
- package/dist/src/cron/scheduler.d.ts.map +1 -1
- package/dist/src/cron/scheduler.js +11 -4
- package/dist/src/cron/scheduler.js.map +1 -1
- package/dist/src/cron/waiting-fires.d.ts +18 -0
- package/dist/src/cron/waiting-fires.d.ts.map +1 -0
- package/dist/src/cron/waiting-fires.js +49 -0
- package/dist/src/cron/waiting-fires.js.map +1 -0
- package/dist/src/engines/claude-interactive.d.ts +19 -3
- package/dist/src/engines/claude-interactive.d.ts.map +1 -1
- package/dist/src/engines/claude-interactive.js +42 -17
- package/dist/src/engines/claude-interactive.js.map +1 -1
- package/dist/src/engines/claude.d.ts.map +1 -1
- package/dist/src/engines/claude.js +38 -5
- package/dist/src/engines/claude.js.map +1 -1
- package/dist/src/engines/codex.d.ts.map +1 -1
- package/dist/src/engines/codex.js +1 -0
- package/dist/src/engines/codex.js.map +1 -1
- package/dist/src/engines/gemini.d.ts.map +1 -1
- package/dist/src/engines/gemini.js +1 -0
- package/dist/src/engines/gemini.js.map +1 -1
- package/dist/src/gateway/api.d.ts.map +1 -1
- package/dist/src/gateway/api.js +184 -160
- package/dist/src/gateway/api.js.map +1 -1
- package/dist/src/gateway/config-redaction.d.ts +32 -0
- package/dist/src/gateway/config-redaction.d.ts.map +1 -0
- package/dist/src/gateway/config-redaction.js +139 -0
- package/dist/src/gateway/config-redaction.js.map +1 -0
- package/dist/src/gateway/config-revision.d.ts +46 -0
- package/dist/src/gateway/config-revision.d.ts.map +1 -0
- package/dist/src/gateway/config-revision.js +63 -0
- package/dist/src/gateway/config-revision.js.map +1 -0
- package/dist/src/gateway/connector-config.d.ts +21 -0
- package/dist/src/gateway/connector-config.d.ts.map +1 -0
- package/dist/src/gateway/connector-config.js +24 -0
- package/dist/src/gateway/connector-config.js.map +1 -0
- package/dist/src/gateway/daemon-entry.js +5 -0
- package/dist/src/gateway/daemon-entry.js.map +1 -1
- package/dist/src/gateway/engine-health-monitor.d.ts +67 -0
- package/dist/src/gateway/engine-health-monitor.d.ts.map +1 -0
- package/dist/src/gateway/engine-health-monitor.js +221 -0
- package/dist/src/gateway/engine-health-monitor.js.map +1 -0
- package/dist/src/gateway/files.d.ts +7 -1
- package/dist/src/gateway/files.d.ts.map +1 -1
- package/dist/src/gateway/files.js +110 -217
- package/dist/src/gateway/files.js.map +1 -1
- package/dist/src/gateway/onboarding-personalize.d.ts +2 -0
- package/dist/src/gateway/onboarding-personalize.d.ts.map +1 -1
- package/dist/src/gateway/onboarding-personalize.js +17 -1
- package/dist/src/gateway/onboarding-personalize.js.map +1 -1
- package/dist/src/gateway/portal-config.d.ts +17 -3
- package/dist/src/gateway/portal-config.d.ts.map +1 -1
- package/dist/src/gateway/portal-config.js +52 -3
- package/dist/src/gateway/portal-config.js.map +1 -1
- package/dist/src/gateway/request-origin.d.ts +9 -0
- package/dist/src/gateway/request-origin.d.ts.map +1 -1
- package/dist/src/gateway/request-origin.js +10 -0
- package/dist/src/gateway/request-origin.js.map +1 -1
- package/dist/src/gateway/server.d.ts.map +1 -1
- package/dist/src/gateway/server.js +82 -59
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/slack-connect-rollback.d.ts +23 -0
- package/dist/src/gateway/slack-connect-rollback.d.ts.map +1 -0
- package/dist/src/gateway/slack-connect-rollback.js +53 -0
- package/dist/src/gateway/slack-connect-rollback.js.map +1 -0
- package/dist/src/gateway/status-reconciler.d.ts +25 -7
- package/dist/src/gateway/status-reconciler.d.ts.map +1 -1
- package/dist/src/gateway/status-reconciler.js +86 -43
- package/dist/src/gateway/status-reconciler.js.map +1 -1
- package/dist/src/gateway/watcher.d.ts.map +1 -1
- package/dist/src/gateway/watcher.js +44 -3
- package/dist/src/gateway/watcher.js.map +1 -1
- package/dist/src/mcp/gateway-server.js +21 -3
- package/dist/src/mcp/gateway-server.js.map +1 -1
- package/dist/src/mcp/resolver.d.ts.map +1 -1
- package/dist/src/mcp/resolver.js +51 -1
- package/dist/src/mcp/resolver.js.map +1 -1
- package/dist/src/models/service.d.ts.map +1 -1
- package/dist/src/models/service.js +14 -8
- package/dist/src/models/service.js.map +1 -1
- package/dist/src/provider-auth/discovery.d.ts +16 -0
- package/dist/src/provider-auth/discovery.d.ts.map +1 -0
- package/dist/src/provider-auth/discovery.js +66 -0
- package/dist/src/provider-auth/discovery.js.map +1 -0
- package/dist/src/provider-auth/failure-notices.d.ts +29 -0
- package/dist/src/provider-auth/failure-notices.d.ts.map +1 -0
- package/dist/src/provider-auth/failure-notices.js +48 -0
- package/dist/src/provider-auth/failure-notices.js.map +1 -0
- package/dist/src/provider-auth/failure-signal.d.ts +22 -0
- package/dist/src/provider-auth/failure-signal.d.ts.map +1 -0
- package/dist/src/provider-auth/failure-signal.js +79 -0
- package/dist/src/provider-auth/failure-signal.js.map +1 -0
- package/dist/src/provider-auth/index.d.ts +26 -0
- package/dist/src/provider-auth/index.d.ts.map +1 -0
- package/dist/src/provider-auth/index.js +51 -0
- package/dist/src/provider-auth/index.js.map +1 -0
- package/dist/src/provider-auth/input.d.ts +44 -0
- package/dist/src/provider-auth/input.d.ts.map +1 -0
- package/dist/src/provider-auth/input.js +86 -0
- package/dist/src/provider-auth/input.js.map +1 -0
- package/dist/src/provider-auth/providers.d.ts +26 -0
- package/dist/src/provider-auth/providers.d.ts.map +1 -0
- package/dist/src/provider-auth/providers.js +86 -0
- package/dist/src/provider-auth/providers.js.map +1 -0
- package/dist/src/provider-auth/runtime.d.ts +21 -0
- package/dist/src/provider-auth/runtime.d.ts.map +1 -0
- package/dist/src/provider-auth/runtime.js +104 -0
- package/dist/src/provider-auth/runtime.js.map +1 -0
- package/dist/src/provider-auth/service.d.ts +70 -0
- package/dist/src/provider-auth/service.d.ts.map +1 -0
- package/dist/src/provider-auth/service.js +349 -0
- package/dist/src/provider-auth/service.js.map +1 -0
- package/dist/src/provider-auth/terminal.d.ts +21 -0
- package/dist/src/provider-auth/terminal.d.ts.map +1 -0
- package/dist/src/provider-auth/terminal.js +46 -0
- package/dist/src/provider-auth/terminal.js.map +1 -0
- package/dist/src/provider-auth/types.d.ts +123 -0
- package/dist/src/provider-auth/types.d.ts.map +1 -0
- package/dist/src/provider-auth/types.js +10 -0
- package/dist/src/provider-auth/types.js.map +1 -0
- package/dist/src/sessions/accounting.d.ts +3 -0
- package/dist/src/sessions/accounting.d.ts.map +1 -1
- package/dist/src/sessions/accounting.js +5 -0
- package/dist/src/sessions/accounting.js.map +1 -1
- package/dist/src/sessions/backup-integrity.d.ts +45 -0
- package/dist/src/sessions/backup-integrity.d.ts.map +1 -0
- package/dist/src/sessions/backup-integrity.js +122 -0
- package/dist/src/sessions/backup-integrity.js.map +1 -0
- package/dist/src/sessions/backup.d.ts +40 -2
- package/dist/src/sessions/backup.d.ts.map +1 -1
- package/dist/src/sessions/backup.js +88 -12
- package/dist/src/sessions/backup.js.map +1 -1
- package/dist/src/sessions/callbacks.d.ts +9 -0
- package/dist/src/sessions/callbacks.d.ts.map +1 -1
- package/dist/src/sessions/callbacks.js +55 -10
- package/dist/src/sessions/callbacks.js.map +1 -1
- package/dist/src/sessions/completion-batching.d.ts +82 -0
- package/dist/src/sessions/completion-batching.d.ts.map +1 -0
- package/dist/src/sessions/completion-batching.js +126 -0
- package/dist/src/sessions/completion-batching.js.map +1 -0
- package/dist/src/sessions/connector-command-guard.d.ts +66 -0
- package/dist/src/sessions/connector-command-guard.d.ts.map +1 -0
- package/dist/src/sessions/connector-command-guard.js +145 -0
- package/dist/src/sessions/connector-command-guard.js.map +1 -0
- package/dist/src/sessions/context.d.ts.map +1 -1
- package/dist/src/sessions/context.js +3 -4
- package/dist/src/sessions/context.js.map +1 -1
- package/dist/src/sessions/engine-fallback.d.ts +43 -1
- package/dist/src/sessions/engine-fallback.d.ts.map +1 -1
- package/dist/src/sessions/engine-fallback.js +266 -15
- package/dist/src/sessions/engine-fallback.js.map +1 -1
- package/dist/src/sessions/engine-health-gate.d.ts +83 -0
- package/dist/src/sessions/engine-health-gate.d.ts.map +1 -0
- package/dist/src/sessions/engine-health-gate.js +186 -0
- package/dist/src/sessions/engine-health-gate.js.map +1 -0
- package/dist/src/sessions/engine-login.d.ts +58 -0
- package/dist/src/sessions/engine-login.d.ts.map +1 -0
- package/dist/src/sessions/engine-login.js +107 -0
- package/dist/src/sessions/engine-login.js.map +1 -0
- package/dist/src/sessions/fork.d.ts.map +1 -1
- package/dist/src/sessions/fork.js +3 -1
- package/dist/src/sessions/fork.js.map +1 -1
- package/dist/src/sessions/goal-execution.d.ts.map +1 -1
- package/dist/src/sessions/goal-execution.js +8 -1
- package/dist/src/sessions/goal-execution.js.map +1 -1
- package/dist/src/sessions/limit-failure-notice.d.ts +41 -0
- package/dist/src/sessions/limit-failure-notice.d.ts.map +1 -0
- package/dist/src/sessions/limit-failure-notice.js +87 -0
- package/dist/src/sessions/limit-failure-notice.js.map +1 -0
- package/dist/src/sessions/lost-turn.d.ts +39 -0
- package/dist/src/sessions/lost-turn.d.ts.map +1 -0
- package/dist/src/sessions/lost-turn.js +32 -0
- package/dist/src/sessions/lost-turn.js.map +1 -0
- package/dist/src/sessions/manager.d.ts.map +1 -1
- package/dist/src/sessions/manager.js +104 -47
- package/dist/src/sessions/manager.js.map +1 -1
- package/dist/src/sessions/new-session-engine.d.ts +42 -0
- package/dist/src/sessions/new-session-engine.d.ts.map +1 -0
- package/dist/src/sessions/new-session-engine.js +100 -0
- package/dist/src/sessions/new-session-engine.js.map +1 -0
- package/dist/src/sessions/origin-delivery.d.ts +50 -4
- package/dist/src/sessions/origin-delivery.d.ts.map +1 -1
- package/dist/src/sessions/origin-delivery.js +108 -9
- package/dist/src/sessions/origin-delivery.js.map +1 -1
- package/dist/src/sessions/queue.d.ts +14 -0
- package/dist/src/sessions/queue.d.ts.map +1 -1
- package/dist/src/sessions/queue.js +38 -2
- package/dist/src/sessions/queue.js.map +1 -1
- package/dist/src/sessions/registry.d.ts +4 -2
- package/dist/src/sessions/registry.d.ts.map +1 -1
- package/dist/src/sessions/registry.js +21 -4
- package/dist/src/sessions/registry.js.map +1 -1
- package/dist/src/sessions/reply-disposition.d.ts +8 -0
- package/dist/src/sessions/reply-disposition.d.ts.map +1 -1
- package/dist/src/sessions/reply-disposition.js +8 -0
- package/dist/src/sessions/reply-disposition.js.map +1 -1
- package/dist/src/sessions/restart-resume.d.ts +234 -0
- package/dist/src/sessions/restart-resume.d.ts.map +1 -0
- package/dist/src/sessions/restart-resume.js +596 -0
- package/dist/src/sessions/restart-resume.js.map +1 -0
- package/dist/src/sessions/speaker-prefix.d.ts.map +1 -1
- package/dist/src/sessions/speaker-prefix.js +3 -1
- package/dist/src/sessions/speaker-prefix.js.map +1 -1
- package/dist/src/sessions/turn-delivery.d.ts +26 -0
- package/dist/src/sessions/turn-delivery.d.ts.map +1 -0
- package/dist/src/sessions/turn-delivery.js +34 -0
- package/dist/src/sessions/turn-delivery.js.map +1 -0
- package/dist/src/sessions/unrequested-stop.d.ts +26 -0
- package/dist/src/sessions/unrequested-stop.d.ts.map +1 -0
- package/dist/src/sessions/unrequested-stop.js +19 -0
- package/dist/src/sessions/unrequested-stop.js.map +1 -0
- package/dist/src/sessions/usage-limit-wait.d.ts +14 -0
- package/dist/src/sessions/usage-limit-wait.d.ts.map +1 -0
- package/dist/src/sessions/usage-limit-wait.js +9 -0
- package/dist/src/sessions/usage-limit-wait.js.map +1 -0
- package/dist/src/shared/attachment-download.d.ts +41 -0
- package/dist/src/shared/attachment-download.d.ts.map +1 -0
- package/dist/src/shared/attachment-download.js +110 -0
- package/dist/src/shared/attachment-download.js.map +1 -0
- package/dist/src/shared/attachment-notice.d.ts +24 -0
- package/dist/src/shared/attachment-notice.d.ts.map +1 -0
- package/dist/src/shared/attachment-notice.js +37 -0
- package/dist/src/shared/attachment-notice.js.map +1 -0
- package/dist/src/shared/attachments.d.ts +65 -0
- package/dist/src/shared/attachments.d.ts.map +1 -0
- package/dist/src/shared/attachments.js +153 -0
- package/dist/src/shared/attachments.js.map +1 -0
- package/dist/src/shared/childEnv.d.ts +15 -0
- package/dist/src/shared/childEnv.d.ts.map +1 -1
- package/dist/src/shared/childEnv.js +15 -0
- package/dist/src/shared/childEnv.js.map +1 -1
- package/dist/src/shared/claude-auto-memory.d.ts +33 -0
- package/dist/src/shared/claude-auto-memory.d.ts.map +1 -0
- package/dist/src/shared/claude-auto-memory.js +156 -0
- package/dist/src/shared/claude-auto-memory.js.map +1 -0
- package/dist/src/shared/claude-limit-reset.d.ts +54 -0
- package/dist/src/shared/claude-limit-reset.d.ts.map +1 -0
- package/dist/src/shared/claude-limit-reset.js +99 -0
- package/dist/src/shared/claude-limit-reset.js.map +1 -0
- package/dist/src/shared/config-error.d.ts +21 -0
- package/dist/src/shared/config-error.d.ts.map +1 -0
- package/dist/src/shared/config-error.js +37 -0
- package/dist/src/shared/config-error.js.map +1 -0
- package/dist/src/shared/config-file.d.ts +57 -0
- package/dist/src/shared/config-file.d.ts.map +1 -0
- package/dist/src/shared/config-file.js +217 -0
- package/dist/src/shared/config-file.js.map +1 -0
- package/dist/src/shared/config-yaml-edit.d.ts +20 -0
- package/dist/src/shared/config-yaml-edit.d.ts.map +1 -0
- package/dist/src/shared/config-yaml-edit.js +468 -0
- package/dist/src/shared/config-yaml-edit.js.map +1 -0
- package/dist/src/shared/config.d.ts.map +1 -1
- package/dist/src/shared/config.js +12 -4
- package/dist/src/shared/config.js.map +1 -1
- package/dist/src/shared/engine-fallback.d.ts +22 -0
- package/dist/src/shared/engine-fallback.d.ts.map +1 -1
- package/dist/src/shared/engine-fallback.js +55 -4
- package/dist/src/shared/engine-fallback.js.map +1 -1
- package/dist/src/shared/engine-health.d.ts +16 -0
- package/dist/src/shared/engine-health.d.ts.map +1 -1
- package/dist/src/shared/engine-health.js +42 -0
- package/dist/src/shared/engine-health.js.map +1 -1
- package/dist/src/shared/list-alignment.d.ts +23 -0
- package/dist/src/shared/list-alignment.d.ts.map +1 -0
- package/dist/src/shared/list-alignment.js +61 -0
- package/dist/src/shared/list-alignment.js.map +1 -0
- package/dist/src/shared/logger.d.ts.map +1 -1
- package/dist/src/shared/logger.js +104 -33
- package/dist/src/shared/logger.js.map +1 -1
- package/dist/src/shared/map-limited.d.ts +11 -0
- package/dist/src/shared/map-limited.d.ts.map +1 -0
- package/dist/src/shared/map-limited.js +30 -0
- package/dist/src/shared/map-limited.js.map +1 -0
- package/dist/src/shared/oneShotCli.d.ts.map +1 -1
- package/dist/src/shared/oneShotCli.js +4 -2
- package/dist/src/shared/oneShotCli.js.map +1 -1
- package/dist/src/shared/partial-delivery.d.ts +24 -0
- package/dist/src/shared/partial-delivery.d.ts.map +1 -0
- package/dist/src/shared/partial-delivery.js +46 -0
- package/dist/src/shared/partial-delivery.js.map +1 -0
- package/dist/src/shared/process-safety-net.d.ts +44 -0
- package/dist/src/shared/process-safety-net.d.ts.map +1 -0
- package/dist/src/shared/process-safety-net.js +88 -0
- package/dist/src/shared/process-safety-net.js.map +1 -0
- package/dist/src/shared/rateLimit.d.ts +45 -2
- package/dist/src/shared/rateLimit.d.ts.map +1 -1
- package/dist/src/shared/rateLimit.js +64 -2
- package/dist/src/shared/rateLimit.js.map +1 -1
- package/dist/src/shared/redact.d.ts.map +1 -1
- package/dist/src/shared/redact.js +11 -1
- package/dist/src/shared/redact.js.map +1 -1
- package/dist/src/shared/safe-file-name.d.ts +9 -0
- package/dist/src/shared/safe-file-name.d.ts.map +1 -0
- package/dist/src/shared/safe-file-name.js +16 -0
- package/dist/src/shared/safe-file-name.js.map +1 -0
- package/dist/src/shared/terminal-safe-text.d.ts +2 -0
- package/dist/src/shared/terminal-safe-text.d.ts.map +1 -0
- package/dist/src/shared/terminal-safe-text.js +21 -0
- package/dist/src/shared/terminal-safe-text.js.map +1 -0
- package/dist/src/shared/types.d.ts +75 -4
- package/dist/src/shared/types.d.ts.map +1 -1
- package/dist/src/skills-sync/apply.d.ts +21 -0
- package/dist/src/skills-sync/apply.d.ts.map +1 -0
- package/dist/src/skills-sync/apply.js +209 -0
- package/dist/src/skills-sync/apply.js.map +1 -0
- package/dist/src/skills-sync/backup-run.d.ts +47 -0
- package/dist/src/skills-sync/backup-run.d.ts.map +1 -0
- package/dist/src/skills-sync/backup-run.js +150 -0
- package/dist/src/skills-sync/backup-run.js.map +1 -0
- package/dist/src/skills-sync/bounded-read.d.ts +32 -0
- package/dist/src/skills-sync/bounded-read.d.ts.map +1 -0
- package/dist/src/skills-sync/bounded-read.js +104 -0
- package/dist/src/skills-sync/bounded-read.js.map +1 -0
- package/dist/src/skills-sync/bundled.d.ts +28 -0
- package/dist/src/skills-sync/bundled.d.ts.map +1 -0
- package/dist/src/skills-sync/bundled.js +84 -0
- package/dist/src/skills-sync/bundled.js.map +1 -0
- package/dist/src/skills-sync/fingerprint.d.ts +32 -0
- package/dist/src/skills-sync/fingerprint.d.ts.map +1 -0
- package/dist/src/skills-sync/fingerprint.js +58 -0
- package/dist/src/skills-sync/fingerprint.js.map +1 -0
- package/dist/src/skills-sync/history.d.ts +44 -0
- package/dist/src/skills-sync/history.d.ts.map +1 -0
- package/dist/src/skills-sync/history.js +115 -0
- package/dist/src/skills-sync/history.js.map +1 -0
- package/dist/src/skills-sync/home-skill.d.ts +28 -0
- package/dist/src/skills-sync/home-skill.d.ts.map +1 -0
- package/dist/src/skills-sync/home-skill.js +67 -0
- package/dist/src/skills-sync/home-skill.js.map +1 -0
- package/dist/src/skills-sync/instance.d.ts +26 -0
- package/dist/src/skills-sync/instance.d.ts.map +1 -0
- package/dist/src/skills-sync/instance.js +128 -0
- package/dist/src/skills-sync/instance.js.map +1 -0
- package/dist/src/skills-sync/names.d.ts +25 -0
- package/dist/src/skills-sync/names.d.ts.map +1 -0
- package/dist/src/skills-sync/names.js +56 -0
- package/dist/src/skills-sync/names.js.map +1 -0
- package/dist/src/skills-sync/plan.d.ts +58 -0
- package/dist/src/skills-sync/plan.d.ts.map +1 -0
- package/dist/src/skills-sync/plan.js +132 -0
- package/dist/src/skills-sync/plan.js.map +1 -0
- package/dist/src/skills-sync/receipt.d.ts +61 -0
- package/dist/src/skills-sync/receipt.d.ts.map +1 -0
- package/dist/src/skills-sync/receipt.js +149 -0
- package/dist/src/skills-sync/receipt.js.map +1 -0
- package/dist/src/skills-sync/staging.d.ts +21 -0
- package/dist/src/skills-sync/staging.d.ts.map +1 -0
- package/dist/src/skills-sync/staging.js +81 -0
- package/dist/src/skills-sync/staging.js.map +1 -0
- package/dist/src/skills-sync/sync.d.ts +37 -0
- package/dist/src/skills-sync/sync.d.ts.map +1 -0
- package/dist/src/skills-sync/sync.js +201 -0
- package/dist/src/skills-sync/sync.js.map +1 -0
- package/dist/src/skills-sync/types.d.ts +66 -0
- package/dist/src/skills-sync/types.d.ts.map +1 -0
- package/dist/src/skills-sync/types.js +2 -0
- package/dist/src/skills-sync/types.js.map +1 -0
- package/dist/src/stt/config.d.ts +5 -0
- package/dist/src/stt/config.d.ts.map +1 -0
- package/dist/src/stt/config.js +18 -0
- package/dist/src/stt/config.js.map +1 -0
- package/dist/src/updates/maintenance.d.ts.map +1 -1
- package/dist/src/updates/maintenance.js +24 -4
- package/dist/src/updates/maintenance.js.map +1 -1
- package/dist/src/workflows/repository-mutex.d.ts +1 -1
- package/dist/web/404.html +1 -1
- package/dist/web/__next.__PAGE__.txt +11 -11
- package/dist/web/__next._full.txt +12 -12
- package/dist/web/__next._tree.txt +2 -2
- package/dist/web/_next/static/chunks/{0g5c5ppr8zmup.js → 20v6mri7epga5.js} +1 -1
- package/dist/web/_next/static/chunks/2u0328ngpt-ek.js +1 -0
- package/dist/web/_next/static/chunks/3f9i3f9q6v6_j.css +1 -0
- package/dist/web/_next/static/chunks/{08i7uo3uz6_fn.js → 3yy053rafgrzy.js} +1 -1
- package/dist/web/_not-found/__next._full.txt +10 -10
- package/dist/web/_not-found/__next._not-found.__PAGE__.txt +9 -9
- package/dist/web/_not-found/__next._tree.txt +2 -2
- package/dist/web/_not-found.html +1 -1
- package/dist/web/_not-found.txt +10 -10
- package/dist/web/chat/__next._full.txt +12 -12
- package/dist/web/chat/__next._tree.txt +2 -2
- package/dist/web/chat/__next.chat.__PAGE__.txt +11 -11
- package/dist/web/chat.html +1 -1
- package/dist/web/chat.txt +12 -12
- package/dist/web/cron/__next._full.txt +12 -12
- package/dist/web/cron/__next._tree.txt +2 -2
- package/dist/web/cron/__next.cron.__PAGE__.txt +11 -11
- package/dist/web/cron.html +1 -1
- package/dist/web/cron.txt +12 -12
- package/dist/web/index.html +1 -1
- package/dist/web/index.txt +12 -12
- package/dist/web/kanban/__next._full.txt +12 -12
- package/dist/web/kanban/__next._tree.txt +2 -2
- package/dist/web/kanban/__next.kanban.__PAGE__.txt +11 -11
- package/dist/web/kanban.html +1 -1
- package/dist/web/kanban.txt +12 -12
- package/dist/web/logs/__next._full.txt +12 -12
- package/dist/web/logs/__next._tree.txt +2 -2
- package/dist/web/logs/__next.logs.__PAGE__.txt +11 -11
- package/dist/web/logs.html +1 -1
- package/dist/web/logs.txt +12 -12
- package/dist/web/models/__next._full.txt +12 -12
- package/dist/web/models/__next._tree.txt +2 -2
- package/dist/web/models/__next.models.__PAGE__.txt +11 -11
- package/dist/web/models.html +1 -1
- package/dist/web/models.txt +12 -12
- package/dist/web/org/__next._full.txt +12 -12
- package/dist/web/org/__next._tree.txt +2 -2
- package/dist/web/org/__next.org.__PAGE__.txt +11 -11
- package/dist/web/org.html +1 -1
- package/dist/web/org.txt +12 -12
- package/dist/web/sessions/__next._full.txt +10 -10
- package/dist/web/sessions/__next._tree.txt +2 -2
- package/dist/web/sessions/__next.sessions.__PAGE__.txt +9 -9
- package/dist/web/sessions.html +1 -1
- package/dist/web/sessions.txt +10 -10
- package/dist/web/settings/__next._full.txt +12 -12
- package/dist/web/settings/__next._tree.txt +2 -2
- package/dist/web/settings/__next.settings.__PAGE__.txt +11 -11
- package/dist/web/settings.html +1 -1
- package/dist/web/settings.txt +12 -12
- package/dist/web/skills/__next._full.txt +12 -12
- package/dist/web/skills/__next._tree.txt +2 -2
- package/dist/web/skills/__next.skills.__PAGE__.txt +11 -11
- package/dist/web/skills.html +1 -1
- package/dist/web/skills.txt +12 -12
- package/package.json +2 -1
- package/template/AGENTS.md +48 -308
- package/template/CLAUDE.md +4 -349
- package/template/bundled-skill-history.json +377 -0
- package/template/config.default.yaml +52 -3
- package/template/docs/architecture.md +41 -3
- package/template/docs/backup.md +142 -0
- package/template/docs/connectors.md +192 -16
- package/template/docs/cron.md +30 -11
- package/template/docs/memory.md +47 -0
- package/template/docs/overview.md +6 -2
- package/template/docs/self-modification.md +11 -10
- package/template/docs/skills.md +77 -4
- package/template/migrations/0.3.0/MIGRATION.md +6 -0
- package/template/migrations/0.7.3/MIGRATION.md +6 -0
- package/template/migrations/0.7.5/MIGRATION.md +1 -1
- package/template/migrations/0.9.0/MIGRATION.md +6 -0
- package/template/migrations/2026.10.13/MIGRATION.md +76 -0
- package/template/migrations/2026.10.13/files/docs/architecture.md +112 -0
- package/template/migrations/2026.10.13/files/docs/automations.md +110 -0
- package/template/migrations/2026.10.13/files/docs/backup.md +142 -0
- package/template/migrations/2026.10.13/files/docs/connectors.md +370 -0
- package/template/migrations/2026.10.13/files/docs/cron-commands.md +52 -0
- package/template/migrations/2026.10.13/files/docs/cron.md +178 -0
- package/template/migrations/2026.10.13/files/docs/mcp.md +108 -0
- package/template/migrations/2026.10.13/files/docs/memory.md +47 -0
- package/template/migrations/2026.10.13/files/docs/org.md +111 -0
- package/template/migrations/2026.10.13/files/docs/overview.md +44 -0
- package/template/migrations/2026.10.13/files/docs/self-modification.md +71 -0
- package/template/migrations/2026.10.13/files/docs/skills.md +140 -0
- package/template/migrations/2026.10.13/files/skills/cron-manager/SKILL.md +107 -0
- package/template/migrations/2026.10.13/files/skills/management/SKILL.md +227 -0
- package/template/migrations/2026.10.13/files/skills/migrate/SKILL.md +194 -0
- package/template/migrations/2026.10.13/files/skills/onboarding/SKILL.md +153 -0
- package/template/migrations/2026.10.13/files/skills/openryoko-config/SKILL.md +35 -0
- package/template/migrations/2026.10.13/files/skills/openryoko-config/references/engine-fallback.md +98 -0
- package/template/migrations/2026.10.13/files/skills/openryoko-config/references/jev.md +89 -0
- package/template/migrations/2026.10.13/files/skills/openryoko-config/references/maintenance.md +49 -0
- package/template/migrations/2026.10.13/files/skills/openryoko-config/references/platform.md +100 -0
- package/template/migrations/2026.10.13/files/skills/self-heal/SKILL.md +187 -0
- package/template/migrations/2026.10.9/MIGRATION.md +44 -0
- package/template/migrations/2026.10.9/files/docs/memory.md +47 -0
- package/template/migrations/2026.10.9/files/skills/migrate/SKILL.md +194 -0
- package/template/migrations/2026.5.7/MIGRATION.md +6 -0
- package/template/migrations/2026.8.28/MIGRATION.md +6 -0
- package/template/migrations/2026.9.11/MIGRATION.md +6 -0
- package/template/skills/cron-manager/SKILL.md +10 -0
- package/template/skills/management/SKILL.md +5 -4
- package/template/skills/migrate/SKILL.md +47 -14
- package/template/skills/onboarding/SKILL.md +3 -3
- package/template/skills/openryoko-config/SKILL.md +1 -1
- package/template/skills/openryoko-config/references/engine-fallback.md +16 -5
- package/template/skills/openryoko-config/references/platform.md +23 -4
- package/template/skills/self-heal/SKILL.md +117 -44
- package/dist/src/engines/mock.d.ts +0 -16
- package/dist/src/engines/mock.d.ts.map +0 -1
- package/dist/src/engines/mock.js +0 -47
- package/dist/src/engines/mock.js.map +0 -1
- package/dist/src/shared/test-support/posix-mode.d.ts +0 -17
- package/dist/src/shared/test-support/posix-mode.d.ts.map +0 -1
- package/dist/src/shared/test-support/posix-mode.js +0 -23
- package/dist/src/shared/test-support/posix-mode.js.map +0 -1
- package/dist/web/_next/static/Oux0UBcCkbX5eOp9-vC4k/_buildManifest.js +0 -11
- package/dist/web/_next/static/Oux0UBcCkbX5eOp9-vC4k/_clientMiddlewareManifest.js +0 -1
- package/dist/web/_next/static/Oux0UBcCkbX5eOp9-vC4k/_ssgManifest.js +0 -1
- package/dist/web/_next/static/chunks/02h65sho8c14h.js +0 -1
- package/dist/web/_next/static/chunks/0ic18n-m7ixyw.css +0 -1
- package/dist/web/_next/static/chunks/19s8vn2kgy7q1.js +0 -1
- package/dist/web/_next/static/chunks/1_jm0szyu2the.js +0 -1
- package/dist/web/_next/static/chunks/1omdg4m5w9lgx.js +0 -1
- package/dist/web/_next/static/chunks/25nob1new8t4s.js +0 -79
- package/dist/web/_next/static/chunks/2iqxlc9wtxzm2.js +0 -1
- package/dist/web/_next/static/chunks/3_6klkygi417n.js +0 -1
- package/dist/web/_next/static/chunks/3alc-b00c58_3.css +0 -1
- /package/dist/web/_next/static/{70PNIyOj8-2kywAG6J41- → ov0mWzyHx0B5oEnTHE_pa}/_buildManifest.js +0 -0
- /package/dist/web/_next/static/{70PNIyOj8-2kywAG6J41- → ov0mWzyHx0B5oEnTHE_pa}/_clientMiddlewareManifest.js +0 -0
- /package/dist/web/_next/static/{70PNIyOj8-2kywAG6J41- → ov0mWzyHx0B5oEnTHE_pa}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-source.d.ts","sourceRoot":"","sources":["../../../src/backup/database-source.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAIhE;;;;;;;GAOG;AAEH,mDAAmD;AACnD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAEjE,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gGAAgG;AAChG,MAAM,MAAM,cAAc,GAAG,MAAM,cAAc,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAE5E,4GAA4G;AAC5G,eAAO,MAAM,sBAAsB,wBAAwB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAMnE;AAUD;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,IAAI,GAAG,MAAM,CAAC,kBAAkB,EAAE,cAAc,CAAC,CASnH"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { detectRunningGateway } from "./gateway-liveness.js";
|
|
4
|
+
import { databasePath } from "./layout.js";
|
|
5
|
+
/** The flag that asks `ryoko backup run` for the databases too. Named here because the reports quote it. */
|
|
6
|
+
export const INCLUDE_DATABASES_FLAG = "--include-databases";
|
|
7
|
+
/**
|
|
8
|
+
* Opens a database read-only for copying.
|
|
9
|
+
*
|
|
10
|
+
* Read-only is not the same as harmless, and this is only for a caller that
|
|
11
|
+
* knows who else has the file open. What a read-only connection does, traced
|
|
12
|
+
* through the SQLite this ships with and measured:
|
|
13
|
+
*
|
|
14
|
+
* - The main file is opened read-only and cannot be written. The -wal is not
|
|
15
|
+
* written, truncated or deleted either: all of that needs an exclusive lock
|
|
16
|
+
* on the main file, which a read-only descriptor cannot take. So closing it
|
|
17
|
+
* never checkpoints the WAL away, which is what a read-write connection does
|
|
18
|
+
* the moment it believes itself the last one.
|
|
19
|
+
* - The -shm (the WAL's index) is opened read-write regardless. Beside other
|
|
20
|
+
* connections it can see, this one only records where it is reading. When it
|
|
21
|
+
* sees none it takes itself for the first, truncates the -shm to three bytes
|
|
22
|
+
* and rebuilds it from the WAL - and creates an empty -wal and a -shm beside
|
|
23
|
+
* a database that had neither, and leaves them there.
|
|
24
|
+
*
|
|
25
|
+
* On the machine the other connections run on, their locks are seen and this
|
|
26
|
+
* is ordinary SQLite. From the far side of a bind mount into a container they
|
|
27
|
+
* may not be, and a gateway whose index was rebuilt underneath it has not been
|
|
28
|
+
* tested and cannot be from here. Hence the two callers: the gateway, for a
|
|
29
|
+
* database in its own home, and {@link standaloneDatabaseSources}.
|
|
30
|
+
*/
|
|
31
|
+
export function readOnlyDatabaseSource(file) {
|
|
32
|
+
return () => {
|
|
33
|
+
if (!fs.existsSync(file))
|
|
34
|
+
return null;
|
|
35
|
+
const database = new Database(file, { readonly: true, fileMustExist: true });
|
|
36
|
+
return { database, release: () => { database.close(); } };
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function refusal(liveness) {
|
|
40
|
+
return {
|
|
41
|
+
withheld: "gateway-running",
|
|
42
|
+
detail: `a gateway appears to be running on this home (${liveness.reason ?? "it was detected"}), so the database was not opened. `
|
|
43
|
+
+ "To copy it from here, stop the gateway (ryoko stop), wait a minute and run this again.",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Sources for a command run by hand, outside the gateway.
|
|
48
|
+
*
|
|
49
|
+
* Before the first database would be opened, the home is looked at for signs
|
|
50
|
+
* of a running gateway - pid files and file timestamps, nothing that touches a
|
|
51
|
+
* database - and if there are any, neither database is opened. The answer is
|
|
52
|
+
* settled once for both: this command's own reading leaves a freshly written
|
|
53
|
+
* -shm behind, and asked again it would take that for a gateway.
|
|
54
|
+
*
|
|
55
|
+
* No sign is not proof. A gateway behind a pid this process cannot see, with
|
|
56
|
+
* nothing written for a minute, passes; so this is offered only on request
|
|
57
|
+
* (`--include-databases`), never by default.
|
|
58
|
+
*/
|
|
59
|
+
export function standaloneDatabaseSources(home, now) {
|
|
60
|
+
let liveness;
|
|
61
|
+
const guarded = (name) => () => {
|
|
62
|
+
const file = databasePath(home, name);
|
|
63
|
+
if (!fs.existsSync(file))
|
|
64
|
+
return null;
|
|
65
|
+
liveness ??= detectRunningGateway(home, { now: now(), databases: [databasePath(home, "workflows")] });
|
|
66
|
+
return liveness.running ? refusal(liveness) : readOnlyDatabaseSource(file)();
|
|
67
|
+
};
|
|
68
|
+
return { sessions: guarded("sessions"), workflows: guarded("workflows") };
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=database-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-source.js","sourceRoot":"","sources":["../../../src/backup/database-source.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,oBAAoB,EAAwB,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiC3C,4GAA4G;AAC5G,MAAM,CAAC,MAAM,sBAAsB,GAAG,qBAAqB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7E,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,QAAyB;IACxC,OAAO;QACL,QAAQ,EAAE,iBAAiB;QAC3B,MAAM,EAAE,iDAAiD,QAAQ,CAAC,MAAM,IAAI,iBAAiB,qCAAqC;cAC9H,wFAAwF;KAC7F,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAY,EAAE,GAAe;IACrE,IAAI,QAAqC,CAAC;IAC1C,MAAM,OAAO,GAAG,CAAC,IAAwB,EAAkB,EAAE,CAAC,GAAG,EAAE;QACjE,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,QAAQ,KAAK,oBAAoB,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;QACtG,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;IAC/E,CAAC,CAAC;IACF,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/backup/format.ts"],"names":[],"mappings":"AAEA,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const UNITS = ["B", "KB", "MB", "GB", "TB"];
|
|
2
|
+
/** A byte count a person can read at a glance: `512 B`, `1.2 MB`. */
|
|
3
|
+
export function formatBytes(bytes) {
|
|
4
|
+
let value = Math.max(0, bytes);
|
|
5
|
+
let unit = 0;
|
|
6
|
+
while (value >= 1024 && unit < UNITS.length - 1) {
|
|
7
|
+
value /= 1024;
|
|
8
|
+
unit += 1;
|
|
9
|
+
}
|
|
10
|
+
return `${unit === 0 ? value : value.toFixed(1)} ${UNITS[unit]}`;
|
|
11
|
+
}
|
|
12
|
+
export function errorMessage(error) {
|
|
13
|
+
return error instanceof Error ? error.message : String(error);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/backup/format.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAErD,qEAAqE;AACrE,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC/B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,KAAK,IAAI,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,KAAK,IAAI,IAAI,CAAC;QACd,IAAI,IAAI,CAAC,CAAC;IACZ,CAAC;IACD,OAAO,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signs that a gateway is running on a home, read without touching anything a
|
|
3
|
+
* gateway might have open.
|
|
4
|
+
*
|
|
5
|
+
* The obvious way to ask "is this database in use" is to open it and see
|
|
6
|
+
* whether SQLite lets us have it. That is exactly what must not be done. File
|
|
7
|
+
* locks do not cross a container boundary: with the home bind-mounted into a
|
|
8
|
+
* container, a process on the host is granted the database outright while the
|
|
9
|
+
* gateway inside holds it, and on closing it - believing itself the last
|
|
10
|
+
* connection - SQLite checkpoints the WAL into the main file and deletes it,
|
|
11
|
+
* under a gateway that goes on appending to a WAL that is no longer there. The
|
|
12
|
+
* commits it makes afterwards are lost. A probe of that kind damaged the
|
|
13
|
+
* database it was written to protect, on the way to refusing a restore.
|
|
14
|
+
*
|
|
15
|
+
* So nothing here opens a database. It reads two small files and the
|
|
16
|
+
* modification times of a few more, and that is all.
|
|
17
|
+
*/
|
|
18
|
+
/** A database file written this recently counts as in use. */
|
|
19
|
+
export declare const RECENT_WRITE_MS = 60000;
|
|
20
|
+
export interface GatewayLiveness {
|
|
21
|
+
running: boolean;
|
|
22
|
+
/** What gave it away, in words an operator can act on. */
|
|
23
|
+
reason?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface LivenessOptions {
|
|
26
|
+
now?: Date;
|
|
27
|
+
/** Databases to look at besides the session registry: the one a restore is about to replace. */
|
|
28
|
+
databases?: readonly string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Looks for a gateway running on `home`.
|
|
32
|
+
*
|
|
33
|
+
* `gateway.json` is written only when the interactive engine is on,
|
|
34
|
+
* `gateway.pid` only by `ryoko start --daemon`; a foreground gateway on the
|
|
35
|
+
* headless engine leaves neither, and a pid from inside a container says
|
|
36
|
+
* nothing outside it. A recent write to the registry is the sign that does not
|
|
37
|
+
* depend on how the gateway was started or where this command runs.
|
|
38
|
+
*
|
|
39
|
+
* None of it is proof of absence. A gateway that has had nothing to write for
|
|
40
|
+
* a minute, behind a pid this process cannot see, is not detected - which is
|
|
41
|
+
* why replacing a database also takes the operator's own word.
|
|
42
|
+
*/
|
|
43
|
+
export declare function detectRunningGateway(home: string, options?: LivenessOptions): GatewayLiveness;
|
|
44
|
+
//# sourceMappingURL=gateway-liveness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway-liveness.d.ts","sourceRoot":"","sources":["../../../src/backup/gateway-liveness.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;GAgBG;AAEH,8DAA8D;AAC9D,eAAO,MAAM,eAAe,QAAS,CAAC;AAEtC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,gGAAgG;IAChG,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAuED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,eAAe,CASjG"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { SQLITE_SIDECAR_SUFFIXES } from "../sessions/backup.js";
|
|
4
|
+
import { GATEWAY_INFO_FILE, PID_FILE } from "../shared/paths.js";
|
|
5
|
+
import { databasePath, inHome } from "./layout.js";
|
|
6
|
+
/**
|
|
7
|
+
* Signs that a gateway is running on a home, read without touching anything a
|
|
8
|
+
* gateway might have open.
|
|
9
|
+
*
|
|
10
|
+
* The obvious way to ask "is this database in use" is to open it and see
|
|
11
|
+
* whether SQLite lets us have it. That is exactly what must not be done. File
|
|
12
|
+
* locks do not cross a container boundary: with the home bind-mounted into a
|
|
13
|
+
* container, a process on the host is granted the database outright while the
|
|
14
|
+
* gateway inside holds it, and on closing it - believing itself the last
|
|
15
|
+
* connection - SQLite checkpoints the WAL into the main file and deletes it,
|
|
16
|
+
* under a gateway that goes on appending to a WAL that is no longer there. The
|
|
17
|
+
* commits it makes afterwards are lost. A probe of that kind damaged the
|
|
18
|
+
* database it was written to protect, on the way to refusing a restore.
|
|
19
|
+
*
|
|
20
|
+
* So nothing here opens a database. It reads two small files and the
|
|
21
|
+
* modification times of a few more, and that is all.
|
|
22
|
+
*/
|
|
23
|
+
/** A database file written this recently counts as in use. */
|
|
24
|
+
export const RECENT_WRITE_MS = 60_000;
|
|
25
|
+
function isAlive(pid) {
|
|
26
|
+
try {
|
|
27
|
+
process.kill(pid, 0);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
// EPERM: it exists and belongs to someone else. Only ESRCH means gone.
|
|
32
|
+
return error.code === "EPERM";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function usablePid(value) {
|
|
36
|
+
const pid = typeof value === "string" ? Number(value.trim()) : value;
|
|
37
|
+
return typeof pid === "number" && Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
38
|
+
}
|
|
39
|
+
function pidFromInfoFile(file) {
|
|
40
|
+
try {
|
|
41
|
+
return usablePid(JSON.parse(fs.readFileSync(file, "utf8"))?.pid);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function pidFromPidFile(file) {
|
|
48
|
+
try {
|
|
49
|
+
const text = fs.readFileSync(file, "utf8").trim();
|
|
50
|
+
return /^\d+$/.test(text) ? usablePid(text) : null;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function alivePid(home) {
|
|
57
|
+
const infoFile = inHome(home, GATEWAY_INFO_FILE);
|
|
58
|
+
const infoPid = pidFromInfoFile(infoFile);
|
|
59
|
+
if (infoPid !== null && isAlive(infoPid))
|
|
60
|
+
return `${path.basename(infoFile)} names pid ${infoPid}, which is alive`;
|
|
61
|
+
const pidFile = inHome(home, PID_FILE);
|
|
62
|
+
const daemonPid = pidFromPidFile(pidFile);
|
|
63
|
+
if (daemonPid !== null && isAlive(daemonPid))
|
|
64
|
+
return `${path.basename(pidFile)} names pid ${daemonPid}, which is alive`;
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The database file or sidecar that was written within the last minute, if
|
|
69
|
+
* any. A pid means nothing in another pid namespace and a lock does not leave
|
|
70
|
+
* the container, but when a file was last written reads the same from both
|
|
71
|
+
* sides of a bind mount. A timestamp slightly ahead of this clock counts too:
|
|
72
|
+
* the writer may be on a machine whose clock is not quite ours.
|
|
73
|
+
*/
|
|
74
|
+
function recentWrite(home, database, now) {
|
|
75
|
+
for (const suffix of ["", ...SQLITE_SIDECAR_SUFFIXES]) {
|
|
76
|
+
const file = `${database}${suffix}`;
|
|
77
|
+
let written;
|
|
78
|
+
try {
|
|
79
|
+
written = fs.statSync(file).mtimeMs;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const age = now.getTime() - written;
|
|
85
|
+
if (age >= RECENT_WRITE_MS || age <= -RECENT_WRITE_MS)
|
|
86
|
+
continue;
|
|
87
|
+
const seconds = Math.round(Math.abs(age) / 1000);
|
|
88
|
+
const when = age >= 0
|
|
89
|
+
? `was written ${seconds} second${seconds === 1 ? "" : "s"} ago`
|
|
90
|
+
: `carries a timestamp ${seconds} second${seconds === 1 ? "" : "s"} ahead of this clock`;
|
|
91
|
+
return `${path.relative(home, file)} ${when}`;
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Looks for a gateway running on `home`.
|
|
97
|
+
*
|
|
98
|
+
* `gateway.json` is written only when the interactive engine is on,
|
|
99
|
+
* `gateway.pid` only by `ryoko start --daemon`; a foreground gateway on the
|
|
100
|
+
* headless engine leaves neither, and a pid from inside a container says
|
|
101
|
+
* nothing outside it. A recent write to the registry is the sign that does not
|
|
102
|
+
* depend on how the gateway was started or where this command runs.
|
|
103
|
+
*
|
|
104
|
+
* None of it is proof of absence. A gateway that has had nothing to write for
|
|
105
|
+
* a minute, behind a pid this process cannot see, is not detected - which is
|
|
106
|
+
* why replacing a database also takes the operator's own word.
|
|
107
|
+
*/
|
|
108
|
+
export function detectRunningGateway(home, options = {}) {
|
|
109
|
+
const pid = alivePid(home);
|
|
110
|
+
if (pid)
|
|
111
|
+
return { running: true, reason: pid };
|
|
112
|
+
const now = options.now ?? new Date();
|
|
113
|
+
for (const database of new Set([databasePath(home, "sessions"), ...(options.databases ?? [])])) {
|
|
114
|
+
const written = recentWrite(home, database, now);
|
|
115
|
+
if (written)
|
|
116
|
+
return { running: true, reason: written };
|
|
117
|
+
}
|
|
118
|
+
return { running: false };
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=gateway-liveness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway-liveness.js","sourceRoot":"","sources":["../../../src/backup/gateway-liveness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type ArchiveLimits } from "./limits.js";
|
|
2
|
+
import { type BackupManifest } from "./manifest.js";
|
|
3
|
+
import { readTar } from "./tar.js";
|
|
4
|
+
export interface ArchiveInspection {
|
|
5
|
+
ok: boolean;
|
|
6
|
+
problems: string[];
|
|
7
|
+
/** Present whenever the archive could be read far enough to find one. */
|
|
8
|
+
manifest?: BackupManifest;
|
|
9
|
+
}
|
|
10
|
+
export interface InspectOptions {
|
|
11
|
+
/** What the archive may hold. Default: the limits an instance uses when its config says nothing. */
|
|
12
|
+
limits?: ArchiveLimits;
|
|
13
|
+
/**
|
|
14
|
+
* The manifest this archive was just written with. Given, the archive is
|
|
15
|
+
* checked against it in a single pass and the copy inside is only compared,
|
|
16
|
+
* never loaded; that is the read-back the gateway does after every backup.
|
|
17
|
+
*/
|
|
18
|
+
expected?: BackupManifest;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Decompresses an archive and hands its entries to `onEntry`, in order, giving
|
|
22
|
+
* up the moment it holds more than `limits` allow. The limits are judged from
|
|
23
|
+
* each header as it arrives - before any of the data it announces is read - so
|
|
24
|
+
* an archive that promises a terabyte, or a million empty directories in a
|
|
25
|
+
* megabyte of gzip, costs neither the time nor the memory it was built to take.
|
|
26
|
+
*
|
|
27
|
+
* Two things a header does not announce are held as well. The manifest is let
|
|
28
|
+
* through once and is not an entry; a second one is refused where it starts,
|
|
29
|
+
* or manifests by the hundred would pass a limit they are not counted against.
|
|
30
|
+
* And the stream as a whole may not unpack to more than an archive at its
|
|
31
|
+
* limits could.
|
|
32
|
+
*/
|
|
33
|
+
export declare function readHomeArchive(file: string, onEntry: Parameters<typeof readTar>[1], limits?: ArchiveLimits): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Reads an archive end to end and checks it against its manifest: every entry
|
|
36
|
+
* hashed, every path in the plain relative form, nothing present that the
|
|
37
|
+
* manifest does not vouch for and nothing promised that is absent, and no more
|
|
38
|
+
* of anything than `limits` allow.
|
|
39
|
+
*
|
|
40
|
+
* Nothing is written. Defects in the archive come back as `problems` rather
|
|
41
|
+
* than as a throw, so a caller can show them - up to a point: past fifty they
|
|
42
|
+
* are only counted.
|
|
43
|
+
*/
|
|
44
|
+
export declare function inspectHomeArchive(file: string, options?: InspectOptions): Promise<ArchiveInspection>;
|
|
45
|
+
//# sourceMappingURL=inspect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../../src/backup/inspect.ts"],"names":[],"mappings":"AAKA,OAAO,EAA6E,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5H,OAAO,EAAuD,KAAK,cAAc,EAAsB,MAAM,eAAe,CAAC;AAE7H,OAAO,EAAE,OAAO,EAAoC,MAAM,UAAU,CAAC;AAKrE,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,oGAAoG;IACpG,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAwDD;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,EACtC,MAAM,GAAE,aAAsC,GAC7C,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAiJD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAuB/G"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { pipeline } from "node:stream/promises";
|
|
4
|
+
import zlib from "node:zlib";
|
|
5
|
+
import { errorMessage, formatBytes } from "./format.js";
|
|
6
|
+
import { ArchiveTooLargeError, manifestByteLimit, pathByteLimit, unpackedByteLimit } from "./limits.js";
|
|
7
|
+
import { findManifestEntry, parseManifest, serializeManifest } from "./manifest.js";
|
|
8
|
+
import { DEFAULT_ARCHIVE_LIMITS } from "./settings.js";
|
|
9
|
+
import { readTar } from "./tar.js";
|
|
10
|
+
import { MANIFEST_ENTRY_PATH, unsafePathReason } from "./targets.js";
|
|
11
|
+
const MAX_REPORTED_PROBLEMS = 50;
|
|
12
|
+
/** What is wrong with an archive, kept to a length somebody can read. The count goes on past it. */
|
|
13
|
+
class ProblemList {
|
|
14
|
+
kept = [];
|
|
15
|
+
dropped = 0;
|
|
16
|
+
add(problem) {
|
|
17
|
+
if (this.kept.length < MAX_REPORTED_PROBLEMS)
|
|
18
|
+
this.kept.push(problem);
|
|
19
|
+
else
|
|
20
|
+
this.dropped += 1;
|
|
21
|
+
}
|
|
22
|
+
get isEmpty() {
|
|
23
|
+
return this.kept.length === 0;
|
|
24
|
+
}
|
|
25
|
+
list() {
|
|
26
|
+
return this.dropped === 0 ? this.kept : [...this.kept, `... and ${this.dropped} more`];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** The archive could be read; it is its manifest that is missing, repeated or not one this version understands. */
|
|
30
|
+
class ManifestProblem extends Error {
|
|
31
|
+
}
|
|
32
|
+
const isManifestEntry = (entry) => entry.path === MANIFEST_ENTRY_PATH && entry.type === "file";
|
|
33
|
+
/**
|
|
34
|
+
* Passes the decompressed stream on, and stops it once it has delivered more
|
|
35
|
+
* than `allowed` bytes. The limits on entries and on content are judged from
|
|
36
|
+
* headers; this is the one that holds whatever the headers say or leave out.
|
|
37
|
+
*/
|
|
38
|
+
function unpackedUpTo(source, allowed) {
|
|
39
|
+
// An iterator by hand, not a generator looping over the stream: leaving such
|
|
40
|
+
// a loop by throwing closes the stream first, and the pipeline then reports
|
|
41
|
+
// that it was aborted instead of why.
|
|
42
|
+
return {
|
|
43
|
+
[Symbol.asyncIterator]() {
|
|
44
|
+
const chunks = source[Symbol.asyncIterator]();
|
|
45
|
+
let unpacked = 0;
|
|
46
|
+
return {
|
|
47
|
+
next: async () => {
|
|
48
|
+
const step = await chunks.next();
|
|
49
|
+
if (step.done)
|
|
50
|
+
return step;
|
|
51
|
+
unpacked += step.value.length;
|
|
52
|
+
if (unpacked > allowed) {
|
|
53
|
+
throw new ArchiveTooLargeError(`the archive unpacks to more than ${formatBytes(allowed)}, past anything its limits account for (backup.maxArchiveMb, backup.maxEntries)`);
|
|
54
|
+
}
|
|
55
|
+
return step;
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Decompresses an archive and hands its entries to `onEntry`, in order, giving
|
|
63
|
+
* up the moment it holds more than `limits` allow. The limits are judged from
|
|
64
|
+
* each header as it arrives - before any of the data it announces is read - so
|
|
65
|
+
* an archive that promises a terabyte, or a million empty directories in a
|
|
66
|
+
* megabyte of gzip, costs neither the time nor the memory it was built to take.
|
|
67
|
+
*
|
|
68
|
+
* Two things a header does not announce are held as well. The manifest is let
|
|
69
|
+
* through once and is not an entry; a second one is refused where it starts,
|
|
70
|
+
* or manifests by the hundred would pass a limit they are not counted against.
|
|
71
|
+
* And the stream as a whole may not unpack to more than an archive at its
|
|
72
|
+
* limits could.
|
|
73
|
+
*/
|
|
74
|
+
export async function readHomeArchive(file, onEntry, limits = DEFAULT_ARCHIVE_LIMITS) {
|
|
75
|
+
const pathLimit = pathByteLimit(limits);
|
|
76
|
+
let entries = 0;
|
|
77
|
+
let declared = 0;
|
|
78
|
+
let manifests = 0;
|
|
79
|
+
const admit = (entry) => {
|
|
80
|
+
if (Buffer.byteLength(entry.path) > pathLimit || Buffer.byteLength(entry.linkTarget ?? "") > pathLimit) {
|
|
81
|
+
throw new ArchiveTooLargeError(`the archive holds a path longer than ${pathLimit} bytes`);
|
|
82
|
+
}
|
|
83
|
+
if (isManifestEntry(entry)) {
|
|
84
|
+
manifests += 1;
|
|
85
|
+
if (manifests > 1)
|
|
86
|
+
throw new ManifestProblem("the manifest appears more than once");
|
|
87
|
+
if (entry.size > manifestByteLimit(limits))
|
|
88
|
+
throw new ArchiveTooLargeError("the archive's manifest is larger than backup.maxEntries allows");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
entries += 1;
|
|
92
|
+
declared += entry.size;
|
|
93
|
+
if (entries > limits.maxEntries)
|
|
94
|
+
throw new ArchiveTooLargeError(`the archive holds more than ${limits.maxEntries} entries (backup.maxEntries)`);
|
|
95
|
+
if (declared > limits.maxBytes) {
|
|
96
|
+
throw new ArchiveTooLargeError(`the archive declares more than ${formatBytes(limits.maxBytes)} of content (backup.maxArchiveMb)`);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
await pipeline(fs.createReadStream(file), zlib.createGunzip(), async (source) => {
|
|
100
|
+
await readTar(unpackedUpTo(source, unpackedByteLimit(limits)), (entry) => {
|
|
101
|
+
admit(entry);
|
|
102
|
+
return onEntry(entry);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Finds the manifest in an archive nobody vouches for, keeping nothing else. It
|
|
108
|
+
* travels last, so this reads the archive through once to reach it; the entries
|
|
109
|
+
* on the way are counted against the limits and let go.
|
|
110
|
+
*/
|
|
111
|
+
async function loadManifest(file, limits) {
|
|
112
|
+
let bytes;
|
|
113
|
+
let copies = 0;
|
|
114
|
+
await readHomeArchive(file, (entry) => {
|
|
115
|
+
if (!isManifestEntry(entry))
|
|
116
|
+
return undefined;
|
|
117
|
+
copies += 1;
|
|
118
|
+
const chunks = [];
|
|
119
|
+
return {
|
|
120
|
+
write: (chunk) => { chunks.push(Buffer.from(chunk)); },
|
|
121
|
+
end: () => { bytes = Buffer.concat(chunks); },
|
|
122
|
+
};
|
|
123
|
+
}, limits);
|
|
124
|
+
if (!bytes)
|
|
125
|
+
throw new ManifestProblem("the archive carries no manifest");
|
|
126
|
+
if (copies > 1)
|
|
127
|
+
throw new ManifestProblem("the manifest appears more than once");
|
|
128
|
+
try {
|
|
129
|
+
return { manifest: parseManifest(bytes), digest: crypto.createHash("sha256").update(bytes).digest("hex") };
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw new ManifestProblem(errorMessage(error));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* An entry below something that is not a directory would be written through it:
|
|
137
|
+
* `skills/link -> /etc` followed by `skills/link/passwd` is how an archive
|
|
138
|
+
* leaves the home. Looked up in the manifest itself, which is in path order, so
|
|
139
|
+
* no index of the archive has to be built to ask.
|
|
140
|
+
*/
|
|
141
|
+
function nonDirectoryAbove(entries, entryPath) {
|
|
142
|
+
const segments = entryPath.split("/");
|
|
143
|
+
for (let depth = 1; depth < segments.length; depth += 1) {
|
|
144
|
+
const ancestor = segments.slice(0, depth).join("/");
|
|
145
|
+
const found = findManifestEntry(entries, ancestor);
|
|
146
|
+
if (found && found.type !== "directory")
|
|
147
|
+
return ancestor;
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Checks the manifest on its own terms: within the limits, every path in the
|
|
153
|
+
* plain relative form, in strict path order (which also rules out a path listed
|
|
154
|
+
* twice), nothing inside a non-directory. Returns false when it is not fit to
|
|
155
|
+
* compare an archive against at all.
|
|
156
|
+
*/
|
|
157
|
+
function validateManifest(manifest, limits, problems) {
|
|
158
|
+
if (manifest.entries.length > limits.maxEntries) {
|
|
159
|
+
problems.add(`the manifest lists more than ${limits.maxEntries} entries (backup.maxEntries)`);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
let previous;
|
|
163
|
+
for (const entry of manifest.entries) {
|
|
164
|
+
const reason = unsafePathReason(entry.path);
|
|
165
|
+
if (reason) {
|
|
166
|
+
problems.add(`unsafe path in the manifest (${reason}): ${JSON.stringify(entry.path)}`);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
if (previous !== undefined && entry.path <= previous) {
|
|
170
|
+
problems.add(entry.path === previous ? `${entry.path}: listed more than once in the manifest` : "the manifest lists its entries out of order");
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
previous = entry.path;
|
|
174
|
+
}
|
|
175
|
+
for (const entry of manifest.entries) {
|
|
176
|
+
const blocker = nonDirectoryAbove(manifest.entries, entry.path);
|
|
177
|
+
if (blocker)
|
|
178
|
+
problems.add(`${entry.path}: is inside ${blocker}, which is not a directory`);
|
|
179
|
+
}
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
/** Holds one archive entry to the manifest entry of the same path. Files are hashed as they stream past. */
|
|
183
|
+
function checkEntry(entry, listed, problems) {
|
|
184
|
+
if (entry.type !== listed.type) {
|
|
185
|
+
problems.add(`${listed.path}: is a ${entry.type} in the archive but a ${listed.type} in the manifest`);
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
if (listed.type === "symlink" && (entry.linkTarget ?? "") !== listed.target)
|
|
189
|
+
problems.add(`${listed.path}: symlink target does not match the manifest`);
|
|
190
|
+
if (listed.type !== "file")
|
|
191
|
+
return undefined;
|
|
192
|
+
if (entry.size !== listed.size) {
|
|
193
|
+
problems.add(`${listed.path}: expected ${listed.size} bytes, found ${entry.size}`);
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
const hash = crypto.createHash("sha256");
|
|
197
|
+
return {
|
|
198
|
+
write: (chunk) => { hash.update(chunk); },
|
|
199
|
+
end: () => { if (hash.digest("hex") !== listed.sha256)
|
|
200
|
+
problems.add(`${listed.path}: sha256 does not match the manifest`); },
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Walks the archive and the manifest side by side. Both are in path order, so
|
|
205
|
+
* each archive entry is held to its manifest entry as it streams past and then
|
|
206
|
+
* forgotten: what is in one and not the other falls out of the order itself,
|
|
207
|
+
* and no table of everything seen is kept. Memory is the manifest, not the
|
|
208
|
+
* archive - which is what lets the gateway read back what it wrote without
|
|
209
|
+
* holding a second copy of the listing.
|
|
210
|
+
*/
|
|
211
|
+
async function compareWithManifest(file, manifest, manifestDigest, limits, problems) {
|
|
212
|
+
const listed = manifest.entries;
|
|
213
|
+
let next = 0;
|
|
214
|
+
let previous;
|
|
215
|
+
let manifestCopies = 0;
|
|
216
|
+
await readHomeArchive(file, (entry) => {
|
|
217
|
+
if (isManifestEntry(entry)) {
|
|
218
|
+
manifestCopies += 1;
|
|
219
|
+
const hash = crypto.createHash("sha256");
|
|
220
|
+
return {
|
|
221
|
+
write: (chunk) => { hash.update(chunk); },
|
|
222
|
+
end: () => { if (hash.digest("hex") !== manifestDigest)
|
|
223
|
+
problems.add("the manifest inside the archive is not the one it is being checked against"); },
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
const reason = unsafePathReason(entry.path);
|
|
227
|
+
if (reason)
|
|
228
|
+
throw new Error(`unsafe path in the archive (${reason}): ${JSON.stringify(entry.path)}`);
|
|
229
|
+
if (entry.path === previous) {
|
|
230
|
+
problems.add(`${entry.path}: appears more than once`);
|
|
231
|
+
return undefined;
|
|
232
|
+
}
|
|
233
|
+
if (previous !== undefined && entry.path < previous)
|
|
234
|
+
throw new Error(`its entries are out of order at ${JSON.stringify(entry.path)}`);
|
|
235
|
+
previous = entry.path;
|
|
236
|
+
for (; next < listed.length && listed[next].path < entry.path; next += 1) {
|
|
237
|
+
problems.add(`${listed[next].path}: listed in the manifest but missing from the archive`);
|
|
238
|
+
}
|
|
239
|
+
if (next >= listed.length || listed[next].path !== entry.path) {
|
|
240
|
+
problems.add(`${entry.path}: not listed in the manifest`);
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
next += 1;
|
|
244
|
+
return checkEntry(entry, listed[next - 1], problems);
|
|
245
|
+
}, limits);
|
|
246
|
+
for (; next < listed.length; next += 1)
|
|
247
|
+
problems.add(`${listed[next].path}: listed in the manifest but missing from the archive`);
|
|
248
|
+
if (manifestCopies === 0)
|
|
249
|
+
problems.add("the archive carries no manifest");
|
|
250
|
+
if (manifestCopies > 1)
|
|
251
|
+
problems.add("the manifest appears more than once");
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Reads an archive end to end and checks it against its manifest: every entry
|
|
255
|
+
* hashed, every path in the plain relative form, nothing present that the
|
|
256
|
+
* manifest does not vouch for and nothing promised that is absent, and no more
|
|
257
|
+
* of anything than `limits` allow.
|
|
258
|
+
*
|
|
259
|
+
* Nothing is written. Defects in the archive come back as `problems` rather
|
|
260
|
+
* than as a throw, so a caller can show them - up to a point: past fifty they
|
|
261
|
+
* are only counted.
|
|
262
|
+
*/
|
|
263
|
+
export async function inspectHomeArchive(file, options = {}) {
|
|
264
|
+
const limits = options.limits ?? DEFAULT_ARCHIVE_LIMITS;
|
|
265
|
+
let manifest;
|
|
266
|
+
let digest;
|
|
267
|
+
try {
|
|
268
|
+
if (options.expected) {
|
|
269
|
+
manifest = options.expected;
|
|
270
|
+
digest = crypto.createHash("sha256").update(serializeManifest(manifest)).digest("hex");
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
({ manifest, digest } = await loadManifest(file, limits));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
const reason = errorMessage(error);
|
|
278
|
+
return { ok: false, problems: [error instanceof ManifestProblem ? reason : `the archive could not be read: ${reason}`] };
|
|
279
|
+
}
|
|
280
|
+
const problems = new ProblemList();
|
|
281
|
+
if (!validateManifest(manifest, limits, problems))
|
|
282
|
+
return { ok: false, problems: problems.list(), manifest };
|
|
283
|
+
try {
|
|
284
|
+
await compareWithManifest(file, manifest, digest, limits, problems);
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
return { ok: false, problems: [`the archive could not be read: ${errorMessage(error)}`], manifest };
|
|
288
|
+
}
|
|
289
|
+
return { ok: problems.isEmpty, problems: problems.list(), manifest };
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=inspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../../src/backup/inspect.ts"],"names":[],"mappings":"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"}
|