@geminixiang/mikan 1.0.0-beta.4 → 1.0.0-beta.40
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 +688 -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 +82 -117
- package/dist/adapters/discord/bot.js.map +1 -1
- 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 +54 -215
- package/dist/adapters/discord/context.js.map +1 -1
- 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/progressive-renderer.d.ts +7 -0
- package/dist/adapters/progressive-renderer.d.ts.map +1 -0
- package/dist/adapters/progressive-renderer.js +383 -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/blocks.d.ts +14 -0
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +147 -111
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +43 -13
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +385 -207
- 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 +126 -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/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 +90 -117
- 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 +61 -184
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/telegram/html.d.ts.map +1 -1
- package/dist/adapters/telegram/html.js +10 -7
- package/dist/adapters/telegram/html.js.map +1 -1
- package/dist/adapters/types.d.ts +109 -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 +840 -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.map +1 -1
- package/dist/commands/extensions.js +9 -6
- 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 +229 -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 +39 -0
- package/dist/harness/subagent-runner.d.ts.map +1 -0
- package/dist/harness/subagent-runner.js +617 -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 +43 -0
- package/dist/subagent-progress.d.ts.map +1 -0
- package/dist/subagent-progress.js +220 -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 +54 -0
- package/dist/tools/subagent.d.ts.map +1 -0
- package/dist/tools/subagent.js +411 -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 +403 -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 +846 -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 +67 -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/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
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Conversation office module: canonical identity (`address.ts`), the
|
|
3
|
+
* Workspace/Office layout values (`layout.ts`), the durable registry journal
|
|
4
|
+
* (`registry.ts`), and the boot-time legacy migration (`migration.ts`).
|
|
5
|
+
* Everything outside `src/office/` imports from this barrel.
|
|
6
|
+
*/
|
|
7
|
+
export { assertConversationId, assertOfficeKey, assertPlatformName, createOfficeAddress, isOfficeKey, officeKey, officeStateDir, sameOffice, validateOfficeAddress, } from "./address.js";
|
|
8
|
+
export { createWorkspace, officeSessionsDir, RESERVED_WORKSPACE_NAMES, type Office, type Workspace, } from "./layout.js";
|
|
9
|
+
export { listRegisteredOffices, OfficeRegistry, resolveOwnedOfficeAddress } from "./registry.js";
|
|
10
|
+
export { buildContainerBindTranslator, formatUnmigratedOfficesError, migrateLegacyOffices, } from "./migration.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/office/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,SAAS,EACT,cAAc,EACd,UAAU,EACV,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,KAAK,MAAM,EACX,KAAK,SAAS,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Conversation office module: canonical identity (`address.ts`), the
|
|
3
|
+
* Workspace/Office layout values (`layout.ts`), the durable registry journal
|
|
4
|
+
* (`registry.ts`), and the boot-time legacy migration (`migration.ts`).
|
|
5
|
+
* Everything outside `src/office/` imports from this barrel.
|
|
6
|
+
*/
|
|
7
|
+
export { assertConversationId, assertOfficeKey, assertPlatformName, createOfficeAddress, isOfficeKey, officeKey, officeStateDir, sameOffice, validateOfficeAddress, } from "./address.js";
|
|
8
|
+
export { createWorkspace, officeSessionsDir, RESERVED_WORKSPACE_NAMES, } from "./layout.js";
|
|
9
|
+
export { listRegisteredOffices, OfficeRegistry, resolveOwnedOfficeAddress } from "./registry.js";
|
|
10
|
+
export { buildContainerBindTranslator, formatUnmigratedOfficesError, migrateLegacyOffices, } from "./migration.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/office/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,SAAS,EACT,cAAc,EACd,UAAU,EACV,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,wBAAwB,GAGzB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,gBAAgB,CAAC","sourcesContent":["/**\n * The Conversation office module: canonical identity (`address.ts`), the\n * Workspace/Office layout values (`layout.ts`), the durable registry journal\n * (`registry.ts`), and the boot-time legacy migration (`migration.ts`).\n * Everything outside `src/office/` imports from this barrel.\n */\nexport {\n assertConversationId,\n assertOfficeKey,\n assertPlatformName,\n createOfficeAddress,\n isOfficeKey,\n officeKey,\n officeStateDir,\n sameOffice,\n validateOfficeAddress,\n} from \"./address.js\";\nexport {\n createWorkspace,\n officeSessionsDir,\n RESERVED_WORKSPACE_NAMES,\n type Office,\n type Workspace,\n} from \"./layout.js\";\nexport { listRegisteredOffices, OfficeRegistry, resolveOwnedOfficeAddress } from \"./registry.js\";\nexport {\n buildContainerBindTranslator,\n formatUnmigratedOfficesError,\n migrateLegacyOffices,\n} from \"./migration.js\";\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Workspace } from "./types.js";
|
|
2
|
+
export type { Office, Workspace } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Workspace-root entries that are shared infrastructure, never office dirs.
|
|
5
|
+
* The single definition behind boot-time directory setup, the events
|
|
6
|
+
* watcher, the workspace projection, and the migration's legacy-dir scan.
|
|
7
|
+
*/
|
|
8
|
+
export declare const RESERVED_WORKSPACE_NAMES: ReadonlySet<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Construct the Workspace value for a deployment. One construction site per
|
|
11
|
+
* process (main.ts for the daemon; CLI subcommands and tests build their
|
|
12
|
+
* own). The value owns the registry instance and the recorded-office cache
|
|
13
|
+
* that office materialization uses on hot paths, so there is no process-wide
|
|
14
|
+
* registry state.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* An office's session files live in `<office dir>/sessions` — the one home of
|
|
18
|
+
* that rule. String-based for surfaces that hold a conversation dir rather
|
|
19
|
+
* than an `Office` value (mirrors `officeStateDir`); `Office.sessionsDir` is
|
|
20
|
+
* derived from it. Pointer/thread-file semantics live in `sessions/store`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function officeSessionsDir(officeDir: string): string;
|
|
23
|
+
export declare function createWorkspace(options: {
|
|
24
|
+
root: string;
|
|
25
|
+
stateDir: string;
|
|
26
|
+
}): Workspace;
|
|
27
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/office/layout.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,YAAY,CAAC;AAIpD,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAExD,CAAC;AAEF;;;;;;GAMG;AACH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAsDtF"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { lstatSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { officeKey, validateOfficeAddress } from "./address.js";
|
|
4
|
+
import { OfficeRegistry } from "./registry.js";
|
|
5
|
+
/**
|
|
6
|
+
* Workspace-root entries that are shared infrastructure, never office dirs.
|
|
7
|
+
* The single definition behind boot-time directory setup, the events
|
|
8
|
+
* watcher, the workspace projection, and the migration's legacy-dir scan.
|
|
9
|
+
*/
|
|
10
|
+
export const RESERVED_WORKSPACE_NAMES = Object.freeze(new Set(["skills", "events", "agents", "MEMORY.md"]));
|
|
11
|
+
/**
|
|
12
|
+
* Construct the Workspace value for a deployment. One construction site per
|
|
13
|
+
* process (main.ts for the daemon; CLI subcommands and tests build their
|
|
14
|
+
* own). The value owns the registry instance and the recorded-office cache
|
|
15
|
+
* that office materialization uses on hot paths, so there is no process-wide
|
|
16
|
+
* registry state.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* An office's session files live in `<office dir>/sessions` — the one home of
|
|
20
|
+
* that rule. String-based for surfaces that hold a conversation dir rather
|
|
21
|
+
* than an `Office` value (mirrors `officeStateDir`); `Office.sessionsDir` is
|
|
22
|
+
* derived from it. Pointer/thread-file semantics live in `sessions/store`.
|
|
23
|
+
*/
|
|
24
|
+
export function officeSessionsDir(officeDir) {
|
|
25
|
+
return join(officeDir, "sessions");
|
|
26
|
+
}
|
|
27
|
+
export function createWorkspace(options) {
|
|
28
|
+
// Paths are joined as given (no resolve) so values match what callers
|
|
29
|
+
// passing the same root/stateDir strings computed before this module.
|
|
30
|
+
const { root, stateDir } = options;
|
|
31
|
+
// Lazy: CLI surfaces construct a Workspace for path math without paying
|
|
32
|
+
// for (or being allowed to create) the registry journal.
|
|
33
|
+
let registry;
|
|
34
|
+
const recorded = new Set();
|
|
35
|
+
const offices = new Map();
|
|
36
|
+
const workspace = Object.freeze({
|
|
37
|
+
root,
|
|
38
|
+
stateDir,
|
|
39
|
+
memoryPath: join(root, "MEMORY.md"),
|
|
40
|
+
skillsDir: join(root, "skills"),
|
|
41
|
+
eventsDir: join(root, "events"),
|
|
42
|
+
agentsDir: join(root, "agents"),
|
|
43
|
+
reservedNames: RESERVED_WORKSPACE_NAMES,
|
|
44
|
+
office(address) {
|
|
45
|
+
const normalized = validateOfficeAddress(address);
|
|
46
|
+
const key = officeKey(normalized);
|
|
47
|
+
const existing = offices.get(key);
|
|
48
|
+
if (existing)
|
|
49
|
+
return existing;
|
|
50
|
+
const dir = join(root, key);
|
|
51
|
+
const office = Object.freeze({
|
|
52
|
+
address: normalized,
|
|
53
|
+
key,
|
|
54
|
+
dir,
|
|
55
|
+
memoryPath: join(dir, "MEMORY.md"),
|
|
56
|
+
skillsDir: join(dir, "skills"),
|
|
57
|
+
sessionsDir: officeSessionsDir(dir),
|
|
58
|
+
attachmentsDir: join(dir, "attachments"),
|
|
59
|
+
logPath: join(dir, "log.jsonl"),
|
|
60
|
+
stateDir: join(stateDir, "conversations", key),
|
|
61
|
+
workspace,
|
|
62
|
+
ensure() {
|
|
63
|
+
// Record-first ordering: a crash can leave a record without a
|
|
64
|
+
// directory (harmless; recreated on the next message) but never an
|
|
65
|
+
// anonymous office directory the registry cannot enumerate.
|
|
66
|
+
if (!recorded.has(key)) {
|
|
67
|
+
registry ??= new OfficeRegistry(stateDir);
|
|
68
|
+
registry.recordOffice(normalized);
|
|
69
|
+
recorded.add(key);
|
|
70
|
+
}
|
|
71
|
+
ensureRegularOfficeDirectory(dir);
|
|
72
|
+
return dir;
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
offices.set(key, office);
|
|
76
|
+
return office;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
return workspace;
|
|
80
|
+
}
|
|
81
|
+
/** mkdir-if-missing with the same fail-closed type guard as projection roots. */
|
|
82
|
+
function ensureRegularOfficeDirectory(dir) {
|
|
83
|
+
let stats;
|
|
84
|
+
try {
|
|
85
|
+
stats = lstatSync(dir);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
if (err.code !== "ENOENT")
|
|
89
|
+
throw err;
|
|
90
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (stats.isSymbolicLink() || !stats.isDirectory()) {
|
|
94
|
+
throw new Error(`Office directory must be a regular non-symlink directory: ${dir}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/office/layout.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstatSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { OfficeAddress } from \"../types.js\";\nimport type { Office, Workspace } from \"./types.js\";\nimport { officeKey, validateOfficeAddress } from \"./address.js\";\nimport { OfficeRegistry } from \"./registry.js\";\n\nexport type { Office, Workspace } from \"./types.js\";\n\n/**\n * Workspace-root entries that are shared infrastructure, never office dirs.\n * The single definition behind boot-time directory setup, the events\n * watcher, the workspace projection, and the migration's legacy-dir scan.\n */\nexport const RESERVED_WORKSPACE_NAMES: ReadonlySet<string> = Object.freeze(\n new Set([\"skills\", \"events\", \"agents\", \"MEMORY.md\"]),\n);\n\n/**\n * Construct the Workspace value for a deployment. One construction site per\n * process (main.ts for the daemon; CLI subcommands and tests build their\n * own). The value owns the registry instance and the recorded-office cache\n * that office materialization uses on hot paths, so there is no process-wide\n * registry state.\n */\n/**\n * An office's session files live in `<office dir>/sessions` — the one home of\n * that rule. String-based for surfaces that hold a conversation dir rather\n * than an `Office` value (mirrors `officeStateDir`); `Office.sessionsDir` is\n * derived from it. Pointer/thread-file semantics live in `sessions/store`.\n */\nexport function officeSessionsDir(officeDir: string): string {\n return join(officeDir, \"sessions\");\n}\n\nexport function createWorkspace(options: { root: string; stateDir: string }): Workspace {\n // Paths are joined as given (no resolve) so values match what callers\n // passing the same root/stateDir strings computed before this module.\n const { root, stateDir } = options;\n // Lazy: CLI surfaces construct a Workspace for path math without paying\n // for (or being allowed to create) the registry journal.\n let registry: OfficeRegistry | undefined;\n const recorded = new Set<string>();\n const offices = new Map<string, Office>();\n\n const workspace: Workspace = Object.freeze({\n root,\n stateDir,\n memoryPath: join(root, \"MEMORY.md\"),\n skillsDir: join(root, \"skills\"),\n eventsDir: join(root, \"events\"),\n agentsDir: join(root, \"agents\"),\n reservedNames: RESERVED_WORKSPACE_NAMES,\n office(address: OfficeAddress): Office {\n const normalized = validateOfficeAddress(address);\n const key = officeKey(normalized);\n const existing = offices.get(key);\n if (existing) return existing;\n\n const dir = join(root, key);\n const office: Office = Object.freeze({\n address: normalized,\n key,\n dir,\n memoryPath: join(dir, \"MEMORY.md\"),\n skillsDir: join(dir, \"skills\"),\n sessionsDir: officeSessionsDir(dir),\n attachmentsDir: join(dir, \"attachments\"),\n logPath: join(dir, \"log.jsonl\"),\n stateDir: join(stateDir, \"conversations\", key),\n workspace,\n ensure(): string {\n // Record-first ordering: a crash can leave a record without a\n // directory (harmless; recreated on the next message) but never an\n // anonymous office directory the registry cannot enumerate.\n if (!recorded.has(key)) {\n registry ??= new OfficeRegistry(stateDir);\n registry.recordOffice(normalized);\n recorded.add(key);\n }\n ensureRegularOfficeDirectory(dir);\n return dir;\n },\n });\n offices.set(key, office);\n return office;\n },\n });\n return workspace;\n}\n\n/** mkdir-if-missing with the same fail-closed type guard as projection roots. */\nfunction ensureRegularOfficeDirectory(dir: string): void {\n let stats;\n try {\n stats = lstatSync(dir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") throw err;\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n return;\n }\n if (stats.isSymbolicLink() || !stats.isDirectory()) {\n throw new Error(`Office directory must be a regular non-symlink directory: ${dir}`);\n }\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { OfficeRecord } from "../types.js";
|
|
2
|
+
import type { PlatformName } from "../types.js";
|
|
3
|
+
export interface OfficeMigrationRunSummary {
|
|
4
|
+
/** Raw ids whose directories moved to the office-key layout this run. */
|
|
5
|
+
migrated: string[];
|
|
6
|
+
/** Raw ids whose interrupted moves were completed from the journal. */
|
|
7
|
+
recovered: string[];
|
|
8
|
+
/** Raw ids that still need an explicit owner (`mikan office claim`). */
|
|
9
|
+
unowned: string[];
|
|
10
|
+
/** Raw ids whose records are failed and need operator repair. */
|
|
11
|
+
failed: string[];
|
|
12
|
+
/** Raw ids whose conversation vault directories moved to office keys. */
|
|
13
|
+
vaultKeysMigrated: string[];
|
|
14
|
+
/** Raw ids whose legacy and office-key vault dirs both exist (manual merge). */
|
|
15
|
+
vaultConflicts: string[];
|
|
16
|
+
/** Raw ids whose host state dirs (settings, extensions, data) moved. */
|
|
17
|
+
stateDirsMigrated: string[];
|
|
18
|
+
/** Raw ids whose legacy and office-key state dirs both exist (manual merge). */
|
|
19
|
+
stateDirConflicts: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Move every legacy raw-id office directory under the workspace root to the
|
|
23
|
+
* canonical office-key layout, journaling each move through the office
|
|
24
|
+
* registry so an interrupted run resumes instead of losing offices.
|
|
25
|
+
*
|
|
26
|
+
* The engine never guesses: with several enabled platforms an unowned raw
|
|
27
|
+
* directory stays in place and is reported for `mikan office claim`. Callers
|
|
28
|
+
* must treat a non-empty `unowned`/`failed` as fatal for daemon boot — after
|
|
29
|
+
* the layout flip, an unmigrated legacy directory is invisible to the
|
|
30
|
+
* runtime, which would silently present the conversation as empty.
|
|
31
|
+
*/
|
|
32
|
+
export declare function migrateLegacyOffices(options: {
|
|
33
|
+
workspaceRoot: string;
|
|
34
|
+
stateDir: string;
|
|
35
|
+
enabledPlatforms: readonly PlatformName[];
|
|
36
|
+
}): OfficeMigrationRunSummary;
|
|
37
|
+
/** Operator-facing boot failure for offices the engine may not move itself. */
|
|
38
|
+
export declare function formatUnmigratedOfficesError(summary: OfficeMigrationRunSummary): string;
|
|
39
|
+
export declare function buildContainerBindTranslator(options: {
|
|
40
|
+
offices: readonly OfficeRecord[];
|
|
41
|
+
workspaceRoot: string;
|
|
42
|
+
stateDir: string;
|
|
43
|
+
}): (bindSpec: string) => string;
|
|
44
|
+
//# sourceMappingURL=migration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../src/office/migration.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,KAAK,EAAyB,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,WAAW,yBAAyB;IACxC,yEAAyE;IACzE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uEAAuE;IACvE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,wEAAwE;IACxE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,iEAAiE;IACjE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,yEAAyE;IACzE,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gFAAgF;IAChF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,wEAAwE;IACxE,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gFAAgF;IAChF,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C,GAAG,yBAAyB,CAqC5B;AA4JD,+EAA+E;AAC/E,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,CAsCvF;AAkBD,wBAAgB,4BAA4B,CAAC,OAAO,EAAE;IACpD,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CA2B/B"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { existsSync, lstatSync, readdirSync, renameSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import * as log from "../log.js";
|
|
4
|
+
import { isOfficeKey, officeKey, officeStateDir } from "./address.js";
|
|
5
|
+
import { RESERVED_WORKSPACE_NAMES } from "./layout.js";
|
|
6
|
+
import { legacyConversationCredentialKey } from "../sandbox/identity.js";
|
|
7
|
+
import { OfficeRegistry } from "./registry.js";
|
|
8
|
+
import { migrateConversationVaultKeys } from "../vault/index.js";
|
|
9
|
+
/**
|
|
10
|
+
* Move every legacy raw-id office directory under the workspace root to the
|
|
11
|
+
* canonical office-key layout, journaling each move through the office
|
|
12
|
+
* registry so an interrupted run resumes instead of losing offices.
|
|
13
|
+
*
|
|
14
|
+
* The engine never guesses: with several enabled platforms an unowned raw
|
|
15
|
+
* directory stays in place and is reported for `mikan office claim`. Callers
|
|
16
|
+
* must treat a non-empty `unowned`/`failed` as fatal for daemon boot — after
|
|
17
|
+
* the layout flip, an unmigrated legacy directory is invisible to the
|
|
18
|
+
* runtime, which would silently present the conversation as empty.
|
|
19
|
+
*/
|
|
20
|
+
export function migrateLegacyOffices(options) {
|
|
21
|
+
const registry = new OfficeRegistry(options.stateDir);
|
|
22
|
+
for (const platform of options.enabledPlatforms)
|
|
23
|
+
registry.enablePlatform(platform);
|
|
24
|
+
const summary = {
|
|
25
|
+
migrated: [],
|
|
26
|
+
recovered: [],
|
|
27
|
+
unowned: [],
|
|
28
|
+
failed: [],
|
|
29
|
+
vaultKeysMigrated: [],
|
|
30
|
+
vaultConflicts: [],
|
|
31
|
+
stateDirsMigrated: [],
|
|
32
|
+
stateDirConflicts: [],
|
|
33
|
+
};
|
|
34
|
+
recoverInterruptedMoves(registry, summary);
|
|
35
|
+
claimAndMoveLegacyDirs(registry, options.workspaceRoot, summary);
|
|
36
|
+
// Credential vaults are keyed by office too; the registry inventory (which
|
|
37
|
+
// the directory moves above just extended) drives the same rename.
|
|
38
|
+
const vaults = migrateConversationVaultKeys({
|
|
39
|
+
stateDir: options.stateDir,
|
|
40
|
+
offices: registry.getOffices(),
|
|
41
|
+
});
|
|
42
|
+
summary.vaultKeysMigrated = vaults.migrated;
|
|
43
|
+
summary.vaultConflicts = vaults.conflicts;
|
|
44
|
+
for (const rawConversationId of vaults.migrated) {
|
|
45
|
+
log.logInfo(`[office] Migrated vault key to office key: ${rawConversationId}`);
|
|
46
|
+
}
|
|
47
|
+
migrateConversationStateDirs(registry, options.stateDir, summary);
|
|
48
|
+
for (const record of registry.getState().migrations) {
|
|
49
|
+
if (record.status === "needs-owner")
|
|
50
|
+
summary.unowned.push(record.rawConversationId);
|
|
51
|
+
else if (record.status === "failed")
|
|
52
|
+
summary.failed.push(record.rawConversationId);
|
|
53
|
+
}
|
|
54
|
+
return summary;
|
|
55
|
+
}
|
|
56
|
+
/** Complete or fail every move the journal says was interrupted mid-rename. */
|
|
57
|
+
function recoverInterruptedMoves(registry, summary) {
|
|
58
|
+
for (const record of registry.getState().migrations) {
|
|
59
|
+
if (record.status !== "moving")
|
|
60
|
+
continue;
|
|
61
|
+
const targetDir = record.targetDir;
|
|
62
|
+
if (!targetDir) {
|
|
63
|
+
registry.markFailed(record.rawConversationId, "Moving record has no target directory");
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const sourceExists = pathExists(record.sourceDir);
|
|
67
|
+
const targetExists = pathExists(targetDir);
|
|
68
|
+
if (sourceExists && targetExists) {
|
|
69
|
+
registry.markFailed(record.rawConversationId, "Both legacy source and office target exist; merge them manually");
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!sourceExists && !targetExists) {
|
|
73
|
+
registry.markFailed(record.rawConversationId, "Neither legacy source nor office target exists");
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (sourceExists)
|
|
77
|
+
renameSync(record.sourceDir, targetDir);
|
|
78
|
+
registry.markCommitted(record.rawConversationId);
|
|
79
|
+
recordMigratedOffice(registry, record);
|
|
80
|
+
summary.recovered.push(record.rawConversationId);
|
|
81
|
+
log.logInfo(`[office] Recovered interrupted migration: ${record.rawConversationId}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Scan the workspace root and move every claimable legacy office directory. */
|
|
85
|
+
function claimAndMoveLegacyDirs(registry, workspaceRoot, summary) {
|
|
86
|
+
for (const rawConversationId of listLegacyOfficeDirs(workspaceRoot)) {
|
|
87
|
+
const existing = registry.getMigration(rawConversationId);
|
|
88
|
+
if (existing?.status === "committed") {
|
|
89
|
+
// The move already happened; a raw-id dir with this name reappearing
|
|
90
|
+
// afterwards is a different (or resurrected) office the runtime can no
|
|
91
|
+
// longer see. Refusing to boot beats silently ignoring its data.
|
|
92
|
+
throw new Error(`Legacy office directory reappeared after migration: ${join(workspaceRoot, rawConversationId)}`);
|
|
93
|
+
}
|
|
94
|
+
if (existing?.status === "failed")
|
|
95
|
+
continue; // reported via summary.failed
|
|
96
|
+
const record = registry.prepareLegacyMigration({
|
|
97
|
+
rawConversationId,
|
|
98
|
+
sourceDir: join(workspaceRoot, rawConversationId),
|
|
99
|
+
workspaceRoot,
|
|
100
|
+
});
|
|
101
|
+
if (record.status === "needs-owner")
|
|
102
|
+
continue; // reported via summary.unowned
|
|
103
|
+
const moving = registry.markMoving(rawConversationId);
|
|
104
|
+
const targetDir = moving.targetDir;
|
|
105
|
+
if (!targetDir)
|
|
106
|
+
throw new Error("Moving office migration has no target directory");
|
|
107
|
+
renameSync(moving.sourceDir, targetDir);
|
|
108
|
+
registry.markCommitted(rawConversationId);
|
|
109
|
+
recordMigratedOffice(registry, moving);
|
|
110
|
+
summary.migrated.push(rawConversationId);
|
|
111
|
+
log.logInfo(`[office] Migrated office directory: ${rawConversationId} -> ${targetDir}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Move each registered office's host state tree — settings.json, extensions,
|
|
116
|
+
* extension-data, git checkouts — from `conversations/<rawId>` to
|
|
117
|
+
* `conversations/<officeKey>` in one rename. Conflicts are reported for
|
|
118
|
+
* manual merge, never clobbered.
|
|
119
|
+
*/
|
|
120
|
+
function migrateConversationStateDirs(registry, stateDir, summary) {
|
|
121
|
+
for (const office of registry.getOffices()) {
|
|
122
|
+
const legacyDir = join(stateDir, "conversations", office.conversationId);
|
|
123
|
+
if (!existsSync(legacyDir))
|
|
124
|
+
continue;
|
|
125
|
+
const targetDir = officeStateDir(stateDir, office);
|
|
126
|
+
if (existsSync(targetDir)) {
|
|
127
|
+
summary.stateDirConflicts.push(office.conversationId);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
renameSync(legacyDir, targetDir);
|
|
131
|
+
summary.stateDirsMigrated.push(office.conversationId);
|
|
132
|
+
log.logInfo(`[office] Migrated host state dir to office key: ${office.conversationId}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** A migrated office is an existing office; keep the directory enumerable. */
|
|
136
|
+
function recordMigratedOffice(registry, record) {
|
|
137
|
+
if (!record.ownerPlatform)
|
|
138
|
+
return;
|
|
139
|
+
registry.recordOffice({
|
|
140
|
+
platform: record.ownerPlatform,
|
|
141
|
+
conversationId: record.rawConversationId,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Legacy office candidates: regular directories that are not reserved
|
|
146
|
+
* infrastructure, not hidden, and not already office-key named. A symlink in
|
|
147
|
+
* office position is refused outright — following it could move data from
|
|
148
|
+
* outside the workspace root.
|
|
149
|
+
*
|
|
150
|
+
* A candidate must also look like a conversation office: every office that
|
|
151
|
+
* ever saw a message has a `log.jsonl`, and every office that ran the agent
|
|
152
|
+
* has `sessions/`. Trusted workspace roots legitimately accumulate other
|
|
153
|
+
* directories — repos the agent cloned, build output — which are not offices
|
|
154
|
+
* and must be neither renamed nor reported as unowned; they stay where they
|
|
155
|
+
* are (an operator can still claim one explicitly via `mikan office claim`).
|
|
156
|
+
*/
|
|
157
|
+
function listLegacyOfficeDirs(workspaceRoot) {
|
|
158
|
+
const candidates = [];
|
|
159
|
+
for (const entry of readdirSync(workspaceRoot, { withFileTypes: true })) {
|
|
160
|
+
if (entry.name.startsWith("."))
|
|
161
|
+
continue;
|
|
162
|
+
if (RESERVED_WORKSPACE_NAMES.has(entry.name))
|
|
163
|
+
continue;
|
|
164
|
+
if (isOfficeKey(entry.name))
|
|
165
|
+
continue;
|
|
166
|
+
if (entry.isSymbolicLink()) {
|
|
167
|
+
throw new Error(`Workspace entry must not be a symlink: ${join(workspaceRoot, entry.name)}`);
|
|
168
|
+
}
|
|
169
|
+
if (!entry.isDirectory())
|
|
170
|
+
continue;
|
|
171
|
+
if (!looksLikeConversationOffice(join(workspaceRoot, entry.name))) {
|
|
172
|
+
log.logInfo(`[office] Skipping non-office workspace directory (no log.jsonl or sessions/): ${entry.name}`);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
candidates.push(entry.name);
|
|
176
|
+
}
|
|
177
|
+
return candidates.toSorted();
|
|
178
|
+
}
|
|
179
|
+
function looksLikeConversationOffice(dir) {
|
|
180
|
+
return existsSync(join(dir, "log.jsonl")) || existsSync(join(dir, "sessions"));
|
|
181
|
+
}
|
|
182
|
+
function pathExists(path) {
|
|
183
|
+
try {
|
|
184
|
+
lstatSync(path);
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
if (err.code === "ENOENT")
|
|
189
|
+
return false;
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** Operator-facing boot failure for offices the engine may not move itself. */
|
|
194
|
+
export function formatUnmigratedOfficesError(summary) {
|
|
195
|
+
const lines = ["Conversation office migration cannot complete:"];
|
|
196
|
+
if (summary.unowned.length > 0) {
|
|
197
|
+
lines.push("", "These legacy conversation directories have no owning platform (several", "platforms are enabled, so ownership cannot be inferred):", ...summary.unowned.map((id) => ` - ${id}`), "", "Assign each one with:", " mikan office claim <conversationId> <platform>");
|
|
198
|
+
}
|
|
199
|
+
if (summary.failed.length > 0) {
|
|
200
|
+
lines.push("", "These migrations previously failed and need manual repair (see", "office-registry.json in the state dir for each error):", ...summary.failed.map((id) => ` - ${id}`));
|
|
201
|
+
}
|
|
202
|
+
if (summary.vaultConflicts.length > 0) {
|
|
203
|
+
lines.push("", "These conversations have credentials under both the legacy and the", "office-key vault directory; merge them manually under <state-dir>/vaults:", ...summary.vaultConflicts.map((id) => ` - ${id}`));
|
|
204
|
+
}
|
|
205
|
+
if (summary.stateDirConflicts.length > 0) {
|
|
206
|
+
lines.push("", "These conversations have host state under both the legacy and the", "office-key directory; merge them manually under <state-dir>/conversations:", ...summary.stateDirConflicts.map((id) => ` - ${id}`));
|
|
207
|
+
}
|
|
208
|
+
return lines.join("\n");
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Bind-spec translator for the container layout migration: rewrites every
|
|
212
|
+
* host path the office migration renamed — workspace dirs, per-conversation
|
|
213
|
+
* state trees, conversation vaults — and the guest workspace segment, using
|
|
214
|
+
* the registry's office inventory as the raw-id ↔ office mapping. Specs that
|
|
215
|
+
* reference none of the renamed paths come back unchanged, which is also how
|
|
216
|
+
* an already-migrated container is recognized.
|
|
217
|
+
*/
|
|
218
|
+
function replacePrefix(path, pairs) {
|
|
219
|
+
for (const [oldPrefix, newPrefix] of pairs) {
|
|
220
|
+
if (path === oldPrefix)
|
|
221
|
+
return newPrefix;
|
|
222
|
+
if (path.startsWith(`${oldPrefix}/`))
|
|
223
|
+
return newPrefix + path.slice(oldPrefix.length);
|
|
224
|
+
}
|
|
225
|
+
return path;
|
|
226
|
+
}
|
|
227
|
+
export function buildContainerBindTranslator(options) {
|
|
228
|
+
const hostPairs = [];
|
|
229
|
+
const guestPairs = [];
|
|
230
|
+
for (const office of options.offices) {
|
|
231
|
+
const key = officeKey(office);
|
|
232
|
+
const rawId = office.conversationId;
|
|
233
|
+
hostPairs.push([join(options.workspaceRoot, rawId), join(options.workspaceRoot, key)]);
|
|
234
|
+
hostPairs.push([
|
|
235
|
+
join(options.stateDir, "conversations", rawId),
|
|
236
|
+
officeStateDir(options.stateDir, office),
|
|
237
|
+
]);
|
|
238
|
+
hostPairs.push([
|
|
239
|
+
join(options.stateDir, "vaults", legacyConversationCredentialKey(rawId)),
|
|
240
|
+
join(options.stateDir, "vaults", key),
|
|
241
|
+
]);
|
|
242
|
+
guestPairs.push([`/workspace/${rawId}`, `/workspace/${key}`]);
|
|
243
|
+
}
|
|
244
|
+
return (bindSpec) => {
|
|
245
|
+
const readOnly = bindSpec.endsWith(":ro");
|
|
246
|
+
const spec = readOnly ? bindSpec.slice(0, -3) : bindSpec;
|
|
247
|
+
const separator = spec.indexOf(":");
|
|
248
|
+
if (separator === -1)
|
|
249
|
+
return bindSpec;
|
|
250
|
+
const source = replacePrefix(spec.slice(0, separator), hostPairs);
|
|
251
|
+
const target = replacePrefix(spec.slice(separator + 1), guestPairs);
|
|
252
|
+
return `${source}:${target}${readOnly ? ":ro" : ""}`;
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/office/migration.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, lstatSync, readdirSync, renameSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport * as log from \"../log.js\";\nimport { isOfficeKey, officeKey, officeStateDir } from \"./address.js\";\nimport { RESERVED_WORKSPACE_NAMES } from \"./layout.js\";\nimport { legacyConversationCredentialKey } from \"../sandbox/identity.js\";\nimport type { OfficeRecord } from \"../types.js\";\nimport { OfficeRegistry } from \"./registry.js\";\nimport { migrateConversationVaultKeys } from \"../vault/index.js\";\nimport type { OfficeMigrationRecord, PlatformName } from \"../types.js\";\n\nexport interface OfficeMigrationRunSummary {\n /** Raw ids whose directories moved to the office-key layout this run. */\n migrated: string[];\n /** Raw ids whose interrupted moves were completed from the journal. */\n recovered: string[];\n /** Raw ids that still need an explicit owner (`mikan office claim`). */\n unowned: string[];\n /** Raw ids whose records are failed and need operator repair. */\n failed: string[];\n /** Raw ids whose conversation vault directories moved to office keys. */\n vaultKeysMigrated: string[];\n /** Raw ids whose legacy and office-key vault dirs both exist (manual merge). */\n vaultConflicts: string[];\n /** Raw ids whose host state dirs (settings, extensions, data) moved. */\n stateDirsMigrated: string[];\n /** Raw ids whose legacy and office-key state dirs both exist (manual merge). */\n stateDirConflicts: string[];\n}\n\n/**\n * Move every legacy raw-id office directory under the workspace root to the\n * canonical office-key layout, journaling each move through the office\n * registry so an interrupted run resumes instead of losing offices.\n *\n * The engine never guesses: with several enabled platforms an unowned raw\n * directory stays in place and is reported for `mikan office claim`. Callers\n * must treat a non-empty `unowned`/`failed` as fatal for daemon boot — after\n * the layout flip, an unmigrated legacy directory is invisible to the\n * runtime, which would silently present the conversation as empty.\n */\nexport function migrateLegacyOffices(options: {\n workspaceRoot: string;\n stateDir: string;\n enabledPlatforms: readonly PlatformName[];\n}): OfficeMigrationRunSummary {\n const registry = new OfficeRegistry(options.stateDir);\n for (const platform of options.enabledPlatforms) registry.enablePlatform(platform);\n\n const summary: OfficeMigrationRunSummary = {\n migrated: [],\n recovered: [],\n unowned: [],\n failed: [],\n vaultKeysMigrated: [],\n vaultConflicts: [],\n stateDirsMigrated: [],\n stateDirConflicts: [],\n };\n\n recoverInterruptedMoves(registry, summary);\n claimAndMoveLegacyDirs(registry, options.workspaceRoot, summary);\n\n // Credential vaults are keyed by office too; the registry inventory (which\n // the directory moves above just extended) drives the same rename.\n const vaults = migrateConversationVaultKeys({\n stateDir: options.stateDir,\n offices: registry.getOffices(),\n });\n summary.vaultKeysMigrated = vaults.migrated;\n summary.vaultConflicts = vaults.conflicts;\n for (const rawConversationId of vaults.migrated) {\n log.logInfo(`[office] Migrated vault key to office key: ${rawConversationId}`);\n }\n\n migrateConversationStateDirs(registry, options.stateDir, summary);\n\n for (const record of registry.getState().migrations) {\n if (record.status === \"needs-owner\") summary.unowned.push(record.rawConversationId);\n else if (record.status === \"failed\") summary.failed.push(record.rawConversationId);\n }\n return summary;\n}\n\n/** Complete or fail every move the journal says was interrupted mid-rename. */\nfunction recoverInterruptedMoves(\n registry: OfficeRegistry,\n summary: OfficeMigrationRunSummary,\n): void {\n for (const record of registry.getState().migrations) {\n if (record.status !== \"moving\") continue;\n const targetDir = record.targetDir;\n if (!targetDir) {\n registry.markFailed(record.rawConversationId, \"Moving record has no target directory\");\n continue;\n }\n const sourceExists = pathExists(record.sourceDir);\n const targetExists = pathExists(targetDir);\n if (sourceExists && targetExists) {\n registry.markFailed(\n record.rawConversationId,\n \"Both legacy source and office target exist; merge them manually\",\n );\n continue;\n }\n if (!sourceExists && !targetExists) {\n registry.markFailed(\n record.rawConversationId,\n \"Neither legacy source nor office target exists\",\n );\n continue;\n }\n if (sourceExists) renameSync(record.sourceDir, targetDir);\n registry.markCommitted(record.rawConversationId);\n recordMigratedOffice(registry, record);\n summary.recovered.push(record.rawConversationId);\n log.logInfo(`[office] Recovered interrupted migration: ${record.rawConversationId}`);\n }\n}\n\n/** Scan the workspace root and move every claimable legacy office directory. */\nfunction claimAndMoveLegacyDirs(\n registry: OfficeRegistry,\n workspaceRoot: string,\n summary: OfficeMigrationRunSummary,\n): void {\n for (const rawConversationId of listLegacyOfficeDirs(workspaceRoot)) {\n const existing = registry.getMigration(rawConversationId);\n if (existing?.status === \"committed\") {\n // The move already happened; a raw-id dir with this name reappearing\n // afterwards is a different (or resurrected) office the runtime can no\n // longer see. Refusing to boot beats silently ignoring its data.\n throw new Error(\n `Legacy office directory reappeared after migration: ${join(workspaceRoot, rawConversationId)}`,\n );\n }\n if (existing?.status === \"failed\") continue; // reported via summary.failed\n\n const record = registry.prepareLegacyMigration({\n rawConversationId,\n sourceDir: join(workspaceRoot, rawConversationId),\n workspaceRoot,\n });\n if (record.status === \"needs-owner\") continue; // reported via summary.unowned\n\n const moving = registry.markMoving(rawConversationId);\n const targetDir = moving.targetDir;\n if (!targetDir) throw new Error(\"Moving office migration has no target directory\");\n renameSync(moving.sourceDir, targetDir);\n registry.markCommitted(rawConversationId);\n recordMigratedOffice(registry, moving);\n summary.migrated.push(rawConversationId);\n log.logInfo(`[office] Migrated office directory: ${rawConversationId} -> ${targetDir}`);\n }\n}\n\n/**\n * Move each registered office's host state tree — settings.json, extensions,\n * extension-data, git checkouts — from `conversations/<rawId>` to\n * `conversations/<officeKey>` in one rename. Conflicts are reported for\n * manual merge, never clobbered.\n */\nfunction migrateConversationStateDirs(\n registry: OfficeRegistry,\n stateDir: string,\n summary: OfficeMigrationRunSummary,\n): void {\n for (const office of registry.getOffices()) {\n const legacyDir = join(stateDir, \"conversations\", office.conversationId);\n if (!existsSync(legacyDir)) continue;\n const targetDir = officeStateDir(stateDir, office);\n if (existsSync(targetDir)) {\n summary.stateDirConflicts.push(office.conversationId);\n continue;\n }\n renameSync(legacyDir, targetDir);\n summary.stateDirsMigrated.push(office.conversationId);\n log.logInfo(`[office] Migrated host state dir to office key: ${office.conversationId}`);\n }\n}\n\n/** A migrated office is an existing office; keep the directory enumerable. */\nfunction recordMigratedOffice(registry: OfficeRegistry, record: OfficeMigrationRecord): void {\n if (!record.ownerPlatform) return;\n registry.recordOffice({\n platform: record.ownerPlatform,\n conversationId: record.rawConversationId,\n });\n}\n\n/**\n * Legacy office candidates: regular directories that are not reserved\n * infrastructure, not hidden, and not already office-key named. A symlink in\n * office position is refused outright — following it could move data from\n * outside the workspace root.\n *\n * A candidate must also look like a conversation office: every office that\n * ever saw a message has a `log.jsonl`, and every office that ran the agent\n * has `sessions/`. Trusted workspace roots legitimately accumulate other\n * directories — repos the agent cloned, build output — which are not offices\n * and must be neither renamed nor reported as unowned; they stay where they\n * are (an operator can still claim one explicitly via `mikan office claim`).\n */\nfunction listLegacyOfficeDirs(workspaceRoot: string): string[] {\n const candidates: string[] = [];\n for (const entry of readdirSync(workspaceRoot, { withFileTypes: true })) {\n if (entry.name.startsWith(\".\")) continue;\n if (RESERVED_WORKSPACE_NAMES.has(entry.name)) continue;\n if (isOfficeKey(entry.name)) continue;\n if (entry.isSymbolicLink()) {\n throw new Error(`Workspace entry must not be a symlink: ${join(workspaceRoot, entry.name)}`);\n }\n if (!entry.isDirectory()) continue;\n if (!looksLikeConversationOffice(join(workspaceRoot, entry.name))) {\n log.logInfo(\n `[office] Skipping non-office workspace directory (no log.jsonl or sessions/): ${entry.name}`,\n );\n continue;\n }\n candidates.push(entry.name);\n }\n return candidates.toSorted();\n}\n\nfunction looksLikeConversationOffice(dir: string): boolean {\n return existsSync(join(dir, \"log.jsonl\")) || existsSync(join(dir, \"sessions\"));\n}\n\nfunction pathExists(path: string): boolean {\n try {\n lstatSync(path);\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw err;\n }\n}\n\n/** Operator-facing boot failure for offices the engine may not move itself. */\nexport function formatUnmigratedOfficesError(summary: OfficeMigrationRunSummary): string {\n const lines = [\"Conversation office migration cannot complete:\"];\n if (summary.unowned.length > 0) {\n lines.push(\n \"\",\n \"These legacy conversation directories have no owning platform (several\",\n \"platforms are enabled, so ownership cannot be inferred):\",\n ...summary.unowned.map((id) => ` - ${id}`),\n \"\",\n \"Assign each one with:\",\n \" mikan office claim <conversationId> <platform>\",\n );\n }\n if (summary.failed.length > 0) {\n lines.push(\n \"\",\n \"These migrations previously failed and need manual repair (see\",\n \"office-registry.json in the state dir for each error):\",\n ...summary.failed.map((id) => ` - ${id}`),\n );\n }\n if (summary.vaultConflicts.length > 0) {\n lines.push(\n \"\",\n \"These conversations have credentials under both the legacy and the\",\n \"office-key vault directory; merge them manually under <state-dir>/vaults:\",\n ...summary.vaultConflicts.map((id) => ` - ${id}`),\n );\n }\n if (summary.stateDirConflicts.length > 0) {\n lines.push(\n \"\",\n \"These conversations have host state under both the legacy and the\",\n \"office-key directory; merge them manually under <state-dir>/conversations:\",\n ...summary.stateDirConflicts.map((id) => ` - ${id}`),\n );\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Bind-spec translator for the container layout migration: rewrites every\n * host path the office migration renamed — workspace dirs, per-conversation\n * state trees, conversation vaults — and the guest workspace segment, using\n * the registry's office inventory as the raw-id ↔ office mapping. Specs that\n * reference none of the renamed paths come back unchanged, which is also how\n * an already-migrated container is recognized.\n */\nfunction replacePrefix(path: string, pairs: Array<[string, string]>): string {\n for (const [oldPrefix, newPrefix] of pairs) {\n if (path === oldPrefix) return newPrefix;\n if (path.startsWith(`${oldPrefix}/`)) return newPrefix + path.slice(oldPrefix.length);\n }\n return path;\n}\n\nexport function buildContainerBindTranslator(options: {\n offices: readonly OfficeRecord[];\n workspaceRoot: string;\n stateDir: string;\n}): (bindSpec: string) => string {\n const hostPairs: Array<[string, string]> = [];\n const guestPairs: Array<[string, string]> = [];\n for (const office of options.offices) {\n const key = officeKey(office);\n const rawId = office.conversationId;\n hostPairs.push([join(options.workspaceRoot, rawId), join(options.workspaceRoot, key)]);\n hostPairs.push([\n join(options.stateDir, \"conversations\", rawId),\n officeStateDir(options.stateDir, office),\n ]);\n hostPairs.push([\n join(options.stateDir, \"vaults\", legacyConversationCredentialKey(rawId)),\n join(options.stateDir, \"vaults\", key),\n ]);\n guestPairs.push([`/workspace/${rawId}`, `/workspace/${key}`]);\n }\n\n return (bindSpec: string): string => {\n const readOnly = bindSpec.endsWith(\":ro\");\n const spec = readOnly ? bindSpec.slice(0, -3) : bindSpec;\n const separator = spec.indexOf(\":\");\n if (separator === -1) return bindSpec;\n const source = replacePrefix(spec.slice(0, separator), hostPairs);\n const target = replacePrefix(spec.slice(separator + 1), guestPairs);\n return `${source}:${target}${readOnly ? \":ro\" : \"\"}`;\n };\n}\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { OfficeAddress, OfficeMigrationPreparation, OfficeMigrationRecord, OfficeRecord, OfficeRegistryState, PlatformName } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Host-only office directory and migration journal.
|
|
4
|
+
*
|
|
5
|
+
* Office records are the durable raw-id ↔ (platform, office) mapping: the
|
|
6
|
+
* ADR 0005 layout migration renamed workspace dirs to office keys, so dir
|
|
7
|
+
* names carry no raw platform ids and enumeration/legacy-scope lookups
|
|
8
|
+
* resolve through these records. Migration records track claiming legacy
|
|
9
|
+
* raw-id directories. Office materialization lives in `layout.ts`; this
|
|
10
|
+
* module owns only the durable record and its crash-safe transitions.
|
|
11
|
+
*/
|
|
12
|
+
interface OfficeRegistryOptions {
|
|
13
|
+
writeState?: (path: string, content: string) => void;
|
|
14
|
+
lockTimeoutMs?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare class OfficeRegistry {
|
|
17
|
+
private readonly stateDir;
|
|
18
|
+
private readonly registryPath;
|
|
19
|
+
private readonly lockPath;
|
|
20
|
+
private readonly writeState;
|
|
21
|
+
private readonly lockTimeoutMs;
|
|
22
|
+
private state;
|
|
23
|
+
constructor(stateDir: string, options?: OfficeRegistryOptions);
|
|
24
|
+
/** Reload the atomic registry file after another host process changed it. */
|
|
25
|
+
reload(): OfficeRegistryState;
|
|
26
|
+
getState(): OfficeRegistryState;
|
|
27
|
+
getMigration(rawConversationId: string): OfficeMigrationRecord | undefined;
|
|
28
|
+
enablePlatform(platform: PlatformName): OfficeRegistryState;
|
|
29
|
+
/**
|
|
30
|
+
* Record that an office exists. Idempotent: re-recording a known office is
|
|
31
|
+
* a lock-free cache hit for callers that materialize directories per
|
|
32
|
+
* message, so this sits safely on hot write paths.
|
|
33
|
+
*/
|
|
34
|
+
recordOffice(address: OfficeAddress): OfficeRecord;
|
|
35
|
+
getOffices(): readonly OfficeRecord[];
|
|
36
|
+
private findOffice;
|
|
37
|
+
/**
|
|
38
|
+
* Validate and record a legacy directory. With exactly one enabled platform,
|
|
39
|
+
* ownership is safe to infer. With zero or multiple platforms, the record
|
|
40
|
+
* remains explicit `needs-owner` unless the caller supplies an owner.
|
|
41
|
+
*/
|
|
42
|
+
prepareLegacyMigration(options: OfficeMigrationPreparation): OfficeMigrationRecord;
|
|
43
|
+
markMoving(rawConversationId: string): OfficeMigrationRecord;
|
|
44
|
+
markCommitted(rawConversationId: string): OfficeMigrationRecord;
|
|
45
|
+
markFailed(rawConversationId: string, error: string): OfficeMigrationRecord;
|
|
46
|
+
private resolveOwner;
|
|
47
|
+
private requireMigration;
|
|
48
|
+
private failRecord;
|
|
49
|
+
private replaceMigration;
|
|
50
|
+
private replaceState;
|
|
51
|
+
/**
|
|
52
|
+
* Acquire the domain lease, reload while holding it, then perform one
|
|
53
|
+
* read-modify-write. A future move transaction can retain the same lease
|
|
54
|
+
* across its filesystem operation instead of splitting the transition.
|
|
55
|
+
*/
|
|
56
|
+
private withExclusiveLease;
|
|
57
|
+
private readState;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Resolve the office behind a raw conversation id for surfaces that name
|
|
61
|
+
* offices by raw id (CLI operators). The registry is the only authority:
|
|
62
|
+
* office records first, then a committed migration's owner, then the sole
|
|
63
|
+
* enabled platform. Two platforms sharing the raw id make the scope
|
|
64
|
+
* genuinely ambiguous, and an unknown id has no office to resolve — both
|
|
65
|
+
* fail loudly rather than guessing a directory.
|
|
66
|
+
*
|
|
67
|
+
* Constructs a registry per call, which re-reads the journal from disk; this
|
|
68
|
+
* is a one-shot CLI/Admin surface, never a per-message path (those go
|
|
69
|
+
* through the Workspace value's cached registry in `layout.ts`).
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveOwnedOfficeAddress(rawConversationId: string, stateDir: string): OfficeAddress;
|
|
72
|
+
/** Current office inventory, read fresh from disk for cross-process freshness. */
|
|
73
|
+
export declare function listRegisteredOffices(stateDir: string): readonly OfficeRecord[];
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/office/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,aAAa,EACb,0BAA0B,EAC1B,qBAAqB,EAErB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACb,MAAM,aAAa,CAAC;AA0BrB;;;;;;;;;GASG;AACH,UAAU,qBAAqB;IAC7B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,KAAK,CAAsB;IAEnC,YAAY,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,EAShE;IAED,6EAA6E;IAC7E,MAAM,IAAI,mBAAmB,CAG5B;IAED,QAAQ,IAAI,mBAAmB,CAE9B;IAED,YAAY,CAAC,iBAAiB,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAGzE;IAED,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,mBAAmB,CAS1D;IAED;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CAmBjD;IAED,UAAU,IAAI,SAAS,YAAY,EAAE,CAEpC;IAED,OAAO,CAAC,UAAU;IAOlB;;;;OAIG;IACH,sBAAsB,CAAC,OAAO,EAAE,0BAA0B,GAAG,qBAAqB,CAsDjF;IAED,UAAU,CAAC,iBAAiB,EAAE,MAAM,GAAG,qBAAqB,CAyB3D;IAED,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,qBAAqB,CAgB9D;IAED,UAAU,CAAC,iBAAiB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAS1E;IAED,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,YAAY;IAUpB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,SAAS;CAelB;AA8VD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,iBAAiB,EAAE,MAAM,EACzB,QAAQ,EAAE,MAAM,GACf,aAAa,CA8Bf;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAE/E"}
|