@geminixiang/mikan 1.0.0-beta.4 → 1.0.0-beta.41
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/CHANGELOG.md +714 -0
- package/README.md +99 -36
- package/dist/adapter.d.ts +11 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +18 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +6 -7
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +88 -122
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/components.d.ts +33 -0
- package/dist/adapters/discord/components.d.ts.map +1 -0
- package/dist/adapters/discord/components.js +32 -0
- package/dist/adapters/discord/components.js.map +1 -0
- package/dist/adapters/discord/context.d.ts +3 -1
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +66 -217
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/discord/format.d.ts +3 -0
- package/dist/adapters/discord/format.d.ts.map +1 -0
- package/dist/adapters/discord/format.js +86 -0
- package/dist/adapters/discord/format.js.map +1 -0
- package/dist/adapters/github/bot.d.ts +89 -0
- package/dist/adapters/github/bot.d.ts.map +1 -0
- package/dist/adapters/github/bot.js +653 -0
- package/dist/adapters/github/bot.js.map +1 -0
- package/dist/adapters/github/client.d.ts +122 -0
- package/dist/adapters/github/client.d.ts.map +1 -0
- package/dist/adapters/github/client.js +314 -0
- package/dist/adapters/github/client.js.map +1 -0
- package/dist/adapters/github/cloudbuild.d.ts +19 -0
- package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
- package/dist/adapters/github/cloudbuild.js +71 -0
- package/dist/adapters/github/cloudbuild.js.map +1 -0
- package/dist/adapters/github/context.d.ts +12 -0
- package/dist/adapters/github/context.d.ts.map +1 -0
- package/dist/adapters/github/context.js +101 -0
- package/dist/adapters/github/context.js.map +1 -0
- package/dist/adapters/github/gcp-auth.d.ts +28 -0
- package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
- package/dist/adapters/github/gcp-auth.js +196 -0
- package/dist/adapters/github/gcp-auth.js.map +1 -0
- package/dist/adapters/github/github-ops.d.ts +91 -0
- package/dist/adapters/github/github-ops.d.ts.map +1 -0
- package/dist/adapters/github/github-ops.js +406 -0
- package/dist/adapters/github/github-ops.js.map +1 -0
- package/dist/adapters/github/ids.d.ts +34 -0
- package/dist/adapters/github/ids.d.ts.map +1 -0
- package/dist/adapters/github/ids.js +57 -0
- package/dist/adapters/github/ids.js.map +1 -0
- package/dist/adapters/github/repo.d.ts +33 -0
- package/dist/adapters/github/repo.d.ts.map +1 -0
- package/dist/adapters/github/repo.js +141 -0
- package/dist/adapters/github/repo.js.map +1 -0
- package/dist/adapters/github/tool-pack.d.ts +14 -0
- package/dist/adapters/github/tool-pack.d.ts.map +1 -0
- package/dist/adapters/github/tool-pack.js +56 -0
- package/dist/adapters/github/tool-pack.js.map +1 -0
- package/dist/adapters/github/tools/checks.d.ts +19 -0
- package/dist/adapters/github/tools/checks.d.ts.map +1 -0
- package/dist/adapters/github/tools/checks.js +105 -0
- package/dist/adapters/github/tools/checks.js.map +1 -0
- package/dist/adapters/github/tools/issue.d.ts +21 -0
- package/dist/adapters/github/tools/issue.d.ts.map +1 -0
- package/dist/adapters/github/tools/issue.js +48 -0
- package/dist/adapters/github/tools/issue.js.map +1 -0
- package/dist/adapters/github/tools/pr.d.ts +22 -0
- package/dist/adapters/github/tools/pr.d.ts.map +1 -0
- package/dist/adapters/github/tools/pr.js +48 -0
- package/dist/adapters/github/tools/pr.js.map +1 -0
- package/dist/adapters/github/tools/read.d.ts +21 -0
- package/dist/adapters/github/tools/read.d.ts.map +1 -0
- package/dist/adapters/github/tools/read.js +141 -0
- package/dist/adapters/github/tools/read.js.map +1 -0
- package/dist/adapters/github/tools/review-reply.d.ts +17 -0
- package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
- package/dist/adapters/github/tools/review-reply.js +38 -0
- package/dist/adapters/github/tools/review-reply.js.map +1 -0
- package/dist/adapters/github/tools/sync.d.ts +17 -0
- package/dist/adapters/github/tools/sync.d.ts.map +1 -0
- package/dist/adapters/github/tools/sync.js +34 -0
- package/dist/adapters/github/tools/sync.js.map +1 -0
- package/dist/adapters/github/types.d.ts +373 -0
- package/dist/adapters/github/types.d.ts.map +1 -0
- package/dist/adapters/github/types.js +2 -0
- package/dist/adapters/github/types.js.map +1 -0
- package/dist/adapters/intake.d.ts +16 -5
- package/dist/adapters/intake.d.ts.map +1 -1
- package/dist/adapters/intake.js +86 -23
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/markdown-tables.d.ts +37 -0
- package/dist/adapters/markdown-tables.d.ts.map +1 -0
- package/dist/adapters/markdown-tables.js +164 -0
- package/dist/adapters/markdown-tables.js.map +1 -0
- package/dist/adapters/progressive-renderer.d.ts +7 -0
- package/dist/adapters/progressive-renderer.d.ts.map +1 -0
- package/dist/adapters/progressive-renderer.js +440 -0
- package/dist/adapters/progressive-renderer.js.map +1 -0
- package/dist/adapters/shared.d.ts +23 -10
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +60 -22
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/assistant.d.ts +101 -0
- package/dist/adapters/slack/assistant.d.ts.map +1 -0
- package/dist/adapters/slack/assistant.js +204 -0
- package/dist/adapters/slack/assistant.js.map +1 -0
- package/dist/adapters/slack/blocks.d.ts +14 -0
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +105 -147
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +95 -13
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +545 -211
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts +3 -1
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +11 -17
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +197 -323
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/session.d.ts.map +1 -1
- package/dist/adapters/slack/session.js +7 -11
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/slack/stream-limits.d.ts +35 -0
- package/dist/adapters/slack/stream-limits.d.ts.map +1 -0
- package/dist/adapters/slack/stream-limits.js +56 -0
- package/dist/adapters/slack/stream-limits.js.map +1 -0
- package/dist/adapters/slack/tool-pack.d.ts +11 -0
- package/dist/adapters/slack/tool-pack.d.ts.map +1 -0
- package/dist/adapters/slack/tool-pack.js +45 -0
- package/dist/adapters/slack/tool-pack.js.map +1 -0
- package/dist/adapters/slack/tools/attach.js +1 -1
- package/dist/adapters/slack/tools/attach.js.map +1 -1
- package/dist/adapters/slack/tools/blockkit.d.ts +14 -0
- package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -0
- package/dist/adapters/slack/tools/blockkit.js +106 -0
- package/dist/adapters/slack/tools/blockkit.js.map +1 -0
- package/dist/adapters/slack/types.d.ts +40 -2
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +8 -9
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +115 -163
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts +2 -0
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +53 -188
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +132 -12
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent-events.d.ts +3 -2
- package/dist/agent-events.d.ts.map +1 -1
- package/dist/agent-events.js +19 -1
- package/dist/agent-events.js.map +1 -1
- package/dist/agent.d.ts +14 -19
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +841 -298
- package/dist/agent.js.map +1 -1
- package/dist/cli/arg-grammar.d.ts +25 -0
- package/dist/cli/arg-grammar.d.ts.map +1 -0
- package/dist/cli/arg-grammar.js +61 -0
- package/dist/cli/arg-grammar.js.map +1 -0
- package/dist/cli/boot.d.ts +5 -0
- package/dist/cli/boot.d.ts.map +1 -0
- package/dist/cli/boot.js +117 -0
- package/dist/cli/boot.js.map +1 -0
- package/dist/cli/download.d.ts.map +1 -0
- package/dist/{download.js → cli/download.js} +2 -0
- package/dist/cli/download.js.map +1 -0
- package/dist/cli/ext-dev.d.ts +2 -0
- package/dist/cli/ext-dev.d.ts.map +1 -0
- package/dist/cli/ext-dev.js +188 -0
- package/dist/cli/ext-dev.js.map +1 -0
- package/dist/cli/ext.d.ts +2 -0
- package/dist/cli/ext.d.ts.map +1 -0
- package/dist/cli/ext.js +324 -0
- package/dist/cli/ext.js.map +1 -0
- package/dist/cli/office.d.ts +2 -0
- package/dist/cli/office.d.ts.map +1 -0
- package/dist/cli/office.js +91 -0
- package/dist/cli/office.js.map +1 -0
- package/dist/cli/types.d.ts +16 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +3 -2
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +5 -9
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/extensions.d.ts +18 -6
- package/dist/commands/extensions.d.ts.map +1 -1
- package/dist/commands/extensions.js +64 -14
- package/dist/commands/extensions.js.map +1 -1
- package/dist/commands/login.d.ts +2 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +40 -5
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/manifest.d.ts +37 -0
- package/dist/commands/manifest.d.ts.map +1 -0
- package/dist/commands/manifest.js +151 -0
- package/dist/commands/manifest.js.map +1 -0
- package/dist/commands/model.d.ts +2 -3
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +63 -24
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +15 -3
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/registry.d.ts +2 -2
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +1 -2
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +83 -33
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/session-view.d.ts.map +1 -1
- package/dist/commands/session-view.js +6 -3
- package/dist/commands/session-view.js.map +1 -1
- package/dist/commands/types.d.ts +79 -7
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +23 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +222 -135
- package/dist/config.js.map +1 -1
- package/dist/env-manifest.d.ts +30 -0
- package/dist/env-manifest.d.ts.map +1 -0
- package/dist/env-manifest.js +233 -0
- package/dist/env-manifest.js.map +1 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +20 -81
- package/dist/events.js.map +1 -1
- package/dist/execution-resolver.d.ts +7 -8
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +106 -110
- package/dist/execution-resolver.js.map +1 -1
- package/dist/extension-schedules.d.ts +31 -0
- package/dist/extension-schedules.d.ts.map +1 -0
- package/dist/extension-schedules.js +229 -0
- package/dist/extension-schedules.js.map +1 -0
- package/dist/harness/auth.d.ts +2 -1
- package/dist/harness/auth.d.ts.map +1 -1
- package/dist/harness/auth.js +11 -5
- package/dist/harness/auth.js.map +1 -1
- package/dist/harness/event-format.d.ts +27 -0
- package/dist/harness/event-format.d.ts.map +1 -0
- package/dist/harness/event-format.js +160 -0
- package/dist/harness/event-format.js.map +1 -0
- package/dist/harness/extensions/loader.d.ts +27 -49
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +486 -130
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/extensions/registry.d.ts +107 -2
- package/dist/harness/extensions/registry.d.ts.map +1 -1
- package/dist/harness/extensions/registry.js +316 -0
- package/dist/harness/extensions/registry.js.map +1 -1
- package/dist/harness/extensions/types.d.ts +482 -42
- package/dist/harness/extensions/types.d.ts.map +1 -1
- package/dist/harness/extensions/types.js.map +1 -1
- package/dist/harness/index.d.ts +18 -8
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +7 -4
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/models.d.ts +7 -4
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +46 -24
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/runner.d.ts +50 -54
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +232 -46
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session-store.d.ts +11 -5
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +141 -36
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/settings.d.ts +2 -20
- package/dist/harness/settings.d.ts.map +1 -1
- package/dist/harness/settings.js +12 -1
- package/dist/harness/settings.js.map +1 -1
- package/dist/harness/skills.d.ts +10 -29
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +48 -6
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/subagent-profiles.d.ts +8 -0
- package/dist/harness/subagent-profiles.d.ts.map +1 -0
- package/dist/harness/subagent-profiles.js +299 -0
- package/dist/harness/subagent-profiles.js.map +1 -0
- package/dist/harness/subagent-runner.d.ts +45 -0
- package/dist/harness/subagent-runner.d.ts.map +1 -0
- package/dist/harness/subagent-runner.js +680 -0
- package/dist/harness/subagent-runner.js.map +1 -0
- package/dist/harness/types.d.ts +267 -1
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage.d.ts +6 -0
- package/dist/harness/usage.d.ts.map +1 -0
- package/dist/harness/usage.js +32 -0
- package/dist/harness/usage.js.map +1 -0
- package/dist/index.d.ts +36 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -6
- package/dist/index.js.map +1 -1
- package/dist/main.js +391 -127
- package/dist/main.js.map +1 -1
- package/dist/observability/instrument.js +7 -5
- package/dist/observability/instrument.js.map +1 -1
- package/dist/observability/sentry.d.ts +2 -0
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +10 -2
- package/dist/observability/sentry.js.map +1 -1
- package/dist/office/address.d.ts +31 -0
- package/dist/office/address.d.ts.map +1 -0
- package/dist/office/address.js +113 -0
- package/dist/office/address.js.map +1 -0
- package/dist/office/index.d.ts +11 -0
- package/dist/office/index.d.ts.map +1 -0
- package/dist/office/index.js +11 -0
- package/dist/office/index.js.map +1 -0
- package/dist/office/layout.d.ts +27 -0
- package/dist/office/layout.d.ts.map +1 -0
- package/dist/office/layout.js +97 -0
- package/dist/office/layout.js.map +1 -0
- package/dist/office/migration.d.ts +44 -0
- package/dist/office/migration.d.ts.map +1 -0
- package/dist/office/migration.js +255 -0
- package/dist/office/migration.js.map +1 -0
- package/dist/office/registry.d.ts +75 -0
- package/dist/office/registry.d.ts.map +1 -0
- package/dist/office/registry.js +646 -0
- package/dist/office/registry.js.map +1 -0
- package/dist/office/types.d.ts +71 -0
- package/dist/office/types.d.ts.map +1 -0
- package/dist/office/types.js +2 -0
- package/dist/office/types.js.map +1 -0
- package/dist/packages/admin.d.ts +17 -0
- package/dist/packages/admin.d.ts.map +1 -0
- package/dist/packages/admin.js +98 -0
- package/dist/packages/admin.js.map +1 -0
- package/dist/packages/index.d.ts +6 -0
- package/dist/packages/index.d.ts.map +1 -0
- package/dist/packages/index.js +6 -0
- package/dist/packages/index.js.map +1 -0
- package/dist/packages/inspect.d.ts +11 -0
- package/dist/packages/inspect.d.ts.map +1 -0
- package/dist/packages/inspect.js +98 -0
- package/dist/packages/inspect.js.map +1 -0
- package/dist/packages/materialize.d.ts +40 -0
- package/dist/packages/materialize.d.ts.map +1 -0
- package/dist/packages/materialize.js +297 -0
- package/dist/packages/materialize.js.map +1 -0
- package/dist/packages/resolve.d.ts +25 -0
- package/dist/packages/resolve.d.ts.map +1 -0
- package/dist/packages/resolve.js +208 -0
- package/dist/packages/resolve.js.map +1 -0
- package/dist/packages/source.d.ts +39 -0
- package/dist/packages/source.d.ts.map +1 -0
- package/dist/packages/source.js +189 -0
- package/dist/packages/source.js.map +1 -0
- package/dist/packages/types.d.ts +104 -0
- package/dist/packages/types.d.ts.map +1 -0
- package/dist/packages/types.js +2 -0
- package/dist/packages/types.js.map +1 -0
- package/dist/provisioner.d.ts +66 -0
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +335 -13
- package/dist/provisioner.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +562 -118
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +38 -0
- package/dist/runtime/session-lifecycle.d.ts.map +1 -0
- package/dist/runtime/session-lifecycle.js +193 -0
- package/dist/runtime/session-lifecycle.js.map +1 -0
- package/dist/runtime/types.d.ts +66 -7
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts +3 -0
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +13 -1
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts +4 -0
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +13 -3
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/firecracker.d.ts +3 -0
- package/dist/sandbox/firecracker.d.ts.map +1 -1
- package/dist/sandbox/firecracker.js +13 -2
- package/dist/sandbox/firecracker.js.map +1 -1
- package/dist/sandbox/gondolin.d.ts +57 -0
- package/dist/sandbox/gondolin.d.ts.map +1 -0
- package/dist/sandbox/gondolin.js +764 -0
- package/dist/sandbox/gondolin.js.map +1 -0
- package/dist/sandbox/host.d.ts +3 -0
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +18 -3
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +44 -0
- package/dist/sandbox/identity.d.ts.map +1 -0
- package/dist/sandbox/identity.js +68 -0
- package/dist/sandbox/identity.js.map +1 -0
- package/dist/sandbox/image.d.ts.map +1 -1
- package/dist/sandbox/image.js +2 -0
- package/dist/sandbox/image.js.map +1 -1
- package/dist/sandbox/index.d.ts +17 -4
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +37 -3
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/types.d.ts +65 -1
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +14 -0
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +68 -1
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +25 -0
- package/dist/sessions/chat-history-sync.d.ts.map +1 -0
- package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +135 -131
- package/dist/sessions/chat-history-sync.js.map +1 -0
- package/dist/sessions/conversation-log.d.ts +9 -0
- package/dist/sessions/conversation-log.d.ts.map +1 -0
- package/dist/sessions/conversation-log.js +50 -0
- package/dist/sessions/conversation-log.js.map +1 -0
- package/dist/sessions/history-line.d.ts +29 -0
- package/dist/sessions/history-line.d.ts.map +1 -0
- package/dist/sessions/history-line.js +45 -0
- package/dist/sessions/history-line.js.map +1 -0
- package/dist/sessions/rotation.d.ts +2 -0
- package/dist/sessions/rotation.d.ts.map +1 -0
- package/dist/sessions/rotation.js +39 -0
- package/dist/sessions/rotation.js.map +1 -0
- package/dist/sessions/session-key.d.ts +33 -0
- package/dist/sessions/session-key.d.ts.map +1 -0
- package/dist/sessions/session-key.js +115 -0
- package/dist/sessions/session-key.js.map +1 -0
- package/dist/sessions/store.d.ts +15 -7
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +127 -36
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +19 -5
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings-mutation.d.ts +40 -0
- package/dist/settings-mutation.d.ts.map +1 -0
- package/dist/settings-mutation.js +61 -0
- package/dist/settings-mutation.js.map +1 -0
- package/dist/subagent-progress.d.ts +39 -0
- package/dist/subagent-progress.d.ts.map +1 -0
- package/dist/subagent-progress.js +225 -0
- package/dist/subagent-progress.js.map +1 -0
- package/dist/tools/bash.d.ts +3 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +26 -18
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +14 -13
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/event.d.ts +1 -1
- package/dist/tools/event.d.ts.map +1 -1
- package/dist/tools/event.js +58 -45
- package/dist/tools/event.js.map +1 -1
- package/dist/tools/generate-image.d.ts +23 -0
- package/dist/tools/generate-image.d.ts.map +1 -0
- package/dist/tools/generate-image.js +65 -0
- package/dist/tools/generate-image.js.map +1 -0
- package/dist/tools/host-fn-tool.d.ts +21 -0
- package/dist/tools/host-fn-tool.d.ts.map +1 -0
- package/dist/tools/host-fn-tool.js +32 -0
- package/dist/tools/host-fn-tool.js.map +1 -0
- package/dist/tools/index.d.ts +19 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +25 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/react.d.ts +15 -0
- package/dist/tools/react.d.ts.map +1 -0
- package/dist/tools/react.js +29 -0
- package/dist/tools/react.js.map +1 -0
- package/dist/tools/read.d.ts +1 -0
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +39 -33
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/sandbox.d.ts +2 -2
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/sandbox.js +14 -9
- package/dist/tools/sandbox.js.map +1 -1
- package/dist/tools/subagent-slots.d.ts +28 -0
- package/dist/tools/subagent-slots.d.ts.map +1 -0
- package/dist/tools/subagent-slots.js +72 -0
- package/dist/tools/subagent-slots.js.map +1 -0
- package/dist/tools/subagent.d.ts +61 -0
- package/dist/tools/subagent.d.ts.map +1 -0
- package/dist/tools/subagent.js +434 -0
- package/dist/tools/subagent.js.map +1 -0
- package/dist/tools/types.d.ts +40 -32
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +2 -8
- package/dist/tools/write.js.map +1 -1
- package/dist/trigger.d.ts +2 -1
- package/dist/trigger.d.ts.map +1 -1
- package/dist/trigger.js +6 -9
- package/dist/trigger.js.map +1 -1
- package/dist/types.d.ts +411 -59
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/dist/utils/file-guards.d.ts +9 -0
- package/dist/utils/file-guards.d.ts.map +1 -1
- package/dist/utils/file-guards.js +44 -1
- package/dist/utils/file-guards.js.map +1 -1
- package/dist/vault/disabled.d.ts +9 -0
- package/dist/vault/disabled.d.ts.map +1 -0
- package/dist/vault/disabled.js +25 -0
- package/dist/vault/disabled.js.map +1 -0
- package/dist/vault/index.d.ts +45 -2
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +127 -36
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/types.d.ts +6 -2
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/dist/web/admin/portal.d.ts +31 -3
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +850 -345
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/provider-models.js +1 -1
- package/dist/web/admin/provider-models.js.map +1 -1
- package/dist/web/admin/types.d.ts +23 -3
- package/dist/web/admin/types.d.ts.map +1 -1
- package/dist/web/admin/types.js.map +1 -1
- package/dist/web/login/oauth.d.ts +2 -3
- package/dist/web/login/oauth.d.ts.map +1 -1
- package/dist/web/login/oauth.js +1 -32
- package/dist/web/login/oauth.js.map +1 -1
- package/dist/web/login/portal.d.ts +1 -1
- package/dist/web/login/portal.d.ts.map +1 -1
- package/dist/web/login/portal.js +13 -36
- package/dist/web/login/portal.js.map +1 -1
- package/dist/web/login/types.d.ts +0 -11
- package/dist/web/login/types.d.ts.map +1 -1
- package/dist/web/login/types.js.map +1 -1
- package/dist/web/portal-shell.d.ts +21 -0
- package/dist/web/portal-shell.d.ts.map +1 -0
- package/dist/{portal-shell.js → web/portal-shell.js} +67 -2
- package/dist/web/portal-shell.js.map +1 -0
- package/dist/web/server.d.ts +3 -2
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +11 -4
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-view/portal.d.ts +1 -1
- package/dist/web/session-view/portal.d.ts.map +1 -1
- package/dist/web/session-view/portal.js +37 -28
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/web/session-view/service.d.ts +1 -1
- package/dist/web/session-view/service.d.ts.map +1 -1
- package/dist/web/session-view/service.js +61 -18
- package/dist/web/session-view/service.js.map +1 -1
- package/dist/web/session-view/types.d.ts +0 -3
- package/dist/web/session-view/types.d.ts.map +1 -1
- package/dist/web/session-view/types.js.map +1 -1
- package/dist/web/token-store.js +1 -1
- package/dist/web/token-store.js.map +1 -1
- package/dist/workspace-projection/index.d.ts +10 -0
- package/dist/workspace-projection/index.d.ts.map +1 -0
- package/dist/workspace-projection/index.js +120 -0
- package/dist/workspace-projection/index.js.map +1 -0
- package/dist/workspace-projection/types.d.ts +16 -0
- package/dist/workspace-projection/types.d.ts.map +1 -0
- package/dist/workspace-projection/types.js +2 -0
- package/dist/workspace-projection/types.js.map +1 -0
- package/package.json +68 -37
- package/dist/adapters/streaming.d.ts +0 -18
- package/dist/adapters/streaming.d.ts.map +0 -1
- package/dist/adapters/streaming.js +0 -44
- package/dist/adapters/streaming.js.map +0 -1
- package/dist/adapters/telegram/html.d.ts +0 -3
- package/dist/adapters/telegram/html.d.ts.map +0 -1
- package/dist/adapters/telegram/html.js +0 -98
- package/dist/adapters/telegram/html.js.map +0 -1
- package/dist/commands/parse.d.ts +0 -7
- package/dist/commands/parse.d.ts.map +0 -1
- package/dist/commands/parse.js +0 -14
- package/dist/commands/parse.js.map +0 -1
- package/dist/download.d.ts.map +0 -1
- package/dist/download.js.map +0 -1
- package/dist/model-registry.d.ts +0 -4
- package/dist/model-registry.d.ts.map +0 -1
- package/dist/model-registry.js +0 -7
- package/dist/model-registry.js.map +0 -1
- package/dist/portal-shell.d.ts +0 -4
- package/dist/portal-shell.d.ts.map +0 -1
- package/dist/portal-shell.js.map +0 -1
- package/dist/runtime/agent-run-controller.d.ts +0 -31
- package/dist/runtime/agent-run-controller.d.ts.map +0 -1
- package/dist/runtime/agent-run-controller.js +0 -195
- package/dist/runtime/agent-run-controller.js.map +0 -1
- package/dist/sandbox/path-context.d.ts +0 -3
- package/dist/sandbox/path-context.d.ts.map +0 -1
- package/dist/sandbox/path-context.js +0 -20
- package/dist/sandbox/path-context.js.map +0 -1
- package/dist/sessions/agent-memory-file-manager.d.ts +0 -19
- package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
- package/dist/sessions/agent-memory-file-manager.js.map +0 -1
- package/dist/sessions/metadata.d.ts +0 -3
- package/dist/sessions/metadata.d.ts.map +0 -1
- package/dist/sessions/metadata.js +0 -11
- package/dist/sessions/metadata.js.map +0 -1
- package/dist/sessions/policy.d.ts +0 -6
- package/dist/sessions/policy.d.ts.map +0 -1
- package/dist/sessions/policy.js +0 -23
- package/dist/sessions/policy.js.map +0 -1
- package/dist/store.d.ts +0 -46
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -177
- package/dist/store.js.map +0 -1
- package/dist/tools/truncate.d.ts +0 -33
- package/dist/tools/truncate.d.ts.map +0 -1
- package/dist/tools/truncate.js +0 -184
- package/dist/tools/truncate.js.map +0 -1
- package/dist/utils/date.d.ts +0 -10
- package/dist/utils/date.d.ts.map +0 -1
- package/dist/utils/date.js +0 -23
- package/dist/utils/date.js.map +0 -1
- package/dist/utils/env.d.ts +0 -3
- package/dist/utils/env.d.ts.map +0 -1
- package/dist/utils/env.js +0 -12
- package/dist/utils/env.js.map +0 -1
- package/dist/utils/fs-atomic.d.ts +0 -10
- package/dist/utils/fs-atomic.d.ts.map +0 -1
- package/dist/utils/fs-atomic.js +0 -45
- package/dist/utils/fs-atomic.js.map +0 -1
- package/dist/utils/html.d.ts +0 -2
- package/dist/utils/html.d.ts.map +0 -1
- package/dist/utils/html.js +0 -4
- package/dist/utils/html.js.map +0 -1
- package/dist/utils/http-body.d.ts +0 -10
- package/dist/utils/http-body.d.ts.map +0 -1
- package/dist/utils/http-body.js +0 -34
- package/dist/utils/http-body.js.map +0 -1
- package/dist/vault/routing.d.ts +0 -3
- package/dist/vault/routing.d.ts.map +0 -1
- package/dist/vault/routing.js +0 -13
- package/dist/vault/routing.js.map +0 -1
- package/dist/web/agent-events/portal.d.ts +0 -3
- package/dist/web/agent-events/portal.d.ts.map +0 -1
- package/dist/web/agent-events/portal.js +0 -18
- package/dist/web/agent-events/portal.js.map +0 -1
- package/dist/web/request.d.ts +0 -3
- package/dist/web/request.d.ts.map +0 -1
- package/dist/web/request.js +0 -13
- package/dist/web/request.js.map +0 -1
- package/dist/web/session-view/command.d.ts +0 -4
- package/dist/web/session-view/command.d.ts.map +0 -1
- package/dist/web/session-view/command.js +0 -7
- package/dist/web/session-view/command.js.map +0 -1
- /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
package/dist/provisioner.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { execFile } from "child_process";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { sanitizeIdentitySegment } from "./sandbox/identity.js";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { readFileSync, statSync } from "node:fs";
|
|
5
|
+
import { promisify } from "node:util";
|
|
5
6
|
import * as log from "./log.js";
|
|
7
|
+
import { readEnv } from "./env-manifest.js";
|
|
6
8
|
import { reportUserFacingError } from "./observability/sentry.js";
|
|
7
9
|
const execFileAsync = promisify(execFile);
|
|
8
10
|
function isDockerNotFoundError(err) {
|
|
@@ -18,16 +20,30 @@ function isDockerNotFoundError(err) {
|
|
|
18
20
|
/network [^\n]+ not found/.test(haystack) ||
|
|
19
21
|
/error: no such [^\n]+/.test(haystack));
|
|
20
22
|
}
|
|
23
|
+
/** Parse `src:dst[:ro]` back into a ContainerMount for signature computation. */
|
|
24
|
+
function bindSpecToMount(bindSpec) {
|
|
25
|
+
const readOnly = bindSpec.endsWith(":ro");
|
|
26
|
+
const spec = readOnly ? bindSpec.slice(0, -3) : bindSpec;
|
|
27
|
+
const separator = spec.indexOf(":");
|
|
28
|
+
return {
|
|
29
|
+
source: spec.slice(0, separator),
|
|
30
|
+
target: spec.slice(separator + 1),
|
|
31
|
+
...(readOnly ? { readOnly: true } : {}),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
21
34
|
export class DockerContainerManager {
|
|
22
35
|
static { this.MANAGED_LABEL = "mikan.managed=true"; }
|
|
23
36
|
static { this.IMAGE_MODE_LABEL = "mikan.sandbox=image"; }
|
|
24
37
|
static { this.VAULT_ID_LABEL_KEY = "mikan.vault-id"; }
|
|
25
38
|
static { this.CONVERSATION_ID_LABEL_KEY = "mikan.conversation-id"; }
|
|
26
39
|
static { this.MOUNT_SIGNATURE_LABEL_KEY = "mikan.mount-signature"; }
|
|
40
|
+
static { this.MIGRATE_IMAGE_PREFIX = "mikan-migrate"; }
|
|
41
|
+
static { this.MIGRATE_BINDS_LABEL_KEY = "mikan.migrate-binds"; }
|
|
27
42
|
constructor(image, options = {}) {
|
|
28
43
|
this.image = image;
|
|
29
44
|
this.state = new Map();
|
|
30
45
|
this.inflight = new Map();
|
|
46
|
+
this.layoutMigrations = new Map();
|
|
31
47
|
this.boostedKeys = new Set();
|
|
32
48
|
this.overrideLimits = new Map();
|
|
33
49
|
this.limits = options.limits;
|
|
@@ -35,11 +51,7 @@ export class DockerContainerManager {
|
|
|
35
51
|
this.execFileImpl = options.execFileImpl ?? execFileAsync;
|
|
36
52
|
}
|
|
37
53
|
static sanitizeSegment(value) {
|
|
38
|
-
|
|
39
|
-
.toLowerCase()
|
|
40
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
41
|
-
.replace(/^-+|-+$/g, "");
|
|
42
|
-
return sanitized || "unknown";
|
|
54
|
+
return sanitizeIdentitySegment(value);
|
|
43
55
|
}
|
|
44
56
|
static containerName(containerKey) {
|
|
45
57
|
return `mikan-sandbox-${containerKey}`;
|
|
@@ -60,13 +72,23 @@ export class DockerContainerManager {
|
|
|
60
72
|
async provisionInner(containerKey, options) {
|
|
61
73
|
const containerName = options.containerName ?? DockerContainerManager.containerName(containerKey);
|
|
62
74
|
const mounts = options.mounts ?? [];
|
|
75
|
+
// A container still on the pre-office layout must move its writable layer
|
|
76
|
+
// to the new mounts before the drift check below would recreate it from
|
|
77
|
+
// the base image and discard everything installed inside.
|
|
78
|
+
await this.migrateContainerLayout(containerName);
|
|
63
79
|
const status = await this.inspectStatus(containerName);
|
|
64
80
|
try {
|
|
65
81
|
if (status !== "missing" &&
|
|
66
82
|
(await this.hasRuntimeDrift(containerKey, containerName, mounts))) {
|
|
67
83
|
log.logInfo(`Container ${containerName} configuration changed; recreating container`);
|
|
68
|
-
|
|
69
|
-
|
|
84
|
+
if (readEnv("SKIP_CONTAINER_PRESERVATION") === "1") {
|
|
85
|
+
await this.execFileImpl("docker", ["rm", "-f", containerName]);
|
|
86
|
+
await this.removeMigrateSnapshot(containerName);
|
|
87
|
+
await this.runContainer(containerKey, containerName, mounts, options);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
await this.recreateContainerPreservingContents(containerKey, containerName, mounts);
|
|
91
|
+
}
|
|
70
92
|
log.logInfo(`Container ${containerName} recreated`);
|
|
71
93
|
}
|
|
72
94
|
else if (status === "running") {
|
|
@@ -144,6 +166,7 @@ export class DockerContainerManager {
|
|
|
144
166
|
catch (err) {
|
|
145
167
|
log.logWarning(`Failed to remove network ${networkName}`, err instanceof Error ? err.message : String(err));
|
|
146
168
|
}
|
|
169
|
+
await this.removeMigrateSnapshot(containerName);
|
|
147
170
|
this.state.delete(containerKey);
|
|
148
171
|
this.boostedKeys.delete(containerKey);
|
|
149
172
|
this.overrideLimits.delete(containerKey);
|
|
@@ -158,6 +181,294 @@ export class DockerContainerManager {
|
|
|
158
181
|
}
|
|
159
182
|
await Promise.all(toStop.map((containerKey) => this.stop(containerKey)));
|
|
160
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Force-remove every managed container belonging to the given conversation
|
|
186
|
+
* ids. The office layout migration renames the host directories a
|
|
187
|
+
* container's workspace mount points at, so a surviving container would keep
|
|
188
|
+
* writing through stale mounts while the runtime works in the new location.
|
|
189
|
+
*/
|
|
190
|
+
async removeContainersForConversations(conversationIds) {
|
|
191
|
+
if (conversationIds.size === 0)
|
|
192
|
+
return;
|
|
193
|
+
const names = await this.listContainerNamesByLabel();
|
|
194
|
+
await Promise.all(names.map(async (containerName) => {
|
|
195
|
+
const details = await this.inspectContainerDetails(containerName);
|
|
196
|
+
if (!details?.conversationId || !conversationIds.has(details.conversationId))
|
|
197
|
+
return;
|
|
198
|
+
await this.forceRemoveContainer(containerName, `Removed container ${containerName} after office migration`, `Failed to remove container ${containerName} after office migration`);
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Arm the office-layout container migration. Containers whose binds still
|
|
203
|
+
* reference legacy raw-id paths are moved to the office-key layout without
|
|
204
|
+
* losing their writable layer: commit → remove → create with translated
|
|
205
|
+
* binds, preserving everything installed inside. Idempotent per container
|
|
206
|
+
* and resumable — the pre-removal binds ride on the snapshot image label,
|
|
207
|
+
* so a crash between commit and create resumes from the snapshot.
|
|
208
|
+
*/
|
|
209
|
+
armContainerLayoutMigration(translator) {
|
|
210
|
+
this.bindTranslator = translator;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Sweep every managed container through the layout migration, serially and
|
|
214
|
+
* with a small gap, so the one-time cost never lands on the boot path or on
|
|
215
|
+
* a message. Safe to fire-and-forget; each unit is idempotent.
|
|
216
|
+
*/
|
|
217
|
+
async sweepContainerLayoutMigration(delayMs = 2000) {
|
|
218
|
+
if (!this.bindTranslator)
|
|
219
|
+
return;
|
|
220
|
+
let names;
|
|
221
|
+
try {
|
|
222
|
+
// Include snapshot names: a crash between commit and create leaves a
|
|
223
|
+
// snapshot with no container, which must resume before the GC below
|
|
224
|
+
// could mistake it for an orphan.
|
|
225
|
+
const containers = await this.listContainerNamesByLabel();
|
|
226
|
+
const snapshots = await this.listMigrateSnapshotContainerNames();
|
|
227
|
+
names = Array.from(new Set([...containers, ...snapshots]));
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
log.logWarning("Container layout sweep could not list containers", String(err));
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
for (const containerName of names) {
|
|
234
|
+
try {
|
|
235
|
+
await this.migrateContainerLayout(containerName);
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
log.logWarning(`Container layout migration failed for ${containerName}; leaving it in place`, err instanceof Error ? err.message : String(err));
|
|
239
|
+
}
|
|
240
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
241
|
+
}
|
|
242
|
+
// Snapshot images whose container has since been recreated from the base
|
|
243
|
+
// image are no longer referenced; reclaim them.
|
|
244
|
+
await this.removeDanglingMigrateImages();
|
|
245
|
+
}
|
|
246
|
+
/** Move one container to the office-key layout; no-op when already there. */
|
|
247
|
+
migrateContainerLayout(containerName) {
|
|
248
|
+
const translator = this.bindTranslator;
|
|
249
|
+
if (!translator)
|
|
250
|
+
return Promise.resolve();
|
|
251
|
+
const existing = this.layoutMigrations.get(containerName);
|
|
252
|
+
if (existing)
|
|
253
|
+
return existing;
|
|
254
|
+
const pending = this.migrateContainerLayoutInner(containerName, translator).finally(() => {
|
|
255
|
+
this.layoutMigrations.delete(containerName);
|
|
256
|
+
});
|
|
257
|
+
this.layoutMigrations.set(containerName, pending);
|
|
258
|
+
return pending;
|
|
259
|
+
}
|
|
260
|
+
async migrateContainerLayoutInner(containerName, translator) {
|
|
261
|
+
const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;
|
|
262
|
+
let originalBinds;
|
|
263
|
+
const status = await this.inspectStatus(containerName);
|
|
264
|
+
if (status === "missing") {
|
|
265
|
+
// Resume path: a previous run committed and removed the container but
|
|
266
|
+
// died before creating the replacement. The snapshot carries the
|
|
267
|
+
// pre-removal binds on its label.
|
|
268
|
+
const labeled = await this.readMigrateImageBinds(snapshotImage);
|
|
269
|
+
if (labeled === undefined)
|
|
270
|
+
return;
|
|
271
|
+
originalBinds = labeled;
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
originalBinds = await this.inspectBindMounts(containerName);
|
|
275
|
+
const translated = originalBinds.map(translator);
|
|
276
|
+
if (this.sameBinds(translated.toSorted(), originalBinds.slice().toSorted())) {
|
|
277
|
+
return; // already on the office layout
|
|
278
|
+
}
|
|
279
|
+
log.logInfo(`Migrating container ${containerName} to the office layout`);
|
|
280
|
+
await this.execFileImpl("docker", [
|
|
281
|
+
"commit",
|
|
282
|
+
"-c",
|
|
283
|
+
`LABEL ${DockerContainerManager.MIGRATE_BINDS_LABEL_KEY}=${JSON.stringify(JSON.stringify(originalBinds))}`,
|
|
284
|
+
containerName,
|
|
285
|
+
snapshotImage,
|
|
286
|
+
]);
|
|
287
|
+
await this.execFileImpl("docker", ["rm", "-f", containerName]);
|
|
288
|
+
}
|
|
289
|
+
await this.createContainerFromSnapshot(containerName, originalBinds.map(translator));
|
|
290
|
+
log.logInfo(`Container ${containerName} migrated to the office layout`);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Create `containerName` from its layout snapshot with `bindSpecs`,
|
|
294
|
+
* restoring the managed labels and recomputing the mount signature.
|
|
295
|
+
* `create`, not `run`: idle containers stay stopped exactly as they were;
|
|
296
|
+
* callers that need the container running start it themselves.
|
|
297
|
+
*/
|
|
298
|
+
async createContainerFromSnapshot(containerName, bindSpecs, knownContainerKey) {
|
|
299
|
+
const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;
|
|
300
|
+
// The sweep has only the container name and derives the key; the drift
|
|
301
|
+
// path knows the real key (container names can be caller-supplied).
|
|
302
|
+
const containerKey = knownContainerKey ?? this.containerKeyFromContainerName(containerName) ?? containerName;
|
|
303
|
+
const networkName = await this.ensureNetwork(containerKey);
|
|
304
|
+
const conversationId = await this.readImageLabel(snapshotImage, DockerContainerManager.CONVERSATION_ID_LABEL_KEY);
|
|
305
|
+
const labels = [
|
|
306
|
+
"--label",
|
|
307
|
+
DockerContainerManager.MANAGED_LABEL,
|
|
308
|
+
"--label",
|
|
309
|
+
DockerContainerManager.IMAGE_MODE_LABEL,
|
|
310
|
+
"--label",
|
|
311
|
+
`${DockerContainerManager.VAULT_ID_LABEL_KEY}=${containerKey}`,
|
|
312
|
+
];
|
|
313
|
+
if (conversationId) {
|
|
314
|
+
labels.push("--label", `${DockerContainerManager.CONVERSATION_ID_LABEL_KEY}=${conversationId}`);
|
|
315
|
+
}
|
|
316
|
+
labels.push("--label", `${DockerContainerManager.MOUNT_SIGNATURE_LABEL_KEY}=${this.mountSignature(bindSpecs.map(bindSpecToMount))}`);
|
|
317
|
+
await this.execFileImpl("docker", [
|
|
318
|
+
"create",
|
|
319
|
+
"--name",
|
|
320
|
+
containerName,
|
|
321
|
+
"--network",
|
|
322
|
+
networkName,
|
|
323
|
+
"--cap-drop",
|
|
324
|
+
"ALL",
|
|
325
|
+
"--security-opt",
|
|
326
|
+
"no-new-privileges",
|
|
327
|
+
"--pids-limit",
|
|
328
|
+
"1024",
|
|
329
|
+
...labels,
|
|
330
|
+
...this.resourceLimitArgs(this.effectiveLimits(containerKey)),
|
|
331
|
+
...bindSpecs.flatMap((bind) => ["-v", bind]),
|
|
332
|
+
snapshotImage,
|
|
333
|
+
"sleep",
|
|
334
|
+
"infinity",
|
|
335
|
+
]);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Recreate a drifted container with the desired mounts while keeping its
|
|
339
|
+
* writable layer: commit — the new binds ride the snapshot label, so a
|
|
340
|
+
* crash at any point resumes through the layout-migration path — then
|
|
341
|
+
* remove, create from the snapshot, and start. Committing replaces any
|
|
342
|
+
* older snapshot tag for this container; the untagged predecessor is
|
|
343
|
+
* removed once the new container is up.
|
|
344
|
+
*/
|
|
345
|
+
async recreateContainerPreservingContents(containerKey, containerName, mounts) {
|
|
346
|
+
const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;
|
|
347
|
+
const bindSpecs = mounts.map((mount) => this.toBindSpec(mount));
|
|
348
|
+
const previousImageId = await this.readImageId(snapshotImage);
|
|
349
|
+
await this.execFileImpl("docker", [
|
|
350
|
+
"commit",
|
|
351
|
+
"-c",
|
|
352
|
+
`LABEL ${DockerContainerManager.MIGRATE_BINDS_LABEL_KEY}=${JSON.stringify(JSON.stringify(bindSpecs))}`,
|
|
353
|
+
containerName,
|
|
354
|
+
snapshotImage,
|
|
355
|
+
]);
|
|
356
|
+
await this.execFileImpl("docker", ["rm", "-f", containerName]);
|
|
357
|
+
await this.createContainerFromSnapshot(containerName, bindSpecs, containerKey);
|
|
358
|
+
await this.execFileImpl("docker", ["start", containerName]);
|
|
359
|
+
const currentImageId = await this.readImageId(snapshotImage);
|
|
360
|
+
if (previousImageId && previousImageId !== currentImageId) {
|
|
361
|
+
try {
|
|
362
|
+
await this.execFileImpl("docker", ["rmi", previousImageId]);
|
|
363
|
+
}
|
|
364
|
+
catch (err) {
|
|
365
|
+
log.logWarning(`Could not remove superseded snapshot image ${previousImageId}`, String(err));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/** Resolved image id for a reference, or undefined when it does not exist. */
|
|
370
|
+
async readImageId(image) {
|
|
371
|
+
try {
|
|
372
|
+
const { stdout } = await this.execFileImpl("docker", ["inspect", "-f", "{{.Id}}", image]);
|
|
373
|
+
const id = stdout.trim();
|
|
374
|
+
return id.length > 0 ? id : undefined;
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/** Binds recorded on a snapshot image, or undefined when no snapshot exists. */
|
|
381
|
+
async readMigrateImageBinds(snapshotImage) {
|
|
382
|
+
const raw = await this.readImageLabel(snapshotImage, DockerContainerManager.MIGRATE_BINDS_LABEL_KEY);
|
|
383
|
+
if (raw === undefined)
|
|
384
|
+
return undefined;
|
|
385
|
+
const parsed = JSON.parse(raw);
|
|
386
|
+
if (!Array.isArray(parsed) || parsed.some((bind) => typeof bind !== "string")) {
|
|
387
|
+
throw new Error(`Snapshot image ${snapshotImage} carries malformed migrate binds`);
|
|
388
|
+
}
|
|
389
|
+
return parsed;
|
|
390
|
+
}
|
|
391
|
+
async readImageLabel(image, key) {
|
|
392
|
+
try {
|
|
393
|
+
const { stdout } = await this.execFileImpl("docker", [
|
|
394
|
+
"inspect",
|
|
395
|
+
"-f",
|
|
396
|
+
`{{index .Config.Labels "${key}"}}`,
|
|
397
|
+
image,
|
|
398
|
+
]);
|
|
399
|
+
return this.normalizeDockerValue(stdout.trim());
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
return undefined;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Delete a container's layout snapshot after an intentional removal, so a
|
|
407
|
+
* missing container plus a surviving snapshot can only mean a crash in the
|
|
408
|
+
* middle of the layout migration (the resume discriminator).
|
|
409
|
+
*/
|
|
410
|
+
async removeMigrateSnapshot(containerName) {
|
|
411
|
+
try {
|
|
412
|
+
await this.execFileImpl("docker", [
|
|
413
|
+
"rmi",
|
|
414
|
+
`${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`,
|
|
415
|
+
]);
|
|
416
|
+
}
|
|
417
|
+
catch {
|
|
418
|
+
// No snapshot for this container — the common case.
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
async listMigrateSnapshotContainerNames() {
|
|
422
|
+
try {
|
|
423
|
+
const { stdout } = await this.execFileImpl("docker", [
|
|
424
|
+
"images",
|
|
425
|
+
DockerContainerManager.MIGRATE_IMAGE_PREFIX,
|
|
426
|
+
"--format",
|
|
427
|
+
"{{.Tag}}",
|
|
428
|
+
]);
|
|
429
|
+
return this.parseNameLines(stdout);
|
|
430
|
+
}
|
|
431
|
+
catch {
|
|
432
|
+
return [];
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
async removeDanglingMigrateImages() {
|
|
436
|
+
let stdout;
|
|
437
|
+
try {
|
|
438
|
+
({ stdout } = await this.execFileImpl("docker", [
|
|
439
|
+
"images",
|
|
440
|
+
`${DockerContainerManager.MIGRATE_IMAGE_PREFIX}`,
|
|
441
|
+
"--format",
|
|
442
|
+
"{{.Repository}}:{{.Tag}}",
|
|
443
|
+
]));
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
for (const image of this.parseNameLines(stdout)) {
|
|
449
|
+
const containerName = image.slice(DockerContainerManager.MIGRATE_IMAGE_PREFIX.length + 1);
|
|
450
|
+
const status = await this.inspectStatus(containerName);
|
|
451
|
+
if (status !== "missing") {
|
|
452
|
+
// Still referenced (until the container's next natural recreation
|
|
453
|
+
// from the base image); keep the snapshot.
|
|
454
|
+
const { stdout: imageRef } = await this.execFileImpl("docker", [
|
|
455
|
+
"inspect",
|
|
456
|
+
"-f",
|
|
457
|
+
"{{.Config.Image}}",
|
|
458
|
+
containerName,
|
|
459
|
+
]);
|
|
460
|
+
if (imageRef.trim() === image)
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
try {
|
|
464
|
+
await this.execFileImpl("docker", ["rmi", image]);
|
|
465
|
+
log.logInfo(`Removed layout-migration snapshot image ${image}`);
|
|
466
|
+
}
|
|
467
|
+
catch (err) {
|
|
468
|
+
log.logWarning(`Could not remove snapshot image ${image}`, String(err));
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
161
472
|
async reconcile() {
|
|
162
473
|
const discovered = new Set();
|
|
163
474
|
const labeledNames = await this.listContainerNamesByLabel();
|
|
@@ -204,7 +515,10 @@ export class DockerContainerManager {
|
|
|
204
515
|
return mounts.flatMap((mount) => ["-v", this.toBindSpec(mount)]);
|
|
205
516
|
}
|
|
206
517
|
toBindSpec(mount) {
|
|
207
|
-
|
|
518
|
+
// The `:ro` suffix is part of the bind spec, so it also flows into
|
|
519
|
+
// expectedBinds/mountSignature — flipping a mount's writability is drift
|
|
520
|
+
// and recreates the container rather than leaving a stale writable bind.
|
|
521
|
+
return `${mount.source}:${mount.target}${mount.readOnly ? ":ro" : ""}`;
|
|
208
522
|
}
|
|
209
523
|
async runContainer(containerKey, containerName, mounts, options) {
|
|
210
524
|
const networkName = await this.ensureNetwork(containerKey);
|
|
@@ -343,9 +657,17 @@ export class DockerContainerManager {
|
|
|
343
657
|
try {
|
|
344
658
|
const stat = statSync(source);
|
|
345
659
|
if (stat.isFile()) {
|
|
660
|
+
// Files are atomically replaced (rename), which leaves the container
|
|
661
|
+
// holding a stale inode — content changes must recreate the mount.
|
|
346
662
|
return createHash("sha256").update(readFileSync(source)).digest("hex");
|
|
347
663
|
}
|
|
348
|
-
|
|
664
|
+
// Directories: a bind mount follows changes inside the directory live,
|
|
665
|
+
// so only replacing the directory itself makes the mount stale.
|
|
666
|
+
// Size/mtime churn from ordinary activity — event files coming and
|
|
667
|
+
// going, children being created — must not read as drift. Identity is
|
|
668
|
+
// dev:ino plus birth time, because ext4 recycles inode numbers
|
|
669
|
+
// immediately and a same-path replacement can reuse the old one.
|
|
670
|
+
return `${stat.isDirectory() ? "dir" : "other"}:${stat.dev}:${stat.ino}:${stat.birthtimeMs}`;
|
|
349
671
|
}
|
|
350
672
|
catch {
|
|
351
673
|
return "missing";
|