@geminixiang/mikan 1.0.0-beta.8 → 1.0.0-beta.80
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 +1149 -0
- package/README.md +98 -38
- package/dist/adapters/commands/admin.d.ts.map +1 -0
- package/dist/{commands → adapters/commands}/admin.js +12 -9
- package/dist/adapters/commands/admin.js.map +1 -0
- package/dist/{commands → adapters/commands}/auto-reply.d.ts +0 -3
- package/dist/adapters/commands/auto-reply.d.ts.map +1 -0
- package/dist/adapters/commands/auto-reply.js +47 -0
- package/dist/adapters/commands/auto-reply.js.map +1 -0
- package/dist/adapters/commands/login.d.ts +6 -0
- package/dist/adapters/commands/login.d.ts.map +1 -0
- package/dist/adapters/commands/login.js +158 -0
- package/dist/adapters/commands/login.js.map +1 -0
- package/dist/adapters/commands/manifest.d.ts +17 -0
- package/dist/adapters/commands/manifest.d.ts.map +1 -0
- package/dist/adapters/commands/manifest.js +121 -0
- package/dist/adapters/commands/manifest.js.map +1 -0
- package/dist/adapters/commands/model.d.ts +9 -0
- package/dist/adapters/commands/model.d.ts.map +1 -0
- package/dist/adapters/commands/model.js +136 -0
- package/dist/adapters/commands/model.js.map +1 -0
- package/dist/adapters/commands/new.d.ts.map +1 -0
- package/dist/adapters/commands/new.js +39 -0
- package/dist/adapters/commands/new.js.map +1 -0
- package/dist/adapters/commands/registry.d.ts +4 -0
- package/dist/adapters/commands/registry.d.ts.map +1 -0
- package/dist/adapters/commands/registry.js +35 -0
- package/dist/adapters/commands/registry.js.map +1 -0
- package/dist/{commands → adapters/commands}/sandbox.d.ts +0 -1
- package/dist/adapters/commands/sandbox.d.ts.map +1 -0
- package/dist/adapters/commands/sandbox.js +125 -0
- package/dist/adapters/commands/sandbox.js.map +1 -0
- package/dist/adapters/commands/session-view.d.ts.map +1 -0
- package/dist/{commands → adapters/commands}/session-view.js +21 -16
- package/dist/adapters/commands/session-view.js.map +1 -0
- package/dist/adapters/commands/types.d.ts +105 -0
- package/dist/adapters/commands/types.d.ts.map +1 -0
- package/dist/adapters/commands/types.js.map +1 -0
- package/dist/adapters/commands/utils.d.ts +11 -0
- package/dist/adapters/commands/utils.d.ts.map +1 -0
- package/dist/{commands → adapters/commands}/utils.js +15 -1
- package/dist/adapters/commands/utils.js.map +1 -0
- package/dist/adapters/discord/bot.d.ts +10 -17
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +232 -297
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/components.d.ts +4 -0
- package/dist/adapters/discord/components.d.ts.map +1 -0
- package/dist/adapters/discord/components.js +9 -0
- package/dist/adapters/discord/components.js.map +1 -0
- package/dist/adapters/discord/context.d.ts +3 -7
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +55 -219
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/discord/format.d.ts +2 -0
- package/dist/adapters/discord/format.d.ts.map +1 -0
- package/dist/adapters/discord/format.js +47 -0
- package/dist/adapters/discord/format.js.map +1 -0
- package/dist/adapters/discord/types.d.ts +90 -1
- package/dist/adapters/discord/types.d.ts.map +1 -1
- package/dist/adapters/discord/types.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +25 -9
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +326 -154
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/client.d.ts +35 -23
- package/dist/adapters/github/client.d.ts.map +1 -1
- package/dist/adapters/github/client.js +121 -28
- package/dist/adapters/github/client.js.map +1 -1
- package/dist/adapters/github/context.d.ts +3 -8
- package/dist/adapters/github/context.d.ts.map +1 -1
- package/dist/adapters/github/context.js +64 -131
- package/dist/adapters/github/context.js.map +1 -1
- package/dist/adapters/github/github-ops.d.ts +22 -0
- package/dist/adapters/github/github-ops.d.ts.map +1 -0
- package/dist/adapters/github/github-ops.js +277 -0
- package/dist/adapters/github/github-ops.js.map +1 -0
- package/dist/adapters/github/ids.d.ts +2 -23
- package/dist/adapters/github/ids.d.ts.map +1 -1
- package/dist/adapters/github/ids.js +6 -36
- package/dist/adapters/github/ids.js.map +1 -1
- package/dist/adapters/github/repo.d.ts +8 -0
- package/dist/adapters/github/repo.d.ts.map +1 -0
- package/dist/adapters/github/repo.js +92 -0
- package/dist/adapters/github/repo.js.map +1 -0
- package/dist/adapters/github/tool-pack.d.ts +4 -0
- package/dist/adapters/github/tool-pack.d.ts.map +1 -0
- package/dist/adapters/github/tool-pack.js +45 -0
- package/dist/adapters/github/tool-pack.js.map +1 -0
- package/dist/adapters/github/tools/checks.d.ts +14 -0
- package/dist/adapters/github/tools/checks.d.ts.map +1 -0
- package/dist/adapters/github/tools/checks.js +80 -0
- package/dist/adapters/github/tools/checks.js.map +1 -0
- package/dist/adapters/github/tools/issue.d.ts +18 -0
- package/dist/adapters/github/tools/issue.d.ts.map +1 -0
- package/dist/adapters/github/tools/issue.js +44 -0
- package/dist/adapters/github/tools/issue.js.map +1 -0
- package/dist/adapters/github/tools/pr.d.ts +17 -0
- package/dist/adapters/github/tools/pr.d.ts.map +1 -0
- package/dist/adapters/github/tools/pr.js +42 -0
- package/dist/adapters/github/tools/pr.js.map +1 -0
- package/dist/adapters/github/tools/read.d.ts +17 -0
- package/dist/adapters/github/tools/read.d.ts.map +1 -0
- package/dist/adapters/github/tools/read.js +134 -0
- package/dist/adapters/github/tools/read.js.map +1 -0
- package/dist/adapters/github/tools/review-reply.d.ts +14 -0
- package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
- package/dist/adapters/github/tools/review-reply.js +34 -0
- package/dist/adapters/github/tools/review-reply.js.map +1 -0
- package/dist/adapters/github/tools/sync.d.ts +13 -0
- package/dist/adapters/github/tools/sync.d.ts.map +1 -0
- package/dist/adapters/github/tools/sync.js +29 -0
- package/dist/adapters/github/tools/sync.js.map +1 -0
- package/dist/adapters/github/types.d.ts +197 -18
- package/dist/adapters/github/types.d.ts.map +1 -1
- package/dist/adapters/github/types.js.map +1 -1
- package/dist/adapters/github/webhook.d.ts +6 -0
- package/dist/adapters/github/webhook.d.ts.map +1 -0
- package/dist/adapters/github/webhook.js +62 -0
- package/dist/adapters/github/webhook.js.map +1 -0
- package/dist/adapters/intake.d.ts +4 -10
- package/dist/adapters/intake.d.ts.map +1 -1
- package/dist/adapters/intake.js +74 -31
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/markdown-tables.d.ts +8 -0
- package/dist/adapters/markdown-tables.d.ts.map +1 -0
- package/dist/adapters/markdown-tables.js +111 -0
- package/dist/adapters/markdown-tables.js.map +1 -0
- package/dist/{platform-messages.d.ts → adapters/messages.d.ts} +3 -2
- package/dist/adapters/messages.d.ts.map +1 -0
- package/dist/{platform-messages.js → adapters/messages.js} +4 -1
- package/dist/adapters/messages.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 +423 -0
- package/dist/adapters/progressive-renderer.js.map +1 -0
- package/dist/adapters/shared.d.ts +24 -53
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +140 -91
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/assistant.d.ts +23 -0
- package/dist/adapters/slack/assistant.d.ts.map +1 -0
- package/dist/adapters/slack/assistant.js +109 -0
- package/dist/adapters/slack/assistant.js.map +1 -0
- package/dist/adapters/slack/auto-reply-context.d.ts +14 -0
- package/dist/adapters/slack/auto-reply-context.d.ts.map +1 -0
- package/dist/adapters/slack/auto-reply-context.js +21 -0
- package/dist/adapters/slack/auto-reply-context.js.map +1 -0
- package/dist/adapters/slack/blocks.d.ts +5 -0
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +84 -148
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +51 -39
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +892 -567
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts +3 -9
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +8 -17
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/jev-context.d.ts +17 -0
- package/dist/adapters/slack/jev-context.d.ts.map +1 -0
- package/dist/adapters/slack/jev-context.js +57 -0
- package/dist/adapters/slack/jev-context.js.map +1 -0
- package/dist/adapters/slack/markdown.d.ts +2 -0
- package/dist/adapters/slack/markdown.d.ts.map +1 -0
- package/dist/adapters/slack/markdown.js +43 -0
- package/dist/adapters/slack/markdown.js.map +1 -0
- package/dist/adapters/slack/persona.d.ts +6 -0
- package/dist/adapters/slack/persona.d.ts.map +1 -0
- package/dist/adapters/slack/persona.js +13 -0
- package/dist/adapters/slack/persona.js.map +1 -0
- package/dist/adapters/slack/response-lifecycle.d.ts +3 -4
- package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +221 -347
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/session.d.ts +3 -2
- package/dist/adapters/slack/session.d.ts.map +1 -1
- package/dist/adapters/slack/session.js +9 -13
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/slack/stream-limits.d.ts +10 -0
- package/dist/adapters/slack/stream-limits.d.ts.map +1 -0
- package/dist/adapters/slack/stream-limits.js +22 -0
- package/dist/adapters/slack/stream-limits.js.map +1 -0
- package/dist/adapters/slack/task-intent.d.ts +19 -0
- package/dist/adapters/slack/task-intent.d.ts.map +1 -0
- package/dist/adapters/slack/task-intent.js +65 -0
- package/dist/adapters/slack/task-intent.js.map +1 -0
- package/dist/adapters/slack/task-status.d.ts +6 -0
- package/dist/adapters/slack/task-status.d.ts.map +1 -0
- package/dist/adapters/slack/task-status.js +100 -0
- package/dist/adapters/slack/task-status.js.map +1 -0
- package/dist/adapters/slack/tool-pack.d.ts +4 -0
- package/dist/adapters/slack/tool-pack.d.ts.map +1 -0
- package/dist/adapters/slack/tool-pack.js +40 -0
- package/dist/adapters/slack/tool-pack.js.map +1 -0
- package/dist/adapters/slack/tools/blockkit.d.ts +17 -0
- package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -0
- package/dist/adapters/slack/tools/blockkit.js +98 -0
- package/dist/adapters/slack/tools/blockkit.js.map +1 -0
- package/dist/adapters/slack/types.d.ts +91 -5
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/slack/update-diagnostics.d.ts +13 -0
- package/dist/adapters/slack/update-diagnostics.d.ts.map +1 -0
- package/dist/adapters/slack/update-diagnostics.js +128 -0
- package/dist/adapters/slack/update-diagnostics.js.map +1 -0
- package/dist/adapters/telegram/bot.d.ts +8 -18
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +114 -232
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts +3 -7
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +47 -191
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/telegram/types.d.ts +24 -1
- package/dist/adapters/telegram/types.d.ts.map +1 -1
- package/dist/adapters/telegram/types.js.map +1 -1
- package/dist/adapters/types.d.ts +89 -16
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/adapters/web/admin/client-assets.d.ts +4 -0
- package/dist/adapters/web/admin/client-assets.d.ts.map +1 -0
- package/dist/adapters/web/admin/client-assets.js +1766 -0
- package/dist/adapters/web/admin/client-assets.js.map +1 -0
- package/dist/adapters/web/admin/portal.d.ts +27 -0
- package/dist/adapters/web/admin/portal.d.ts.map +1 -0
- package/dist/adapters/web/admin/portal.js +1506 -0
- package/dist/adapters/web/admin/portal.js.map +1 -0
- package/dist/{web → adapters/web}/admin/provider-models.d.ts +1 -1
- package/dist/adapters/web/admin/provider-models.d.ts.map +1 -0
- package/dist/{web → adapters/web}/admin/provider-models.js +1 -1
- package/dist/adapters/web/admin/provider-models.js.map +1 -0
- package/dist/adapters/web/admin/types.d.ts +56 -0
- package/dist/adapters/web/admin/types.d.ts.map +1 -0
- package/dist/adapters/web/admin/types.js.map +1 -0
- package/dist/adapters/web/login/oauth.d.ts +4 -0
- package/dist/adapters/web/login/oauth.d.ts.map +1 -0
- package/dist/{web → adapters/web}/login/oauth.js +61 -100
- package/dist/adapters/web/login/oauth.js.map +1 -0
- package/dist/adapters/web/login/portal.d.ts +10 -0
- package/dist/adapters/web/login/portal.d.ts.map +1 -0
- package/dist/{web → adapters/web}/login/portal.js +169 -159
- package/dist/adapters/web/login/portal.js.map +1 -0
- package/dist/{web → adapters/web}/login/types.d.ts +1 -17
- package/dist/adapters/web/login/types.d.ts.map +1 -0
- package/dist/adapters/web/login/types.js.map +1 -0
- package/dist/adapters/web/portal-shell.d.ts +9 -0
- package/dist/adapters/web/portal-shell.d.ts.map +1 -0
- package/dist/{portal-shell.js → adapters/web/portal-shell.js} +73 -11
- package/dist/adapters/web/portal-shell.js.map +1 -0
- package/dist/adapters/web/server.d.ts +33 -0
- package/dist/adapters/web/server.d.ts.map +1 -0
- package/dist/{web → adapters/web}/server.js +15 -9
- package/dist/adapters/web/server.js.map +1 -0
- package/dist/adapters/web/session-view/portal.d.ts +19 -0
- package/dist/adapters/web/session-view/portal.d.ts.map +1 -0
- package/dist/{web → adapters/web}/session-view/portal.js +641 -181
- package/dist/adapters/web/session-view/portal.js.map +1 -0
- package/dist/{web → adapters/web}/session-view/types.d.ts +1 -6
- package/dist/adapters/web/session-view/types.d.ts.map +1 -0
- package/dist/adapters/web/session-view/types.js.map +1 -0
- package/dist/{web → adapters/web}/token-store.d.ts +0 -3
- package/dist/adapters/web/token-store.d.ts.map +1 -0
- package/dist/{web → adapters/web}/token-store.js +1 -3
- package/dist/adapters/web/token-store.js.map +1 -0
- package/dist/adapters/web/types.d.ts.map +1 -0
- package/dist/adapters/web/types.js.map +1 -0
- package/dist/cli/arg-grammar.d.ts +8 -0
- package/dist/cli/arg-grammar.d.ts.map +1 -0
- package/dist/cli/arg-grammar.js +47 -0
- package/dist/cli/arg-grammar.js.map +1 -0
- package/dist/cli/boot.d.ts +4 -0
- package/dist/cli/boot.d.ts.map +1 -0
- package/dist/cli/boot.js +81 -0
- package/dist/cli/boot.js.map +1 -0
- package/dist/cli/download.d.ts.map +1 -0
- package/dist/cli/download.js +84 -0
- package/dist/cli/download.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 +151 -0
- package/dist/cli/office.js.map +1 -0
- package/dist/cli/onboard.d.ts +8 -0
- package/dist/cli/onboard.d.ts.map +1 -0
- package/dist/cli/onboard.js +195 -0
- package/dist/cli/onboard.js.map +1 -0
- package/dist/cli/process-lifecycle.d.ts +14 -0
- package/dist/cli/process-lifecycle.d.ts.map +1 -0
- package/dist/cli/process-lifecycle.js +61 -0
- package/dist/cli/process-lifecycle.js.map +1 -0
- package/dist/cli/sandbox.d.ts +3 -0
- package/dist/cli/sandbox.d.ts.map +1 -0
- package/dist/cli/sandbox.js +80 -0
- package/dist/cli/sandbox.js.map +1 -0
- package/dist/cli/sessions.d.ts +2 -0
- package/dist/cli/sessions.d.ts.map +1 -0
- package/dist/cli/sessions.js +78 -0
- package/dist/cli/sessions.js.map +1 -0
- package/dist/cli/types.d.ts +21 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/env-manifest.d.ts +17 -0
- package/dist/env-manifest.d.ts.map +1 -0
- package/dist/env-manifest.js +249 -0
- package/dist/env-manifest.js.map +1 -0
- package/dist/events/index.d.ts +122 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +299 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/scheduler.d.ts +25 -0
- package/dist/events/scheduler.d.ts.map +1 -0
- package/dist/events/scheduler.js +223 -0
- package/dist/events/scheduler.js.map +1 -0
- package/dist/file-guards.d.ts +13 -0
- package/dist/file-guards.d.ts.map +1 -0
- package/dist/file-guards.js +104 -0
- package/dist/file-guards.js.map +1 -0
- package/dist/harness/execution-env.d.ts +4 -0
- package/dist/harness/execution-env.d.ts.map +1 -0
- package/dist/harness/execution-env.js +245 -0
- package/dist/harness/execution-env.js.map +1 -0
- package/dist/harness/execution-resolver.d.ts +23 -0
- package/dist/harness/execution-resolver.d.ts.map +1 -0
- package/dist/harness/execution-resolver.js +156 -0
- package/dist/harness/execution-resolver.js.map +1 -0
- package/dist/harness/http.d.ts +0 -12
- package/dist/harness/http.d.ts.map +1 -1
- package/dist/harness/http.js +0 -34
- package/dist/harness/http.js.map +1 -1
- package/dist/harness/index.d.ts +19 -17
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +12 -15
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/jev.d.ts +67 -0
- package/dist/harness/jev.d.ts.map +1 -0
- package/dist/harness/jev.js +135 -0
- package/dist/harness/jev.js.map +1 -0
- package/dist/harness/mcp-result.d.ts +20 -0
- package/dist/harness/mcp-result.d.ts.map +1 -0
- package/dist/harness/mcp-result.js +179 -0
- package/dist/harness/mcp-result.js.map +1 -0
- package/dist/harness/mcp.d.ts +17 -0
- package/dist/harness/mcp.d.ts.map +1 -0
- package/dist/harness/mcp.js +243 -0
- package/dist/harness/mcp.js.map +1 -0
- package/dist/harness/models.d.ts +2 -19
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +42 -94
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/open-connector.d.ts +12 -0
- package/dist/harness/open-connector.d.ts.map +1 -0
- package/dist/harness/open-connector.js +160 -0
- package/dist/harness/open-connector.js.map +1 -0
- package/dist/harness/presenter.d.ts +11 -0
- package/dist/harness/presenter.d.ts.map +1 -0
- package/dist/harness/presenter.js +824 -0
- package/dist/harness/presenter.js.map +1 -0
- package/dist/harness/prompt.d.ts +18 -0
- package/dist/harness/prompt.d.ts.map +1 -0
- package/dist/harness/prompt.js +403 -0
- package/dist/harness/prompt.js.map +1 -0
- package/dist/harness/runner.d.ts +2 -123
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +547 -415
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session.d.ts +98 -0
- package/dist/harness/session.d.ts.map +1 -0
- package/dist/harness/session.js +645 -0
- package/dist/harness/session.js.map +1 -0
- package/dist/harness/skills.d.ts +7 -41
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +101 -55
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/subagent-profiles.d.ts +3 -0
- package/dist/harness/subagent-profiles.d.ts.map +1 -0
- package/dist/harness/subagent-profiles.js +260 -0
- package/dist/harness/subagent-profiles.js.map +1 -0
- package/dist/harness/subagent.d.ts +39 -0
- package/dist/harness/subagent.d.ts.map +1 -0
- package/dist/harness/subagent.js +618 -0
- package/dist/harness/subagent.js.map +1 -0
- package/dist/harness/tool-args.d.ts +2 -0
- package/dist/harness/tool-args.d.ts.map +1 -0
- package/dist/harness/tool-args.js +20 -0
- package/dist/harness/tool-args.js.map +1 -0
- package/dist/harness/tools/attach.d.ts +13 -0
- package/dist/harness/tools/attach.d.ts.map +1 -0
- package/dist/{adapters/slack → harness}/tools/attach.js +2 -2
- package/dist/harness/tools/attach.js.map +1 -0
- package/dist/harness/tools/event.d.ts +28 -0
- package/dist/harness/tools/event.d.ts.map +1 -0
- package/dist/harness/tools/event.js +166 -0
- package/dist/harness/tools/event.js.map +1 -0
- package/dist/harness/tools/generate-image.d.ts +20 -0
- package/dist/harness/tools/generate-image.d.ts.map +1 -0
- package/dist/harness/tools/generate-image.js +68 -0
- package/dist/harness/tools/generate-image.js.map +1 -0
- package/dist/harness/tools/host-fn-tool.d.ts +14 -0
- package/dist/harness/tools/host-fn-tool.d.ts.map +1 -0
- package/dist/harness/tools/host-fn-tool.js +39 -0
- package/dist/harness/tools/host-fn-tool.js.map +1 -0
- package/dist/harness/tools/index.d.ts +34 -0
- package/dist/harness/tools/index.d.ts.map +1 -0
- package/dist/harness/tools/index.js +49 -0
- package/dist/harness/tools/index.js.map +1 -0
- package/dist/harness/tools/jev-browser.d.ts +42 -0
- package/dist/harness/tools/jev-browser.d.ts.map +1 -0
- package/dist/harness/tools/jev-browser.js +547 -0
- package/dist/harness/tools/jev-browser.js.map +1 -0
- package/dist/harness/tools/jev.d.ts +15 -0
- package/dist/harness/tools/jev.d.ts.map +1 -0
- package/dist/harness/tools/jev.js +98 -0
- package/dist/harness/tools/jev.js.map +1 -0
- package/dist/harness/tools/pi-tools.d.ts +8 -0
- package/dist/harness/tools/pi-tools.d.ts.map +1 -0
- package/dist/harness/tools/pi-tools.js +55 -0
- package/dist/harness/tools/pi-tools.js.map +1 -0
- package/dist/harness/tools/react.d.ts +11 -0
- package/dist/harness/tools/react.d.ts.map +1 -0
- package/dist/harness/tools/react.js +24 -0
- package/dist/harness/tools/react.js.map +1 -0
- package/dist/harness/tools/sandbox.d.ts +24 -0
- package/dist/harness/tools/sandbox.d.ts.map +1 -0
- package/dist/{tools → harness/tools}/sandbox.js +15 -9
- package/dist/harness/tools/sandbox.js.map +1 -0
- package/dist/harness/tools/secret-redaction.d.ts +9 -0
- package/dist/harness/tools/secret-redaction.d.ts.map +1 -0
- package/dist/harness/tools/secret-redaction.js +44 -0
- package/dist/harness/tools/secret-redaction.js.map +1 -0
- package/dist/harness/tools/subagent.d.ts +51 -0
- package/dist/harness/tools/subagent.d.ts.map +1 -0
- package/dist/harness/tools/subagent.js +581 -0
- package/dist/harness/tools/subagent.js.map +1 -0
- package/dist/harness/tools/task.d.ts +22 -0
- package/dist/harness/tools/task.d.ts.map +1 -0
- package/dist/harness/tools/task.js +80 -0
- package/dist/harness/tools/task.js.map +1 -0
- package/dist/harness/tools/types.d.ts +14 -0
- package/dist/harness/tools/types.d.ts.map +1 -0
- package/dist/harness/tools/types.js.map +1 -0
- package/dist/harness/types.d.ts +345 -29
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +36 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +0 -1
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +3 -13
- package/dist/log.js.map +1 -1
- package/dist/main.js +300 -217
- package/dist/main.js.map +1 -1
- package/dist/memory-capture/index.d.ts +15 -0
- package/dist/memory-capture/index.d.ts.map +1 -0
- package/dist/memory-capture/index.js +199 -0
- package/dist/memory-capture/index.js.map +1 -0
- package/dist/memory-capture/types.d.ts +27 -0
- package/dist/memory-capture/types.d.ts.map +1 -0
- package/dist/memory-capture/types.js +2 -0
- package/dist/memory-capture/types.js.map +1 -0
- package/dist/observability/index.d.ts +30 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +273 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/instrument.js +9 -6
- package/dist/observability/instrument.js.map +1 -1
- package/dist/observability/otel.d.ts +10 -0
- package/dist/observability/otel.d.ts.map +1 -0
- package/dist/observability/otel.js +182 -0
- package/dist/observability/otel.js.map +1 -0
- package/dist/observability/sentry.d.ts +32 -13
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +85 -58
- package/dist/observability/sentry.js.map +1 -1
- package/dist/observability/types.d.ts +30 -3
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/observability/types.js.map +1 -1
- package/dist/office/index.d.ts +74 -0
- package/dist/office/index.d.ts.map +1 -0
- package/dist/office/index.js +971 -0
- package/dist/office/index.js.map +1 -0
- package/dist/office/projection.d.ts +11 -0
- package/dist/office/projection.d.ts.map +1 -0
- package/dist/office/projection.js +146 -0
- package/dist/office/projection.js.map +1 -0
- package/dist/office/types.d.ts +55 -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/runtime/conversation-runtime.d.ts +0 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +375 -152
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +66 -0
- package/dist/runtime/session-lifecycle.d.ts.map +1 -0
- package/dist/runtime/session-lifecycle.js +393 -0
- package/dist/runtime/session-lifecycle.js.map +1 -0
- package/dist/runtime/types.d.ts +41 -17
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts +4 -0
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +59 -55
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts +3 -0
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +39 -20
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/host.d.ts +3 -0
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +42 -35
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +13 -0
- package/dist/sandbox/identity.d.ts.map +1 -0
- package/dist/sandbox/identity.js +49 -0
- package/dist/sandbox/identity.js.map +1 -0
- package/dist/sandbox/index.d.ts +5 -15
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +5 -51
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/layout.d.ts +7 -0
- package/dist/sandbox/layout.d.ts.map +1 -0
- package/dist/sandbox/layout.js +13 -0
- package/dist/sandbox/layout.js.map +1 -0
- package/dist/{provisioner.d.ts → sandbox/provisioner.d.ts} +41 -4
- package/dist/sandbox/provisioner.d.ts.map +1 -0
- package/dist/sandbox/provisioner.js +971 -0
- package/dist/sandbox/provisioner.js.map +1 -0
- package/dist/sandbox/registry.d.ts +12 -0
- package/dist/sandbox/registry.d.ts.map +1 -0
- package/dist/sandbox/registry.js +93 -0
- package/dist/sandbox/registry.js.map +1 -0
- package/dist/sandbox/types.d.ts +23 -25
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +21 -0
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +100 -8
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +17 -0
- package/dist/sessions/chat-history-sync.d.ts.map +1 -0
- package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +224 -183
- package/dist/sessions/chat-history-sync.js.map +1 -0
- package/dist/sessions/history-line.d.ts +9 -0
- package/dist/sessions/history-line.d.ts.map +1 -0
- package/dist/sessions/history-line.js +25 -0
- package/dist/sessions/history-line.js.map +1 -0
- package/dist/sessions/migrate-common.d.ts +28 -0
- package/dist/sessions/migrate-common.d.ts.map +1 -0
- package/dist/sessions/migrate-common.js +80 -0
- package/dist/sessions/migrate-common.js.map +1 -0
- package/dist/sessions/migrate-pi-084.d.ts +7 -0
- package/dist/sessions/migrate-pi-084.d.ts.map +1 -0
- package/dist/sessions/migrate-pi-084.js +293 -0
- package/dist/sessions/migrate-pi-084.js.map +1 -0
- package/dist/sessions/migrate-v3.d.ts +7 -0
- package/dist/sessions/migrate-v3.d.ts.map +1 -0
- package/dist/sessions/migrate-v3.js +351 -0
- package/dist/sessions/migrate-v3.js.map +1 -0
- package/dist/sessions/session-key.d.ts +18 -0
- package/dist/sessions/session-key.d.ts.map +1 -0
- package/dist/sessions/session-key.js +88 -0
- package/dist/sessions/session-key.js.map +1 -0
- package/dist/sessions/session-store.d.ts +55 -0
- package/dist/sessions/session-store.d.ts.map +1 -0
- package/dist/sessions/session-store.js +635 -0
- package/dist/sessions/session-store.js.map +1 -0
- package/dist/sessions/store.d.ts +7 -61
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +126 -102
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +59 -8
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js +2 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings/apply.d.ts +9 -0
- package/dist/settings/apply.d.ts.map +1 -0
- package/dist/settings/apply.js +31 -0
- package/dist/settings/apply.js.map +1 -0
- package/dist/settings/index.d.ts +76 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +351 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/migrate.d.ts +16 -0
- package/dist/settings/migrate.d.ts.map +1 -0
- package/dist/settings/migrate.js +70 -0
- package/dist/settings/migrate.js.map +1 -0
- package/dist/types.d.ts +231 -173
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -3
- package/dist/types.js.map +1 -1
- package/dist/unknown-values.d.ts +3 -0
- package/dist/unknown-values.d.ts.map +1 -0
- package/dist/unknown-values.js +7 -0
- package/dist/unknown-values.js.map +1 -0
- package/dist/vault/index.d.ts +35 -11
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +326 -115
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/types.d.ts +5 -16
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/package.json +82 -41
- package/dist/adapter.d.ts +0 -2
- package/dist/adapter.d.ts.map +0 -1
- package/dist/adapter.js +0 -2
- package/dist/adapter.js.map +0 -1
- package/dist/adapters/slack/tools/attach.d.ts +0 -12
- package/dist/adapters/slack/tools/attach.d.ts.map +0 -1
- package/dist/adapters/slack/tools/attach.js.map +0 -1
- 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/agent-events.d.ts +0 -5
- package/dist/agent-events.d.ts.map +0 -1
- package/dist/agent-events.js +0 -26
- package/dist/agent-events.js.map +0 -1
- package/dist/agent.d.ts +0 -39
- package/dist/agent.d.ts.map +0 -1
- package/dist/agent.js +0 -1291
- package/dist/agent.js.map +0 -1
- package/dist/cli/ext-git.d.ts +0 -22
- package/dist/cli/ext-git.d.ts.map +0 -1
- package/dist/cli/ext-git.js +0 -76
- package/dist/cli/ext-git.js.map +0 -1
- package/dist/cli/ext.d.ts +0 -2
- package/dist/cli/ext.d.ts.map +0 -1
- package/dist/cli/ext.js +0 -217
- package/dist/cli/ext.js.map +0 -1
- package/dist/commands/admin.d.ts.map +0 -1
- package/dist/commands/admin.js.map +0 -1
- package/dist/commands/auto-reply.d.ts.map +0 -1
- package/dist/commands/auto-reply.js +0 -76
- package/dist/commands/auto-reply.js.map +0 -1
- package/dist/commands/extensions.d.ts +0 -14
- package/dist/commands/extensions.d.ts.map +0 -1
- package/dist/commands/extensions.js +0 -55
- package/dist/commands/extensions.js.map +0 -1
- package/dist/commands/login.d.ts +0 -5
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js +0 -115
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/model.d.ts +0 -10
- package/dist/commands/model.d.ts.map +0 -1
- package/dist/commands/model.js +0 -102
- package/dist/commands/model.js.map +0 -1
- package/dist/commands/new.d.ts.map +0 -1
- package/dist/commands/new.js +0 -25
- package/dist/commands/new.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/commands/registry.d.ts +0 -5
- package/dist/commands/registry.d.ts.map +0 -1
- package/dist/commands/registry.js +0 -31
- package/dist/commands/registry.js.map +0 -1
- package/dist/commands/sandbox.d.ts.map +0 -1
- package/dist/commands/sandbox.js +0 -78
- package/dist/commands/sandbox.js.map +0 -1
- package/dist/commands/session-view.d.ts.map +0 -1
- package/dist/commands/session-view.js.map +0 -1
- package/dist/commands/types.d.ts +0 -66
- package/dist/commands/types.d.ts.map +0 -1
- package/dist/commands/types.js.map +0 -1
- package/dist/commands/utils.d.ts +0 -11
- package/dist/commands/utils.d.ts.map +0 -1
- package/dist/commands/utils.js.map +0 -1
- package/dist/config.d.ts +0 -78
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -450
- package/dist/config.js.map +0 -1
- package/dist/download.d.ts.map +0 -1
- package/dist/download.js +0 -89
- package/dist/download.js.map +0 -1
- package/dist/events.d.ts +0 -43
- package/dist/events.d.ts.map +0 -1
- package/dist/events.js +0 -456
- package/dist/events.js.map +0 -1
- package/dist/execution-resolver.d.ts +0 -21
- package/dist/execution-resolver.d.ts.map +0 -1
- package/dist/execution-resolver.js +0 -170
- package/dist/execution-resolver.js.map +0 -1
- package/dist/harness/auth.d.ts +0 -16
- package/dist/harness/auth.d.ts.map +0 -1
- package/dist/harness/auth.js +0 -86
- package/dist/harness/auth.js.map +0 -1
- package/dist/harness/extensions/loader.d.ts +0 -86
- package/dist/harness/extensions/loader.d.ts.map +0 -1
- package/dist/harness/extensions/loader.js +0 -525
- package/dist/harness/extensions/loader.js.map +0 -1
- package/dist/harness/extensions/registry.d.ts +0 -23
- package/dist/harness/extensions/registry.d.ts.map +0 -1
- package/dist/harness/extensions/registry.js +0 -45
- package/dist/harness/extensions/registry.js.map +0 -1
- package/dist/harness/extensions/types.d.ts +0 -248
- package/dist/harness/extensions/types.d.ts.map +0 -1
- package/dist/harness/extensions/types.js.map +0 -1
- package/dist/harness/session-store.d.ts +0 -77
- package/dist/harness/session-store.d.ts.map +0 -1
- package/dist/harness/session-store.js +0 -248
- package/dist/harness/session-store.js.map +0 -1
- package/dist/harness/settings.d.ts +0 -47
- package/dist/harness/settings.d.ts.map +0 -1
- package/dist/harness/settings.js +0 -29
- package/dist/harness/settings.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/platform-messages.d.ts.map +0 -1
- package/dist/platform-messages.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/provisioner.d.ts.map +0 -1
- package/dist/provisioner.js +0 -517
- package/dist/provisioner.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/errors.d.ts +0 -6
- package/dist/sandbox/errors.d.ts.map +0 -1
- package/dist/sandbox/errors.js +0 -11
- package/dist/sandbox/errors.js.map +0 -1
- package/dist/sandbox/firecracker.d.ts +0 -15
- package/dist/sandbox/firecracker.d.ts.map +0 -1
- package/dist/sandbox/firecracker.js +0 -212
- package/dist/sandbox/firecracker.js.map +0 -1
- package/dist/sandbox/image.d.ts +0 -3
- package/dist/sandbox/image.d.ts.map +0 -1
- package/dist/sandbox/image.js +0 -27
- package/dist/sandbox/image.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 -24
- 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/bash.d.ts +0 -10
- package/dist/tools/bash.d.ts.map +0 -1
- package/dist/tools/bash.js +0 -80
- package/dist/tools/bash.js.map +0 -1
- package/dist/tools/edit.d.ts +0 -11
- package/dist/tools/edit.d.ts.map +0 -1
- package/dist/tools/edit.js +0 -131
- package/dist/tools/edit.js.map +0 -1
- package/dist/tools/event.d.ts +0 -56
- package/dist/tools/event.d.ts.map +0 -1
- package/dist/tools/event.js +0 -252
- package/dist/tools/event.js.map +0 -1
- package/dist/tools/index.d.ts +0 -24
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -31
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/react.d.ts +0 -15
- package/dist/tools/react.d.ts.map +0 -1
- package/dist/tools/react.js +0 -40
- package/dist/tools/react.js.map +0 -1
- package/dist/tools/read.d.ts +0 -11
- package/dist/tools/read.d.ts.map +0 -1
- package/dist/tools/read.js +0 -134
- package/dist/tools/read.js.map +0 -1
- package/dist/tools/sandbox.d.ts +0 -22
- package/dist/tools/sandbox.d.ts.map +0 -1
- package/dist/tools/sandbox.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/tools/types.d.ts +0 -54
- package/dist/tools/types.d.ts.map +0 -1
- package/dist/tools/types.js.map +0 -1
- package/dist/tools/write.d.ts +0 -10
- package/dist/tools/write.d.ts.map +0 -1
- package/dist/tools/write.js +0 -29
- package/dist/tools/write.js.map +0 -1
- package/dist/trigger.d.ts +0 -22
- package/dist/trigger.d.ts.map +0 -1
- package/dist/trigger.js +0 -100
- package/dist/trigger.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/file-guards.d.ts +0 -9
- package/dist/utils/file-guards.d.ts.map +0 -1
- package/dist/utils/file-guards.js +0 -59
- package/dist/utils/file-guards.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/admin/portal.d.ts +0 -5
- package/dist/web/admin/portal.d.ts.map +0 -1
- package/dist/web/admin/portal.js +0 -2572
- package/dist/web/admin/portal.js.map +0 -1
- package/dist/web/admin/provider-models.d.ts.map +0 -1
- package/dist/web/admin/provider-models.js.map +0 -1
- package/dist/web/admin/store.d.ts +0 -13
- package/dist/web/admin/store.d.ts.map +0 -1
- package/dist/web/admin/store.js +0 -14
- package/dist/web/admin/store.js.map +0 -1
- package/dist/web/admin/types.d.ts +0 -30
- package/dist/web/admin/types.d.ts.map +0 -1
- package/dist/web/admin/types.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/login/oauth.d.ts +0 -6
- package/dist/web/login/oauth.d.ts.map +0 -1
- package/dist/web/login/oauth.js.map +0 -1
- package/dist/web/login/portal.d.ts +0 -17
- package/dist/web/login/portal.d.ts.map +0 -1
- package/dist/web/login/portal.js.map +0 -1
- package/dist/web/login/store.d.ts +0 -8
- package/dist/web/login/store.d.ts.map +0 -1
- package/dist/web/login/store.js +0 -15
- package/dist/web/login/store.js.map +0 -1
- package/dist/web/login/types.d.ts.map +0 -1
- package/dist/web/login/types.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/server.d.ts +0 -28
- package/dist/web/server.d.ts.map +0 -1
- package/dist/web/server.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/web/session-view/portal.d.ts +0 -13
- package/dist/web/session-view/portal.d.ts.map +0 -1
- package/dist/web/session-view/portal.js.map +0 -1
- package/dist/web/session-view/service.d.ts +0 -6
- package/dist/web/session-view/service.d.ts.map +0 -1
- package/dist/web/session-view/service.js +0 -498
- package/dist/web/session-view/service.js.map +0 -1
- package/dist/web/session-view/store.d.ts +0 -8
- package/dist/web/session-view/store.d.ts.map +0 -1
- package/dist/web/session-view/store.js +0 -15
- package/dist/web/session-view/store.js.map +0 -1
- package/dist/web/session-view/types.d.ts.map +0 -1
- package/dist/web/session-view/types.js.map +0 -1
- package/dist/web/token-store.d.ts.map +0 -1
- package/dist/web/token-store.js.map +0 -1
- package/dist/web/types.d.ts.map +0 -1
- package/dist/web/types.js.map +0 -1
- /package/dist/{commands → adapters/commands}/admin.d.ts +0 -0
- /package/dist/{commands → adapters/commands}/new.d.ts +0 -0
- /package/dist/{commands → adapters/commands}/session-view.d.ts +0 -0
- /package/dist/{commands → adapters/commands}/types.js +0 -0
- /package/dist/{harness/extensions → adapters/web/admin}/types.js +0 -0
- /package/dist/{tools → adapters/web/login}/types.js +0 -0
- /package/dist/{web/admin → adapters/web/session-view}/types.js +0 -0
- /package/dist/{web → adapters/web}/types.d.ts +0 -0
- /package/dist/{web/login → adapters/web}/types.js +0 -0
- /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
- /package/dist/{web/session-view → cli}/types.js +0 -0
- /package/dist/{web → harness/tools}/types.js +0 -0
|
@@ -0,0 +1,971 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
4
|
+
import * as log from "../log.js";
|
|
5
|
+
import { legacyConversationCredentialKey } from "../sandbox/identity.js";
|
|
6
|
+
import { guestWorkspacePath } from "../sandbox/layout.js";
|
|
7
|
+
import { migrateConversationVaultKeys } from "../vault/index.js";
|
|
8
|
+
import { atomicWritePrivateFile, readTextFileIfExists } from "../file-guards.js";
|
|
9
|
+
import { isRecord } from "../unknown-values.js";
|
|
10
|
+
export const OFFICE_LOG_FILENAME = "log.jsonl";
|
|
11
|
+
const OFFICE_KEY_VERSION = "v1";
|
|
12
|
+
const OFFICE_KEY_DOMAIN = "office-address-v1";
|
|
13
|
+
const OFFICE_KEY_DIGEST_LENGTH = 16;
|
|
14
|
+
const READABLE_ID_LENGTH = 32;
|
|
15
|
+
const PLATFORM_NAMES = new Set(["slack", "discord", "telegram", "github"]);
|
|
16
|
+
const OFFICE_KEY_PATTERN = /^v1-(slack|discord|telegram|github)-[a-z0-9]+(?:-[a-z0-9]+)*-[a-f0-9]{16}$/;
|
|
17
|
+
export function createOfficeAddress(platform, conversationId) {
|
|
18
|
+
assertPlatformName(platform);
|
|
19
|
+
assertConversationId(conversationId);
|
|
20
|
+
return Object.freeze({ platform, conversationId });
|
|
21
|
+
}
|
|
22
|
+
export function validateOfficeAddress(value) {
|
|
23
|
+
if (!isRecord(value))
|
|
24
|
+
throw new Error("Office address must be an object");
|
|
25
|
+
if (typeof value.platform !== "string") {
|
|
26
|
+
throw new Error("Office address platform must be a string");
|
|
27
|
+
}
|
|
28
|
+
if (typeof value.conversationId !== "string") {
|
|
29
|
+
throw new Error("Office address conversation id must be a string");
|
|
30
|
+
}
|
|
31
|
+
return createOfficeAddress(assertPlatformName(value.platform), value.conversationId);
|
|
32
|
+
}
|
|
33
|
+
function isPlatformName(value) {
|
|
34
|
+
return typeof value === "string" && PLATFORM_NAMES.has(value);
|
|
35
|
+
}
|
|
36
|
+
export function assertPlatformName(value) {
|
|
37
|
+
if (!isPlatformName(value))
|
|
38
|
+
throw new Error(`Unsupported platform: ${JSON.stringify(value)}`);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
function isUnsafeConversationIdChar(character) {
|
|
42
|
+
const code = character.codePointAt(0) ?? 0;
|
|
43
|
+
return character === "/" || character === "\\" || code <= 0x1f || (code >= 0x7f && code <= 0x9f);
|
|
44
|
+
}
|
|
45
|
+
export function assertConversationId(value) {
|
|
46
|
+
if (value.length === 0 || value === "." || value === "..") {
|
|
47
|
+
throw new Error("Conversation id must be non-empty and not a path marker");
|
|
48
|
+
}
|
|
49
|
+
if ([...value].some(isUnsafeConversationIdChar)) {
|
|
50
|
+
throw new Error("Conversation id must not contain path separators or control characters");
|
|
51
|
+
}
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
export function officeKey(address) {
|
|
55
|
+
const normalized = validateOfficeAddress(address);
|
|
56
|
+
const readable = readableConversationId(normalized.conversationId);
|
|
57
|
+
const digest = createHash("sha256")
|
|
58
|
+
.update(`${OFFICE_KEY_DOMAIN}\0${normalized.platform}\0${normalized.conversationId}`)
|
|
59
|
+
.digest("hex")
|
|
60
|
+
.slice(0, OFFICE_KEY_DIGEST_LENGTH);
|
|
61
|
+
return `${OFFICE_KEY_VERSION}-${normalized.platform}-${readable}-${digest}`;
|
|
62
|
+
}
|
|
63
|
+
export function officeDir(workspaceRoot, address) {
|
|
64
|
+
return join(workspaceRoot, officeKey(address));
|
|
65
|
+
}
|
|
66
|
+
export function officeStateDir(stateDir, address) {
|
|
67
|
+
return join(stateDir, "conversations", officeKey(address));
|
|
68
|
+
}
|
|
69
|
+
export function sameOffice(left, right) {
|
|
70
|
+
const leftAddress = validateOfficeAddress(left);
|
|
71
|
+
const rightAddress = validateOfficeAddress(right);
|
|
72
|
+
return (leftAddress.platform === rightAddress.platform &&
|
|
73
|
+
leftAddress.conversationId === rightAddress.conversationId);
|
|
74
|
+
}
|
|
75
|
+
function resolveConversationAddress(input) {
|
|
76
|
+
const address = createOfficeAddress(input.platform, input.conversationId);
|
|
77
|
+
if (input.address && !sameOffice(address, input.address)) {
|
|
78
|
+
throw new Error(`Conversation address mismatch for ${JSON.stringify(input.conversationId)} on ${input.platform}`);
|
|
79
|
+
}
|
|
80
|
+
return address;
|
|
81
|
+
}
|
|
82
|
+
export function createConversationEvent(input) {
|
|
83
|
+
const address = resolveConversationAddress(input);
|
|
84
|
+
const { platform: _platform, conversationId: _conversationId, address: _suppliedAddress, ...event } = input;
|
|
85
|
+
return { ...event, address };
|
|
86
|
+
}
|
|
87
|
+
export function createConversationMessage(input) {
|
|
88
|
+
const address = resolveConversationAddress(input);
|
|
89
|
+
const { platform: _platform, conversationId: _conversationId, address: _suppliedAddress, ...message } = input;
|
|
90
|
+
return { ...message, address };
|
|
91
|
+
}
|
|
92
|
+
export function buildGithubConversationId(ref) {
|
|
93
|
+
return `GH_${ref.owner.toLowerCase()}_${ref.repo.toLowerCase()}_${ref.number}`;
|
|
94
|
+
}
|
|
95
|
+
const GITHUB_CONVERSATION_ID_PATTERN = /^GH_([A-Za-z0-9-]+)_(.+)_(\d+)$/;
|
|
96
|
+
export function parseGithubConversationId(conversationId) {
|
|
97
|
+
const match = GITHUB_CONVERSATION_ID_PATTERN.exec(conversationId);
|
|
98
|
+
if (!match) {
|
|
99
|
+
throw new Error(`Not a GitHub conversation id: ${conversationId}`);
|
|
100
|
+
}
|
|
101
|
+
const [, owner, repo, number] = match;
|
|
102
|
+
if (owner === undefined || repo === undefined || number === undefined) {
|
|
103
|
+
throw new Error(`Not a GitHub conversation id: ${conversationId}`);
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
owner: owner.toLowerCase(),
|
|
107
|
+
repo: repo.toLowerCase(),
|
|
108
|
+
number: Number(number),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function assertOfficeKey(value) {
|
|
112
|
+
if (!OFFICE_KEY_PATTERN.test(value)) {
|
|
113
|
+
throw new Error(`Invalid office key: ${JSON.stringify(value)}`);
|
|
114
|
+
}
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
export function isOfficeKey(value) {
|
|
118
|
+
return typeof value === "string" && OFFICE_KEY_PATTERN.test(value);
|
|
119
|
+
}
|
|
120
|
+
function readableConversationId(conversationId) {
|
|
121
|
+
const readable = conversationId
|
|
122
|
+
.toLowerCase()
|
|
123
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
124
|
+
.replace(/^-+|-+$/g, "")
|
|
125
|
+
.slice(0, READABLE_ID_LENGTH)
|
|
126
|
+
.replace(/-+$/g, "");
|
|
127
|
+
return readable || "conversation";
|
|
128
|
+
}
|
|
129
|
+
export const RESERVED_WORKSPACE_NAMES = Object.freeze(new Set(["skills", "events", "agents", "MEMORY.md"]));
|
|
130
|
+
export function officeSessionsDir(dir) {
|
|
131
|
+
return join(dir, "sessions");
|
|
132
|
+
}
|
|
133
|
+
export function createWorkspace(options) {
|
|
134
|
+
const { root, stateDir } = options;
|
|
135
|
+
let registry;
|
|
136
|
+
const recorded = new Set();
|
|
137
|
+
const offices = new Map();
|
|
138
|
+
const workspace = Object.freeze({
|
|
139
|
+
root,
|
|
140
|
+
stateDir,
|
|
141
|
+
memoryPath: join(root, "MEMORY.md"),
|
|
142
|
+
skillsDir: join(root, "skills"),
|
|
143
|
+
agentsDir: join(root, "agents"),
|
|
144
|
+
reservedNames: RESERVED_WORKSPACE_NAMES,
|
|
145
|
+
office(address) {
|
|
146
|
+
const normalized = validateOfficeAddress(address);
|
|
147
|
+
const key = officeKey(normalized);
|
|
148
|
+
const existing = offices.get(key);
|
|
149
|
+
if (existing)
|
|
150
|
+
return existing;
|
|
151
|
+
const dir = join(root, key);
|
|
152
|
+
const office = Object.freeze({
|
|
153
|
+
address: normalized,
|
|
154
|
+
key,
|
|
155
|
+
dir,
|
|
156
|
+
memoryPath: join(dir, "MEMORY.md"),
|
|
157
|
+
skillsDir: join(dir, "skills"),
|
|
158
|
+
sessionsDir: officeSessionsDir(dir),
|
|
159
|
+
attachmentsDir: join(dir, "attachments"),
|
|
160
|
+
logPath: join(dir, OFFICE_LOG_FILENAME),
|
|
161
|
+
stateDir: join(stateDir, "conversations", key),
|
|
162
|
+
workspace,
|
|
163
|
+
ensure() {
|
|
164
|
+
if (!recorded.has(key)) {
|
|
165
|
+
registry ??= new OfficeRegistry(stateDir);
|
|
166
|
+
registry.recordOffice(normalized);
|
|
167
|
+
recorded.add(key);
|
|
168
|
+
}
|
|
169
|
+
ensureRegularOfficeDirectory(dir);
|
|
170
|
+
return dir;
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
offices.set(key, office);
|
|
174
|
+
return office;
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
return workspace;
|
|
178
|
+
}
|
|
179
|
+
function ensureRegularOfficeDirectory(dir) {
|
|
180
|
+
let stats;
|
|
181
|
+
try {
|
|
182
|
+
stats = lstatSync(dir);
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
if (err.code !== "ENOENT")
|
|
186
|
+
throw err;
|
|
187
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (stats.isSymbolicLink() || !stats.isDirectory()) {
|
|
191
|
+
throw new Error(`Office directory must be a regular non-symlink directory: ${dir}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const REGISTRY_VERSION = 1;
|
|
195
|
+
const REGISTRY_FILENAME = "office-registry.json";
|
|
196
|
+
const MIGRATION_STATUSES = new Set([
|
|
197
|
+
"needs-owner",
|
|
198
|
+
"prepared",
|
|
199
|
+
"moving",
|
|
200
|
+
"committed",
|
|
201
|
+
"failed",
|
|
202
|
+
]);
|
|
203
|
+
const REGISTRY_LOCK_FILENAME = ".office-registry.lock";
|
|
204
|
+
const REGISTRY_LOCK_RETRY_MS = 25;
|
|
205
|
+
const REGISTRY_LOCK_TIMEOUT_MS = 5_000;
|
|
206
|
+
const REGISTRY_LOCK_STALE_MS = 60_000;
|
|
207
|
+
export class OfficeRegistry {
|
|
208
|
+
constructor(stateDir, options = {}) {
|
|
209
|
+
this.stateDir = resolve(stateDir);
|
|
210
|
+
mkdirSync(this.stateDir, { recursive: true, mode: 0o700 });
|
|
211
|
+
assertRegularDirectory(this.stateDir, "State directory");
|
|
212
|
+
this.registryPath = resolve(this.stateDir, REGISTRY_FILENAME);
|
|
213
|
+
this.lockPath = join(this.stateDir, REGISTRY_LOCK_FILENAME);
|
|
214
|
+
this.writeState = options.writeState ?? atomicWritePrivateFile;
|
|
215
|
+
this.lockTimeoutMs = options.lockTimeoutMs ?? REGISTRY_LOCK_TIMEOUT_MS;
|
|
216
|
+
this.state = this.readState();
|
|
217
|
+
}
|
|
218
|
+
reload() {
|
|
219
|
+
this.state = this.readState();
|
|
220
|
+
return this.state;
|
|
221
|
+
}
|
|
222
|
+
getState() {
|
|
223
|
+
return this.state;
|
|
224
|
+
}
|
|
225
|
+
getMigration(rawConversationId) {
|
|
226
|
+
assertConversationId(rawConversationId);
|
|
227
|
+
return this.state.migrations.find((record) => record.rawConversationId === rawConversationId);
|
|
228
|
+
}
|
|
229
|
+
enablePlatform(platform) {
|
|
230
|
+
const validPlatform = assertPlatformName(platform);
|
|
231
|
+
return this.withExclusiveLease(() => {
|
|
232
|
+
if (this.state.enabledPlatforms.includes(validPlatform))
|
|
233
|
+
return this.state;
|
|
234
|
+
const enabledPlatforms = [...this.state.enabledPlatforms, validPlatform].toSorted();
|
|
235
|
+
this.replaceState(enabledPlatforms, this.state.offices, this.state.migrations);
|
|
236
|
+
return this.state;
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
recordOffice(address) {
|
|
240
|
+
const normalized = validateOfficeAddress(address);
|
|
241
|
+
const existing = this.findOffice(normalized);
|
|
242
|
+
if (existing)
|
|
243
|
+
return existing;
|
|
244
|
+
return this.withExclusiveLease(() => {
|
|
245
|
+
const found = this.findOffice(normalized);
|
|
246
|
+
if (found)
|
|
247
|
+
return found;
|
|
248
|
+
const record = Object.freeze({
|
|
249
|
+
platform: normalized.platform,
|
|
250
|
+
conversationId: normalized.conversationId,
|
|
251
|
+
recordedAt: new Date().toISOString(),
|
|
252
|
+
});
|
|
253
|
+
this.replaceState(this.state.enabledPlatforms, [...this.state.offices, record], this.state.migrations);
|
|
254
|
+
return record;
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
getOffices() {
|
|
258
|
+
return this.state.offices;
|
|
259
|
+
}
|
|
260
|
+
findOffice(address) {
|
|
261
|
+
return this.state.offices.find((record) => record.platform === address.platform && record.conversationId === address.conversationId);
|
|
262
|
+
}
|
|
263
|
+
prepareLegacyMigration(options) {
|
|
264
|
+
const rawConversationId = assertConversationId(options.rawConversationId);
|
|
265
|
+
const sourceDir = resolve(options.sourceDir);
|
|
266
|
+
const workspaceRoot = resolve(options.workspaceRoot);
|
|
267
|
+
return this.withExclusiveLease(() => {
|
|
268
|
+
const existing = this.getMigration(rawConversationId);
|
|
269
|
+
assertCanonicalSource(sourceDir, workspaceRoot, rawConversationId);
|
|
270
|
+
if (existing) {
|
|
271
|
+
assertSameMigrationInputs(existing, sourceDir, workspaceRoot);
|
|
272
|
+
if (existing.status !== "needs-owner")
|
|
273
|
+
return existing;
|
|
274
|
+
}
|
|
275
|
+
assertRegularDirectory(sourceDir, "Legacy office source");
|
|
276
|
+
const ownerPlatform = this.resolveOwner(options.ownerPlatform, rawConversationId);
|
|
277
|
+
if (!ownerPlatform) {
|
|
278
|
+
const record = makeRecord({
|
|
279
|
+
rawConversationId,
|
|
280
|
+
sourceDir,
|
|
281
|
+
workspaceRoot,
|
|
282
|
+
status: "needs-owner",
|
|
283
|
+
});
|
|
284
|
+
this.replaceMigration(existing, record);
|
|
285
|
+
return record;
|
|
286
|
+
}
|
|
287
|
+
const targetDir = officeDir(workspaceRoot, {
|
|
288
|
+
platform: ownerPlatform,
|
|
289
|
+
conversationId: rawConversationId,
|
|
290
|
+
});
|
|
291
|
+
if (pathExists(targetDir)) {
|
|
292
|
+
const failed = makeRecord({
|
|
293
|
+
rawConversationId,
|
|
294
|
+
sourceDir,
|
|
295
|
+
workspaceRoot,
|
|
296
|
+
ownerPlatform,
|
|
297
|
+
targetDir,
|
|
298
|
+
status: "failed",
|
|
299
|
+
error: "Target office directory already exists",
|
|
300
|
+
});
|
|
301
|
+
this.replaceMigration(existing, failed);
|
|
302
|
+
throw new Error(`${failed.error}: ${targetDir}`);
|
|
303
|
+
}
|
|
304
|
+
const prepared = makeRecord({
|
|
305
|
+
rawConversationId,
|
|
306
|
+
sourceDir,
|
|
307
|
+
workspaceRoot,
|
|
308
|
+
ownerPlatform,
|
|
309
|
+
targetDir,
|
|
310
|
+
status: "prepared",
|
|
311
|
+
});
|
|
312
|
+
this.replaceMigration(existing, prepared);
|
|
313
|
+
return prepared;
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
markMoving(rawConversationId) {
|
|
317
|
+
return this.withExclusiveLease(() => {
|
|
318
|
+
const record = this.requireMigration(rawConversationId);
|
|
319
|
+
if (record.status === "moving" ||
|
|
320
|
+
record.status === "committed" ||
|
|
321
|
+
record.status === "failed") {
|
|
322
|
+
return record;
|
|
323
|
+
}
|
|
324
|
+
if (record.status === "needs-owner") {
|
|
325
|
+
throw new Error(`Legacy office ${JSON.stringify(rawConversationId)} still needs an owner`);
|
|
326
|
+
}
|
|
327
|
+
assertRegularDirectory(record.sourceDir, "Legacy office source");
|
|
328
|
+
const targetDir = migrationTarget(record);
|
|
329
|
+
if (!targetDir)
|
|
330
|
+
throw new Error("Prepared office migration has no target directory");
|
|
331
|
+
if (pathExists(targetDir)) {
|
|
332
|
+
const failed = this.failRecord(record, "Target office directory appeared before moving");
|
|
333
|
+
throw new Error(`${failed.error}: ${targetDir}`);
|
|
334
|
+
}
|
|
335
|
+
const moving = transitionRecord(record, "moving");
|
|
336
|
+
this.replaceMigration(record, moving);
|
|
337
|
+
return moving;
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
markCommitted(rawConversationId) {
|
|
341
|
+
return this.withExclusiveLease(() => {
|
|
342
|
+
const record = this.requireMigration(rawConversationId);
|
|
343
|
+
if (record.status === "committed" || record.status === "failed")
|
|
344
|
+
return record;
|
|
345
|
+
if (record.status !== "moving") {
|
|
346
|
+
throw new Error(`Cannot commit office migration from ${record.status}`);
|
|
347
|
+
}
|
|
348
|
+
const targetDir = migrationTarget(record);
|
|
349
|
+
if (!targetDir)
|
|
350
|
+
throw new Error("Moving office migration has no target directory");
|
|
351
|
+
assertRegularDirectory(targetDir, "Migrated office target");
|
|
352
|
+
assertPathAbsent(record.sourceDir, "Legacy office source");
|
|
353
|
+
const committed = transitionRecord(record, "committed");
|
|
354
|
+
this.replaceMigration(record, committed);
|
|
355
|
+
return committed;
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
markFailed(rawConversationId, error) {
|
|
359
|
+
return this.withExclusiveLease(() => {
|
|
360
|
+
const record = this.requireMigration(rawConversationId);
|
|
361
|
+
if (record.status === "committed") {
|
|
362
|
+
throw new Error("A committed office migration cannot be marked failed");
|
|
363
|
+
}
|
|
364
|
+
if (record.status === "failed")
|
|
365
|
+
return record;
|
|
366
|
+
return this.failRecord(record, error);
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
resolveOwner(ownerPlatform, rawConversationId) {
|
|
370
|
+
if (ownerPlatform !== undefined) {
|
|
371
|
+
const validPlatform = assertPlatformName(ownerPlatform);
|
|
372
|
+
if (!this.state.enabledPlatforms.includes(validPlatform)) {
|
|
373
|
+
throw new Error(`Owner platform ${validPlatform} is not enabled`);
|
|
374
|
+
}
|
|
375
|
+
return validPlatform;
|
|
376
|
+
}
|
|
377
|
+
const candidates = platformsMatchingConversationIdFormat(rawConversationId, this.state.enabledPlatforms);
|
|
378
|
+
return candidates.length === 1 ? candidates[0] : undefined;
|
|
379
|
+
}
|
|
380
|
+
requireMigration(rawConversationId) {
|
|
381
|
+
assertConversationId(rawConversationId);
|
|
382
|
+
const record = this.getMigration(rawConversationId);
|
|
383
|
+
if (!record)
|
|
384
|
+
throw new Error(`No office migration registered for ${rawConversationId}`);
|
|
385
|
+
return record;
|
|
386
|
+
}
|
|
387
|
+
failRecord(record, error) {
|
|
388
|
+
const message = error.trim();
|
|
389
|
+
if (!message)
|
|
390
|
+
throw new Error("Office migration failure reason must not be empty");
|
|
391
|
+
const failed = transitionRecord(record, "failed", message);
|
|
392
|
+
this.replaceMigration(record, failed);
|
|
393
|
+
return failed;
|
|
394
|
+
}
|
|
395
|
+
replaceMigration(previous, next) {
|
|
396
|
+
const migrations = [...this.state.migrations];
|
|
397
|
+
const index = previous
|
|
398
|
+
? migrations.findIndex((record) => record.rawConversationId === previous.rawConversationId)
|
|
399
|
+
: -1;
|
|
400
|
+
if (index === -1)
|
|
401
|
+
migrations.push(next);
|
|
402
|
+
else
|
|
403
|
+
migrations[index] = next;
|
|
404
|
+
this.replaceState(this.state.enabledPlatforms, this.state.offices, migrations);
|
|
405
|
+
}
|
|
406
|
+
replaceState(enabledPlatforms, offices, migrations) {
|
|
407
|
+
const candidate = freezeState({ enabledPlatforms, offices, migrations });
|
|
408
|
+
this.writeState(this.registryPath, `${JSON.stringify(candidate, null, 2)}\n`);
|
|
409
|
+
this.state = candidate;
|
|
410
|
+
}
|
|
411
|
+
withExclusiveLease(operation) {
|
|
412
|
+
const release = acquireRegistryLease(this.lockPath, this.lockTimeoutMs);
|
|
413
|
+
try {
|
|
414
|
+
this.state = this.readState();
|
|
415
|
+
return operation();
|
|
416
|
+
}
|
|
417
|
+
finally {
|
|
418
|
+
release();
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
readState() {
|
|
422
|
+
assertRegistryFileSafe(this.registryPath);
|
|
423
|
+
const raw = readTextFileIfExists(this.registryPath);
|
|
424
|
+
if (raw === undefined) {
|
|
425
|
+
return freezeState({ enabledPlatforms: [], offices: [], migrations: [] });
|
|
426
|
+
}
|
|
427
|
+
let value;
|
|
428
|
+
try {
|
|
429
|
+
value = JSON.parse(raw);
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
throw new Error(`Invalid office registry JSON at ${this.registryPath}`, { cause: error });
|
|
433
|
+
}
|
|
434
|
+
return parseState(value, this.registryPath);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function makeRecord(fields) {
|
|
438
|
+
const record = {
|
|
439
|
+
rawConversationId: fields.rawConversationId,
|
|
440
|
+
sourceDir: fields.sourceDir,
|
|
441
|
+
workspaceRoot: fields.workspaceRoot,
|
|
442
|
+
ownerPlatform: fields.ownerPlatform ? fields.ownerPlatform : undefined,
|
|
443
|
+
targetDir: fields.targetDir ? fields.targetDir : undefined,
|
|
444
|
+
status: fields.status,
|
|
445
|
+
error: fields.error ? fields.error : undefined,
|
|
446
|
+
updatedAt: fields.updatedAt ?? new Date().toISOString(),
|
|
447
|
+
};
|
|
448
|
+
return Object.freeze(record);
|
|
449
|
+
}
|
|
450
|
+
function transitionRecord(record, status, error) {
|
|
451
|
+
const targetDir = migrationTarget(record);
|
|
452
|
+
return makeRecord({
|
|
453
|
+
rawConversationId: record.rawConversationId,
|
|
454
|
+
sourceDir: record.sourceDir,
|
|
455
|
+
workspaceRoot: record.workspaceRoot,
|
|
456
|
+
ownerPlatform: record.ownerPlatform,
|
|
457
|
+
targetDir,
|
|
458
|
+
status,
|
|
459
|
+
error,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
function migrationTarget(record) {
|
|
463
|
+
return record.ownerPlatform
|
|
464
|
+
? officeDir(record.workspaceRoot, {
|
|
465
|
+
platform: record.ownerPlatform,
|
|
466
|
+
conversationId: record.rawConversationId,
|
|
467
|
+
})
|
|
468
|
+
: undefined;
|
|
469
|
+
}
|
|
470
|
+
function freezeState(input) {
|
|
471
|
+
return Object.freeze({
|
|
472
|
+
version: REGISTRY_VERSION,
|
|
473
|
+
enabledPlatforms: Object.freeze([...input.enabledPlatforms]),
|
|
474
|
+
offices: Object.freeze(input.offices.map((record) => Object.freeze({ ...record }))),
|
|
475
|
+
migrations: Object.freeze(input.migrations.map((record) => Object.freeze({ ...record }))),
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
function parseState(value, path) {
|
|
479
|
+
if (!isRecord(value) || value.version !== REGISTRY_VERSION) {
|
|
480
|
+
throw new Error(`Invalid office registry version at ${path}`);
|
|
481
|
+
}
|
|
482
|
+
if (!Array.isArray(value.enabledPlatforms) || !Array.isArray(value.migrations)) {
|
|
483
|
+
throw new Error(`Invalid office registry shape at ${path}`);
|
|
484
|
+
}
|
|
485
|
+
const enabledPlatforms = value.enabledPlatforms.map((platform) => {
|
|
486
|
+
if (typeof platform !== "string")
|
|
487
|
+
throw new Error(`Invalid enabled platform in ${path}`);
|
|
488
|
+
return assertPlatformName(platform);
|
|
489
|
+
});
|
|
490
|
+
if (new Set(enabledPlatforms).size !== enabledPlatforms.length) {
|
|
491
|
+
throw new Error(`Duplicate enabled platform in ${path}`);
|
|
492
|
+
}
|
|
493
|
+
const offices = (Array.isArray(value.offices) ? value.offices : []).map((entry) => parseOfficeRecord(entry, path));
|
|
494
|
+
if (new Set(offices.map((record) => officeKey(record))).size !== offices.length) {
|
|
495
|
+
throw new Error(`Duplicate office record in ${path}`);
|
|
496
|
+
}
|
|
497
|
+
const migrations = value.migrations.map((entry) => parseRecord(entry, path, enabledPlatforms));
|
|
498
|
+
if (new Set(migrations.map((record) => record.rawConversationId)).size !== migrations.length) {
|
|
499
|
+
throw new Error(`Duplicate office migration in ${path}`);
|
|
500
|
+
}
|
|
501
|
+
return freezeState({ enabledPlatforms, offices, migrations });
|
|
502
|
+
}
|
|
503
|
+
function parseOfficeRecord(value, path) {
|
|
504
|
+
if (!isRecord(value))
|
|
505
|
+
throw new Error(`Invalid office record in ${path}`);
|
|
506
|
+
if (typeof value.platform !== "string" ||
|
|
507
|
+
typeof value.conversationId !== "string" ||
|
|
508
|
+
typeof value.recordedAt !== "string") {
|
|
509
|
+
throw new Error(`Invalid office record fields in ${path}`);
|
|
510
|
+
}
|
|
511
|
+
return Object.freeze({
|
|
512
|
+
platform: assertPlatformName(value.platform),
|
|
513
|
+
conversationId: assertConversationId(value.conversationId),
|
|
514
|
+
recordedAt: value.recordedAt,
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
function hasMigrationStrings(value) {
|
|
518
|
+
return (typeof value.rawConversationId === "string" &&
|
|
519
|
+
typeof value.sourceDir === "string" &&
|
|
520
|
+
typeof value.workspaceRoot === "string" &&
|
|
521
|
+
typeof value.status === "string" &&
|
|
522
|
+
typeof value.updatedAt === "string");
|
|
523
|
+
}
|
|
524
|
+
function parseMigrationFields(value, path) {
|
|
525
|
+
if (!hasMigrationStrings(value)) {
|
|
526
|
+
throw new Error(`Invalid office migration fields in ${path}`);
|
|
527
|
+
}
|
|
528
|
+
assertConversationId(value.rawConversationId);
|
|
529
|
+
if (!isAbsolute(value.sourceDir) || !isAbsolute(value.workspaceRoot)) {
|
|
530
|
+
throw new Error(`Office migration paths must be absolute in ${path}`);
|
|
531
|
+
}
|
|
532
|
+
assertCanonicalSource(value.sourceDir, value.workspaceRoot, value.rawConversationId);
|
|
533
|
+
if (!MIGRATION_STATUSES.has(value.status)) {
|
|
534
|
+
throw new Error(`Invalid office migration status in ${path}`);
|
|
535
|
+
}
|
|
536
|
+
return {
|
|
537
|
+
rawConversationId: value.rawConversationId,
|
|
538
|
+
sourceDir: value.sourceDir,
|
|
539
|
+
workspaceRoot: value.workspaceRoot,
|
|
540
|
+
status: value.status,
|
|
541
|
+
updatedAt: value.updatedAt,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
function assertOwnershipMatchesStatus(status, ownerPlatform, targetDir, path) {
|
|
545
|
+
const owned = ownerPlatform !== undefined;
|
|
546
|
+
const targeted = targetDir !== undefined;
|
|
547
|
+
if (status === "needs-owner" && (owned || targeted)) {
|
|
548
|
+
throw new Error(`Needs-owner migration cannot have an owner or target in ${path}`);
|
|
549
|
+
}
|
|
550
|
+
if (status !== "needs-owner" && status !== "failed" && !(owned && targeted)) {
|
|
551
|
+
throw new Error(`Prepared office migration is missing ownership in ${path}`);
|
|
552
|
+
}
|
|
553
|
+
if (!owned && targeted) {
|
|
554
|
+
throw new Error(`Office migration target has no owner in ${path}`);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
function parseRecord(value, path, enabledPlatforms) {
|
|
558
|
+
if (!isRecord(value))
|
|
559
|
+
throw new Error(`Invalid office migration record in ${path}`);
|
|
560
|
+
const fields = parseMigrationFields(value, path);
|
|
561
|
+
const ownerPlatform = optionalPlatform(value.ownerPlatform);
|
|
562
|
+
const targetDir = optionalString(value.targetDir);
|
|
563
|
+
const error = optionalString(value.error);
|
|
564
|
+
if (ownerPlatform !== undefined && !enabledPlatforms.includes(ownerPlatform)) {
|
|
565
|
+
throw new Error(`Office migration owner is not enabled in ${path}`);
|
|
566
|
+
}
|
|
567
|
+
assertOwnershipMatchesStatus(fields.status, ownerPlatform, targetDir, path);
|
|
568
|
+
const expectedTargetDir = ownerPlatform
|
|
569
|
+
? officeDir(fields.workspaceRoot, {
|
|
570
|
+
platform: ownerPlatform,
|
|
571
|
+
conversationId: fields.rawConversationId,
|
|
572
|
+
})
|
|
573
|
+
: undefined;
|
|
574
|
+
if (targetDir !== expectedTargetDir) {
|
|
575
|
+
throw new Error(`Office migration target does not match its office address in ${path}`);
|
|
576
|
+
}
|
|
577
|
+
if (fields.status === "failed" && !error) {
|
|
578
|
+
throw new Error(`Failed office migration is missing an error in ${path}`);
|
|
579
|
+
}
|
|
580
|
+
return buildMigrationRecord(fields, ownerPlatform, expectedTargetDir, error);
|
|
581
|
+
}
|
|
582
|
+
function buildMigrationRecord(fields, ownerPlatform, targetDir, error) {
|
|
583
|
+
return makeRecord({
|
|
584
|
+
rawConversationId: fields.rawConversationId,
|
|
585
|
+
sourceDir: fields.sourceDir,
|
|
586
|
+
workspaceRoot: fields.workspaceRoot,
|
|
587
|
+
ownerPlatform,
|
|
588
|
+
targetDir,
|
|
589
|
+
status: fields.status,
|
|
590
|
+
error,
|
|
591
|
+
updatedAt: fields.updatedAt,
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
function optionalPlatform(value) {
|
|
595
|
+
return value === undefined
|
|
596
|
+
? undefined
|
|
597
|
+
: typeof value === "string"
|
|
598
|
+
? assertPlatformName(value)
|
|
599
|
+
: failOptional("platform");
|
|
600
|
+
}
|
|
601
|
+
function optionalString(value) {
|
|
602
|
+
return value === undefined
|
|
603
|
+
? undefined
|
|
604
|
+
: typeof value === "string"
|
|
605
|
+
? value
|
|
606
|
+
: failOptional("string");
|
|
607
|
+
}
|
|
608
|
+
function failOptional(label) {
|
|
609
|
+
throw new Error(`Invalid optional ${label} in office registry`);
|
|
610
|
+
}
|
|
611
|
+
function assertSameMigrationInputs(existing, sourceDir, workspaceRoot) {
|
|
612
|
+
if (existing.sourceDir !== sourceDir || existing.workspaceRoot !== workspaceRoot) {
|
|
613
|
+
throw new Error(`Legacy office migration inputs changed for ${existing.rawConversationId}`);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
function assertCanonicalSource(sourceDir, workspaceRoot, rawConversationId) {
|
|
617
|
+
const expectedSourceDir = resolve(workspaceRoot, rawConversationId);
|
|
618
|
+
if (sourceDir !== expectedSourceDir) {
|
|
619
|
+
throw new Error(`Legacy office source must be ${expectedSourceDir}`);
|
|
620
|
+
}
|
|
621
|
+
assertRegularDirectory(workspaceRoot, "Workspace root");
|
|
622
|
+
assertPathIfPresent(sourceDir, "Legacy office source");
|
|
623
|
+
}
|
|
624
|
+
function assertRegularDirectory(path, label) {
|
|
625
|
+
let stat;
|
|
626
|
+
try {
|
|
627
|
+
stat = lstatSync(path);
|
|
628
|
+
}
|
|
629
|
+
catch (error) {
|
|
630
|
+
throw new Error(`${label} does not exist: ${path}`, { cause: error });
|
|
631
|
+
}
|
|
632
|
+
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
633
|
+
throw new Error(`${label} must be a regular directory: ${path}`);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
function lstatIfExists(path) {
|
|
637
|
+
try {
|
|
638
|
+
return lstatSync(path);
|
|
639
|
+
}
|
|
640
|
+
catch (error) {
|
|
641
|
+
if (isErrno(error, "ENOENT"))
|
|
642
|
+
return undefined;
|
|
643
|
+
throw error;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
function assertRegistryFileSafe(path) {
|
|
647
|
+
const stat = lstatIfExists(path);
|
|
648
|
+
if (stat && (stat.isSymbolicLink() || !stat.isFile())) {
|
|
649
|
+
throw new Error(`Office registry must be a regular file: ${path}`);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
function assertPathIfPresent(path, label) {
|
|
653
|
+
const stat = lstatIfExists(path);
|
|
654
|
+
if (stat && (stat.isSymbolicLink() || !stat.isDirectory())) {
|
|
655
|
+
throw new Error(`${label} must be a regular directory: ${path}`);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
function assertPathAbsent(path, label) {
|
|
659
|
+
if (lstatIfExists(path))
|
|
660
|
+
throw new Error(`${label} must be absent: ${path}`);
|
|
661
|
+
}
|
|
662
|
+
function pathExists(path) {
|
|
663
|
+
return lstatIfExists(path) !== undefined;
|
|
664
|
+
}
|
|
665
|
+
function claimRegistryLock(lockPath, token) {
|
|
666
|
+
mkdirSync(lockPath, { mode: 0o700 });
|
|
667
|
+
try {
|
|
668
|
+
writeFileSync(join(lockPath, "owner"), `${token}\n`, { mode: 0o600 });
|
|
669
|
+
}
|
|
670
|
+
catch (error) {
|
|
671
|
+
rmSync(lockPath, { recursive: true, force: true });
|
|
672
|
+
throw error;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
function acquireRegistryLease(lockPath, timeoutMs) {
|
|
676
|
+
const deadline = Date.now() + timeoutMs;
|
|
677
|
+
const token = `${process.pid}:${randomBytes(8).toString("hex")}`;
|
|
678
|
+
for (;;) {
|
|
679
|
+
try {
|
|
680
|
+
claimRegistryLock(lockPath, token);
|
|
681
|
+
return () => releaseRegistryLease(lockPath, token);
|
|
682
|
+
}
|
|
683
|
+
catch (error) {
|
|
684
|
+
awaitFreeRegistryLock(lockPath, deadline, error);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
function awaitFreeRegistryLock(lockPath, deadline, error) {
|
|
689
|
+
if (!isErrno(error, "EEXIST"))
|
|
690
|
+
throw error;
|
|
691
|
+
if (registryLockIsStale(lockPath)) {
|
|
692
|
+
rmSync(lockPath, { recursive: true, force: true });
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
if (Date.now() >= deadline) {
|
|
696
|
+
throw new Error(`Timed out acquiring office registry lock: ${lockPath}`, { cause: error });
|
|
697
|
+
}
|
|
698
|
+
sleepSync(REGISTRY_LOCK_RETRY_MS);
|
|
699
|
+
}
|
|
700
|
+
function releaseRegistryLease(lockPath, token) {
|
|
701
|
+
try {
|
|
702
|
+
if (readFileSync(join(lockPath, "owner"), "utf8").trim() === token) {
|
|
703
|
+
rmSync(lockPath, { recursive: true, force: true });
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
catch (error) {
|
|
707
|
+
if (!isErrno(error, "ENOENT"))
|
|
708
|
+
throw error;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
function registryLockIsStale(lockPath) {
|
|
712
|
+
let ownerKnown = false;
|
|
713
|
+
let ownerAlive = false;
|
|
714
|
+
try {
|
|
715
|
+
const owner = readFileSync(join(lockPath, "owner"), "utf8").trim();
|
|
716
|
+
const pid = Number(owner.split(":", 1)[0]);
|
|
717
|
+
if (Number.isInteger(pid) && pid > 0) {
|
|
718
|
+
ownerKnown = true;
|
|
719
|
+
try {
|
|
720
|
+
process.kill(pid, 0);
|
|
721
|
+
ownerAlive = true;
|
|
722
|
+
}
|
|
723
|
+
catch (error) {
|
|
724
|
+
if (isErrno(error, "EPERM"))
|
|
725
|
+
ownerAlive = true;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
catch { }
|
|
730
|
+
try {
|
|
731
|
+
const oldEnough = Date.now() - statSync(lockPath).mtimeMs >= REGISTRY_LOCK_STALE_MS;
|
|
732
|
+
return ownerKnown ? !ownerAlive : oldEnough;
|
|
733
|
+
}
|
|
734
|
+
catch {
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
function sleepSync(milliseconds) {
|
|
739
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
|
|
740
|
+
}
|
|
741
|
+
export function listRegisteredOffices(stateDir) {
|
|
742
|
+
return new OfficeRegistry(stateDir).getOffices();
|
|
743
|
+
}
|
|
744
|
+
function platformsMatchingConversationIdFormat(rawConversationId, enabledPlatforms) {
|
|
745
|
+
return enabledPlatforms.filter((platform) => {
|
|
746
|
+
switch (platform) {
|
|
747
|
+
case "github":
|
|
748
|
+
return isGithubConversationId(rawConversationId);
|
|
749
|
+
case "telegram":
|
|
750
|
+
return /^-?\d+$/.test(rawConversationId);
|
|
751
|
+
case "discord":
|
|
752
|
+
return /^\d+$/.test(rawConversationId);
|
|
753
|
+
case "slack":
|
|
754
|
+
return /^[A-Z][A-Z0-9]*$/.test(rawConversationId);
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
function isGithubConversationId(rawConversationId) {
|
|
759
|
+
try {
|
|
760
|
+
parseGithubConversationId(rawConversationId);
|
|
761
|
+
return true;
|
|
762
|
+
}
|
|
763
|
+
catch {
|
|
764
|
+
return false;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
function isErrno(error, code) {
|
|
768
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
769
|
+
}
|
|
770
|
+
export function migrateLegacyOffices(options) {
|
|
771
|
+
const registry = new OfficeRegistry(options.stateDir);
|
|
772
|
+
for (const platform of options.enabledPlatforms)
|
|
773
|
+
registry.enablePlatform(platform);
|
|
774
|
+
const summary = {
|
|
775
|
+
migrated: [],
|
|
776
|
+
recovered: [],
|
|
777
|
+
unowned: [],
|
|
778
|
+
failed: [],
|
|
779
|
+
vaultKeysMigrated: [],
|
|
780
|
+
vaultConflicts: [],
|
|
781
|
+
stateDirsMigrated: [],
|
|
782
|
+
stateDirConflicts: [],
|
|
783
|
+
};
|
|
784
|
+
recoverInterruptedMoves(registry, summary);
|
|
785
|
+
claimAndMoveLegacyDirs(registry, options.workspaceRoot, summary);
|
|
786
|
+
const vaults = migrateConversationVaultKeys({
|
|
787
|
+
stateDir: options.stateDir,
|
|
788
|
+
offices: registry.getOffices(),
|
|
789
|
+
});
|
|
790
|
+
summary.vaultKeysMigrated = vaults.migrated;
|
|
791
|
+
summary.vaultConflicts = vaults.conflicts;
|
|
792
|
+
for (const rawConversationId of vaults.migrated) {
|
|
793
|
+
log.logInfo(`[office] Migrated vault key to office key: ${rawConversationId}`);
|
|
794
|
+
}
|
|
795
|
+
migrateConversationStateDirs(registry, options.stateDir, summary);
|
|
796
|
+
for (const record of registry.getState().migrations) {
|
|
797
|
+
if (record.status === "needs-owner")
|
|
798
|
+
summary.unowned.push(record.rawConversationId);
|
|
799
|
+
else if (record.status === "failed")
|
|
800
|
+
summary.failed.push(record.rawConversationId);
|
|
801
|
+
}
|
|
802
|
+
return summary;
|
|
803
|
+
}
|
|
804
|
+
function recoverInterruptedMoves(registry, summary) {
|
|
805
|
+
for (const record of registry.getState().migrations) {
|
|
806
|
+
if (record.status !== "moving")
|
|
807
|
+
continue;
|
|
808
|
+
const failure = finishInterruptedMove(record);
|
|
809
|
+
if (failure) {
|
|
810
|
+
registry.markFailed(record.rawConversationId, failure);
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
registry.markCommitted(record.rawConversationId);
|
|
814
|
+
recordMigratedOffice(registry, record);
|
|
815
|
+
summary.recovered.push(record.rawConversationId);
|
|
816
|
+
log.logInfo(`[office] Recovered interrupted migration: ${record.rawConversationId}`);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
function finishInterruptedMove(record) {
|
|
820
|
+
const targetDir = record.targetDir;
|
|
821
|
+
if (!targetDir)
|
|
822
|
+
return "Moving record has no target directory";
|
|
823
|
+
const sourceExists = pathExists(record.sourceDir);
|
|
824
|
+
const targetExists = pathExists(targetDir);
|
|
825
|
+
if (sourceExists && targetExists) {
|
|
826
|
+
return "Both legacy source and office target exist; merge them manually";
|
|
827
|
+
}
|
|
828
|
+
if (!sourceExists && !targetExists)
|
|
829
|
+
return "Neither legacy source nor office target exists";
|
|
830
|
+
if (sourceExists)
|
|
831
|
+
renameSync(record.sourceDir, targetDir);
|
|
832
|
+
return undefined;
|
|
833
|
+
}
|
|
834
|
+
function isClaimableLegacyDir(registry, workspaceRoot, rawConversationId) {
|
|
835
|
+
const existing = registry.getMigration(rawConversationId);
|
|
836
|
+
if (existing?.status === "committed") {
|
|
837
|
+
throw new Error(`Legacy office directory reappeared after migration: ${join(workspaceRoot, rawConversationId)}`);
|
|
838
|
+
}
|
|
839
|
+
return existing?.status !== "failed";
|
|
840
|
+
}
|
|
841
|
+
function claimAndMoveLegacyDirs(registry, workspaceRoot, summary) {
|
|
842
|
+
for (const rawConversationId of listLegacyOfficeDirs(workspaceRoot)) {
|
|
843
|
+
if (!isClaimableLegacyDir(registry, workspaceRoot, rawConversationId))
|
|
844
|
+
continue;
|
|
845
|
+
const record = registry.prepareLegacyMigration({
|
|
846
|
+
rawConversationId,
|
|
847
|
+
sourceDir: join(workspaceRoot, rawConversationId),
|
|
848
|
+
workspaceRoot,
|
|
849
|
+
});
|
|
850
|
+
if (record.status === "needs-owner")
|
|
851
|
+
continue;
|
|
852
|
+
const moving = registry.markMoving(rawConversationId);
|
|
853
|
+
const targetDir = moving.targetDir;
|
|
854
|
+
if (!targetDir)
|
|
855
|
+
throw new Error("Moving office migration has no target directory");
|
|
856
|
+
renameSync(moving.sourceDir, targetDir);
|
|
857
|
+
registry.markCommitted(rawConversationId);
|
|
858
|
+
recordMigratedOffice(registry, moving);
|
|
859
|
+
summary.migrated.push(rawConversationId);
|
|
860
|
+
log.logInfo(`[office] Migrated office directory: ${rawConversationId} -> ${targetDir}`);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
function migrateConversationStateDirs(registry, stateDir, summary) {
|
|
864
|
+
for (const office of registry.getOffices()) {
|
|
865
|
+
const legacyDir = join(stateDir, "conversations", office.conversationId);
|
|
866
|
+
if (!existsSync(legacyDir))
|
|
867
|
+
continue;
|
|
868
|
+
const targetDir = officeStateDir(stateDir, office);
|
|
869
|
+
if (existsSync(targetDir)) {
|
|
870
|
+
summary.stateDirConflicts.push(office.conversationId);
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
renameSync(legacyDir, targetDir);
|
|
874
|
+
summary.stateDirsMigrated.push(office.conversationId);
|
|
875
|
+
log.logInfo(`[office] Migrated host state dir to office key: ${office.conversationId}`);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
function recordMigratedOffice(registry, record) {
|
|
879
|
+
if (!record.ownerPlatform)
|
|
880
|
+
return;
|
|
881
|
+
registry.recordOffice({
|
|
882
|
+
platform: record.ownerPlatform,
|
|
883
|
+
conversationId: record.rawConversationId,
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
function listLegacyOfficeDirs(workspaceRoot) {
|
|
887
|
+
return readdirSync(workspaceRoot, { withFileTypes: true })
|
|
888
|
+
.filter((entry) => isLegacyOfficeDir(workspaceRoot, entry))
|
|
889
|
+
.map((entry) => entry.name)
|
|
890
|
+
.toSorted();
|
|
891
|
+
}
|
|
892
|
+
function isLegacyOfficeDir(workspaceRoot, entry) {
|
|
893
|
+
if (entry.name.startsWith("."))
|
|
894
|
+
return false;
|
|
895
|
+
if (RESERVED_WORKSPACE_NAMES.has(entry.name))
|
|
896
|
+
return false;
|
|
897
|
+
if (isOfficeKey(entry.name))
|
|
898
|
+
return false;
|
|
899
|
+
if (entry.isSymbolicLink()) {
|
|
900
|
+
throw new Error(`Workspace entry must not be a symlink: ${join(workspaceRoot, entry.name)}`);
|
|
901
|
+
}
|
|
902
|
+
if (!entry.isDirectory())
|
|
903
|
+
return false;
|
|
904
|
+
if (looksLikeConversationOffice(join(workspaceRoot, entry.name)))
|
|
905
|
+
return true;
|
|
906
|
+
log.logInfo(`[office] Skipping non-office workspace directory (no ${OFFICE_LOG_FILENAME} or sessions/): ${entry.name}`);
|
|
907
|
+
return false;
|
|
908
|
+
}
|
|
909
|
+
function looksLikeConversationOffice(dir) {
|
|
910
|
+
return existsSync(join(dir, OFFICE_LOG_FILENAME)) || existsSync(join(dir, "sessions"));
|
|
911
|
+
}
|
|
912
|
+
export function formatUnmigratedOfficesError(summary) {
|
|
913
|
+
const lines = ["Conversation office migration cannot complete:"];
|
|
914
|
+
if (summary.unowned.length > 0) {
|
|
915
|
+
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>");
|
|
916
|
+
}
|
|
917
|
+
lines.push(...conflictSection(summary.failed, [
|
|
918
|
+
"These migrations previously failed and need manual repair (see",
|
|
919
|
+
"office-registry.json in the state dir for each error):",
|
|
920
|
+
]), ...conflictSection(summary.vaultConflicts, [
|
|
921
|
+
"These conversations have credentials under both the legacy and the",
|
|
922
|
+
"office-key vault directory; merge them manually under <state-dir>/vaults:",
|
|
923
|
+
]), ...conflictSection(summary.stateDirConflicts, [
|
|
924
|
+
"These conversations have host state under both the legacy and the",
|
|
925
|
+
"office-key directory; merge them manually under <state-dir>/conversations:",
|
|
926
|
+
]));
|
|
927
|
+
return lines.join("\n");
|
|
928
|
+
}
|
|
929
|
+
function conflictSection(ids, explanation) {
|
|
930
|
+
if (ids.length === 0)
|
|
931
|
+
return [];
|
|
932
|
+
return ["", ...explanation, ...ids.map((id) => ` - ${id}`)];
|
|
933
|
+
}
|
|
934
|
+
function replacePrefix(path, pairs) {
|
|
935
|
+
for (const [oldPrefix, newPrefix] of pairs) {
|
|
936
|
+
if (path === oldPrefix)
|
|
937
|
+
return newPrefix;
|
|
938
|
+
if (path.startsWith(`${oldPrefix}/`))
|
|
939
|
+
return newPrefix + path.slice(oldPrefix.length);
|
|
940
|
+
}
|
|
941
|
+
return path;
|
|
942
|
+
}
|
|
943
|
+
export function buildContainerBindTranslator(options) {
|
|
944
|
+
const hostPairs = [];
|
|
945
|
+
const guestPairs = [];
|
|
946
|
+
for (const office of options.offices) {
|
|
947
|
+
const key = officeKey(office);
|
|
948
|
+
const rawId = office.conversationId;
|
|
949
|
+
hostPairs.push([join(options.workspaceRoot, rawId), join(options.workspaceRoot, key)]);
|
|
950
|
+
hostPairs.push([
|
|
951
|
+
join(options.stateDir, "conversations", rawId),
|
|
952
|
+
officeStateDir(options.stateDir, office),
|
|
953
|
+
]);
|
|
954
|
+
hostPairs.push([
|
|
955
|
+
join(options.stateDir, "vaults", legacyConversationCredentialKey(rawId)),
|
|
956
|
+
join(options.stateDir, "vaults", key),
|
|
957
|
+
]);
|
|
958
|
+
guestPairs.push([guestWorkspacePath(rawId), guestWorkspacePath(key)]);
|
|
959
|
+
}
|
|
960
|
+
return (bindSpec) => {
|
|
961
|
+
const readOnly = bindSpec.endsWith(":ro");
|
|
962
|
+
const spec = readOnly ? bindSpec.slice(0, -3) : bindSpec;
|
|
963
|
+
const separator = spec.indexOf(":");
|
|
964
|
+
if (separator === -1)
|
|
965
|
+
return bindSpec;
|
|
966
|
+
const source = replacePrefix(spec.slice(0, separator), hostPairs);
|
|
967
|
+
const target = replacePrefix(spec.slice(separator + 1), guestPairs);
|
|
968
|
+
return `${source}:${target}${readOnly ? ":ro" : ""}`;
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
//# sourceMappingURL=index.js.map
|