@geminixiang/mikan 1.0.0-beta.2 → 1.0.0-beta.20
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 +354 -0
- package/README.md +42 -16
- package/dist/adapter.d.ts +1 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +1 -0
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +36 -67
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +17 -42
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +148 -0
- package/dist/adapters/github/bot.d.ts.map +1 -0
- package/dist/adapters/github/bot.js +1031 -0
- package/dist/adapters/github/bot.js.map +1 -0
- package/dist/adapters/github/client.d.ts +118 -0
- package/dist/adapters/github/client.d.ts.map +1 -0
- package/dist/adapters/github/client.js +309 -0
- package/dist/adapters/github/client.js.map +1 -0
- package/dist/adapters/github/cloudbuild.d.ts +24 -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 +9 -0
- package/dist/adapters/github/context.d.ts.map +1 -0
- package/dist/adapters/github/context.js +175 -0
- package/dist/adapters/github/context.js.map +1 -0
- package/dist/adapters/github/gcp-auth.d.ts +31 -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/ids.d.ts +34 -0
- package/dist/adapters/github/ids.d.ts.map +1 -0
- package/dist/adapters/github/ids.js +53 -0
- package/dist/adapters/github/ids.js.map +1 -0
- package/dist/adapters/github/repo.d.ts +30 -0
- package/dist/adapters/github/repo.d.ts.map +1 -0
- package/dist/adapters/github/repo.js +136 -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 +24 -0
- package/dist/adapters/github/tools/checks.d.ts.map +1 -0
- package/dist/adapters/github/tools/checks.js +116 -0
- package/dist/adapters/github/tools/checks.js.map +1 -0
- package/dist/adapters/github/tools/issue.d.ts +22 -0
- package/dist/adapters/github/tools/issue.d.ts.map +1 -0
- package/dist/adapters/github/tools/issue.js +59 -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 +59 -0
- package/dist/adapters/github/tools/pr.js.map +1 -0
- package/dist/adapters/github/tools/read.d.ts +22 -0
- package/dist/adapters/github/tools/read.d.ts.map +1 -0
- package/dist/adapters/github/tools/read.js +152 -0
- package/dist/adapters/github/tools/read.js.map +1 -0
- package/dist/adapters/github/tools/review-reply.d.ts +19 -0
- package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
- package/dist/adapters/github/tools/review-reply.js +49 -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 +45 -0
- package/dist/adapters/github/tools/sync.js.map +1 -0
- package/dist/adapters/github/types.d.ts +350 -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 +79 -22
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +8 -6
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +81 -133
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +3 -14
- 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 +14 -17
- 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 +5 -8
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/streaming.d.ts +4 -0
- package/dist/adapters/streaming.d.ts.map +1 -1
- package/dist/adapters/streaming.js +11 -0
- package/dist/adapters/streaming.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +1 -2
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +27 -62
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +8 -27
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +28 -2
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent.d.ts +38 -14
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +358 -224
- package/dist/agent.js.map +1 -1
- package/dist/cli/download.d.ts.map +1 -0
- package/dist/cli/download.js.map +1 -0
- package/dist/cli/ext-git.d.ts +22 -0
- package/dist/cli/ext-git.d.ts.map +1 -0
- package/dist/cli/ext-git.js +76 -0
- package/dist/cli/ext-git.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 +217 -0
- package/dist/cli/ext.js.map +1 -0
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +2 -1
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +2 -6
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/extensions.d.ts.map +1 -1
- package/dist/commands/extensions.js +16 -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 +30 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/manifest.d.ts +72 -0
- package/dist/commands/manifest.d.ts.map +1 -0
- package/dist/commands/manifest.js +121 -0
- package/dist/commands/manifest.js.map +1 -0
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +3 -1
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +2 -1
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +16 -12
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/text.d.ts +2 -0
- package/dist/commands/text.d.ts.map +1 -0
- package/dist/commands/text.js +16 -0
- package/dist/commands/text.js.map +1 -0
- package/dist/commands/types.d.ts +14 -1
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +90 -54
- package/dist/config.js.map +1 -1
- package/dist/events.d.ts +10 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +14 -5
- package/dist/events.js.map +1 -1
- package/dist/execution-resolver.d.ts +3 -2
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +28 -12
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/extensions/loader.d.ts +39 -9
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +258 -54
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/extensions/registry.d.ts +48 -1
- package/dist/harness/extensions/registry.d.ts.map +1 -1
- package/dist/harness/extensions/registry.js +146 -0
- package/dist/harness/extensions/registry.js.map +1 -1
- package/dist/harness/extensions/types.d.ts +161 -14
- 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 +5 -5
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +2 -2
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/models.d.ts +5 -0
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +10 -0
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/runner.d.ts +21 -2
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +80 -22
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session-store.d.ts +4 -1
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +11 -2
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/subagent-runner.d.ts +17 -0
- package/dist/harness/subagent-runner.d.ts.map +1 -0
- package/dist/harness/subagent-runner.js +307 -0
- package/dist/harness/subagent-runner.js.map +1 -0
- package/dist/harness/types.d.ts +53 -0
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.js +232 -29
- package/dist/main.js.map +1 -1
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +2 -5
- 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 +264 -41
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +32 -5
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts +2 -0
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +7 -0
- 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 +8 -2
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/firecracker.d.ts +2 -0
- package/dist/sandbox/firecracker.d.ts.map +1 -1
- package/dist/sandbox/firecracker.js +7 -1
- package/dist/sandbox/firecracker.js.map +1 -1
- package/dist/sandbox/gondolin-fleet.d.ts +104 -0
- package/dist/sandbox/gondolin-fleet.d.ts.map +1 -0
- package/dist/sandbox/gondolin-fleet.js +330 -0
- package/dist/sandbox/gondolin-fleet.js.map +1 -0
- package/dist/sandbox/gondolin-gateway.d.ts +85 -0
- package/dist/sandbox/gondolin-gateway.d.ts.map +1 -0
- package/dist/sandbox/gondolin-gateway.js +400 -0
- package/dist/sandbox/gondolin-gateway.js.map +1 -0
- package/dist/sandbox/gondolin-inventory.d.ts +89 -0
- package/dist/sandbox/gondolin-inventory.d.ts.map +1 -0
- package/dist/sandbox/gondolin-inventory.js +267 -0
- package/dist/sandbox/gondolin-inventory.js.map +1 -0
- package/dist/sandbox/gondolin-join.d.ts +62 -0
- package/dist/sandbox/gondolin-join.d.ts.map +1 -0
- package/dist/sandbox/gondolin-join.js +261 -0
- package/dist/sandbox/gondolin-join.js.map +1 -0
- package/dist/sandbox/gondolin-nfs-advisory.d.ts +15 -0
- package/dist/sandbox/gondolin-nfs-advisory.d.ts.map +1 -0
- package/dist/sandbox/gondolin-nfs-advisory.js +60 -0
- package/dist/sandbox/gondolin-nfs-advisory.js.map +1 -0
- package/dist/sandbox/gondolin-placement.d.ts +32 -0
- package/dist/sandbox/gondolin-placement.d.ts.map +1 -0
- package/dist/sandbox/gondolin-placement.js +83 -0
- package/dist/sandbox/gondolin-placement.js.map +1 -0
- package/dist/sandbox/gondolin-remote.d.ts +73 -0
- package/dist/sandbox/gondolin-remote.d.ts.map +1 -0
- package/dist/sandbox/gondolin-remote.js +352 -0
- package/dist/sandbox/gondolin-remote.js.map +1 -0
- package/dist/sandbox/gondolin-worker-client.d.ts +139 -0
- package/dist/sandbox/gondolin-worker-client.d.ts.map +1 -0
- package/dist/sandbox/gondolin-worker-client.js +325 -0
- package/dist/sandbox/gondolin-worker-client.js.map +1 -0
- package/dist/sandbox/gondolin-worker-main.d.ts +2 -0
- package/dist/sandbox/gondolin-worker-main.d.ts.map +1 -0
- package/dist/sandbox/gondolin-worker-main.js +22 -0
- package/dist/sandbox/gondolin-worker-main.js.map +1 -0
- package/dist/sandbox/gondolin-worker.d.ts +55 -0
- package/dist/sandbox/gondolin-worker.d.ts.map +1 -0
- package/dist/sandbox/gondolin-worker.js +201 -0
- package/dist/sandbox/gondolin-worker.js.map +1 -0
- package/dist/sandbox/gondolin.d.ts +52 -0
- package/dist/sandbox/gondolin.d.ts.map +1 -0
- package/dist/sandbox/gondolin.js +425 -0
- package/dist/sandbox/gondolin.js.map +1 -0
- package/dist/sandbox/host.d.ts +2 -0
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +11 -0
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +21 -0
- package/dist/sandbox/identity.d.ts.map +1 -0
- package/dist/sandbox/identity.js +36 -0
- package/dist/sandbox/identity.js.map +1 -0
- package/dist/sandbox/index.d.ts +4 -3
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +5 -3
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/types.d.ts +26 -1
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +11 -0
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +35 -0
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -1
- package/dist/sessions/agent-memory-file-manager.js +16 -30
- package/dist/sessions/agent-memory-file-manager.js.map +1 -1
- package/dist/sessions/history-line.d.ts +20 -0
- package/dist/sessions/history-line.d.ts.map +1 -0
- package/dist/sessions/history-line.js +24 -0
- package/dist/sessions/history-line.js.map +1 -0
- package/dist/sessions/policy.d.ts.map +1 -1
- package/dist/sessions/policy.js +5 -3
- package/dist/sessions/policy.js.map +1 -1
- package/dist/sessions/session-key.d.ts +31 -0
- package/dist/sessions/session-key.d.ts.map +1 -0
- package/dist/sessions/session-key.js +44 -0
- package/dist/sessions/session-key.js.map +1 -0
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +2 -2
- package/dist/sessions/store.js.map +1 -1
- package/dist/tools/bash.d.ts +3 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +24 -17
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +9 -12
- 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 +33 -4
- package/dist/tools/event.js.map +1 -1
- package/dist/tools/generate-image.d.ts +17 -0
- package/dist/tools/generate-image.d.ts.map +1 -0
- package/dist/tools/generate-image.js +63 -0
- package/dist/tools/generate-image.js.map +1 -0
- package/dist/tools/index.d.ts +16 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +27 -3
- 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 +40 -0
- package/dist/tools/react.js.map +1 -0
- package/dist/tools/sandbox.d.ts +2 -2
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/sandbox.js +8 -7
- package/dist/tools/sandbox.js.map +1 -1
- package/dist/tools/subagent.d.ts +69 -0
- package/dist/tools/subagent.d.ts.map +1 -0
- package/dist/tools/subagent.js +286 -0
- package/dist/tools/subagent.js.map +1 -0
- package/dist/tools/types.d.ts +34 -1
- 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 +1 -8
- package/dist/tools/write.js.map +1 -1
- package/dist/trigger.d.ts.map +1 -1
- package/dist/trigger.js +1 -2
- package/dist/trigger.js.map +1 -1
- package/dist/types.d.ts +139 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.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 +23 -0
- package/dist/vault/disabled.js.map +1 -0
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +3 -24
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/policy.d.ts +20 -0
- package/dist/vault/policy.d.ts.map +1 -0
- package/dist/vault/policy.js +20 -0
- package/dist/vault/policy.js.map +1 -0
- package/dist/vault/routing.d.ts +1 -0
- package/dist/vault/routing.d.ts.map +1 -1
- package/dist/vault/routing.js +3 -10
- package/dist/vault/routing.js.map +1 -1
- package/dist/web/admin/portal.d.ts +27 -0
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +91 -130
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/types.d.ts +3 -0
- 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 +0 -31
- package/dist/web/login/oauth.js.map +1 -1
- package/dist/web/login/portal.js +1 -1
- 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 +4 -0
- package/dist/web/portal-shell.d.ts.map +1 -0
- package/dist/{portal-shell.js → web/portal-shell.js} +2 -2
- package/dist/web/portal-shell.js.map +1 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +7 -0
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-view/command.d.ts.map +1 -1
- package/dist/web/session-view/command.js +4 -1
- package/dist/web/session-view/command.js.map +1 -1
- package/dist/web/session-view/portal.d.ts.map +1 -1
- package/dist/web/session-view/portal.js +4 -3
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/web/session-view/service.d.ts.map +1 -1
- package/dist/web/session-view/service.js +2 -1
- package/dist/web/session-view/service.js.map +1 -1
- package/dist/web/session-view/types.d.ts +2 -1
- package/dist/web/session-view/types.d.ts.map +1 -1
- package/dist/web/session-view/types.js.map +1 -1
- package/package.json +7 -4
- 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/{download.d.ts → cli/download.d.ts} +0 -0
- /package/dist/{download.js → cli/download.js} +0 -0
package/dist/sandbox/index.d.ts
CHANGED
|
@@ -2,16 +2,17 @@ import { ContainerExecutor } from "./container.js";
|
|
|
2
2
|
import { FirecrackerExecutor } from "./firecracker.js";
|
|
3
3
|
import { CloudflareSandboxExecutor } from "./cloudflare.js";
|
|
4
4
|
import { HostExecutor } from "./host.js";
|
|
5
|
+
import { GondolinExecutor } from "./gondolin.js";
|
|
5
6
|
import type { Executor, SandboxAdapter, SandboxConfig } from "./types.js";
|
|
6
7
|
export type { CloudflareSandboxConfig, ExecOptions, ExecResult, Executor, RuntimePathContext, SandboxAdapter, SandboxConfig, } from "./types.js";
|
|
7
|
-
export { CloudflareSandboxExecutor, ContainerExecutor, FirecrackerExecutor, HostExecutor };
|
|
8
|
+
export { CloudflareSandboxExecutor, ContainerExecutor, FirecrackerExecutor, HostExecutor, GondolinExecutor, };
|
|
8
9
|
export { SandboxError } from "./errors.js";
|
|
9
|
-
declare const sandboxAdapters: readonly [SandboxAdapter<import("./types.js").HostSandboxConfig>, SandboxAdapter<import("./types.js").ContainerSandboxConfig>, SandboxAdapter<import("./types.js").ImageSandboxConfig>, SandboxAdapter<import("./types.js").FirecrackerSandboxConfig>, SandboxAdapter<import("./types.js").CloudflareSandboxConfig>];
|
|
10
|
+
declare const sandboxAdapters: readonly [SandboxAdapter<import("./types.js").HostSandboxConfig>, SandboxAdapter<import("./types.js").ContainerSandboxConfig>, SandboxAdapter<import("./types.js").ImageSandboxConfig>, SandboxAdapter<import("./types.js").GondolinSandboxConfig>, SandboxAdapter<import("./types.js").FirecrackerSandboxConfig>, SandboxAdapter<import("./types.js").CloudflareSandboxConfig>];
|
|
10
11
|
export declare function getSandboxAdapters(): readonly [...typeof sandboxAdapters];
|
|
11
12
|
export declare function parseSandboxArg(value: string): SandboxConfig;
|
|
12
13
|
export declare function validateSandbox(config: SandboxConfig): Promise<void>;
|
|
13
14
|
/**
|
|
14
|
-
* Create an executor that runs commands on host, in Docker, in a Firecracker VM, or through a Cloudflare sandbox bridge.
|
|
15
|
+
* Create an executor that runs commands on host, in Docker, in a microVM, in a Firecracker VM, or through a Cloudflare sandbox bridge.
|
|
15
16
|
*/
|
|
16
17
|
export declare function createExecutor(config: SandboxConfig, env?: Record<string, string>, ensureReady?: () => Promise<void>): Executor;
|
|
17
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA2B,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAA6B,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAA4B,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAsB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA2B,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAA6B,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAA4B,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAsB,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAA0B,MAAM,eAAe,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE1E,YAAY,EACV,uBAAuB,EACvB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,GACjB,CAAC;AACF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,QAAA,MAAM,eAAe,kXAOX,CAAC;AAKX,wBAAgB,kBAAkB,IAAI,SAAS,CAAC,GAAG,OAAO,eAAe,CAAC,CAEzE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAiB5D;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAChC,QAAQ,CASV"}
|
package/dist/sandbox/index.js
CHANGED
|
@@ -3,13 +3,15 @@ import { FirecrackerExecutor, firecrackerSandboxAdapter } from "./firecracker.js
|
|
|
3
3
|
import { CloudflareSandboxExecutor, cloudflareSandboxAdapter } from "./cloudflare.js";
|
|
4
4
|
import { HostExecutor, hostSandboxAdapter } from "./host.js";
|
|
5
5
|
import { imageSandboxAdapter } from "./image.js";
|
|
6
|
+
import { GondolinExecutor, gondolinSandboxAdapter } from "./gondolin.js";
|
|
6
7
|
import { SandboxError } from "./errors.js";
|
|
7
|
-
export { CloudflareSandboxExecutor, ContainerExecutor, FirecrackerExecutor, HostExecutor };
|
|
8
|
+
export { CloudflareSandboxExecutor, ContainerExecutor, FirecrackerExecutor, HostExecutor, GondolinExecutor, };
|
|
8
9
|
export { SandboxError } from "./errors.js";
|
|
9
10
|
const sandboxAdapters = [
|
|
10
11
|
hostSandboxAdapter,
|
|
11
12
|
containerSandboxAdapter,
|
|
12
13
|
imageSandboxAdapter,
|
|
14
|
+
gondolinSandboxAdapter,
|
|
13
15
|
firecrackerSandboxAdapter,
|
|
14
16
|
cloudflareSandboxAdapter,
|
|
15
17
|
];
|
|
@@ -27,7 +29,7 @@ export function parseSandboxArg(value) {
|
|
|
27
29
|
if (value.startsWith("docker:")) {
|
|
28
30
|
throw new SandboxError(`Error: '${value}' is not supported. Use 'container:<container-name>' for the shared-container mode or 'image:<image-name>' for mikan-managed per-user containers.`);
|
|
29
31
|
}
|
|
30
|
-
throw new SandboxError(`Error: Invalid sandbox type '${value}'. Use 'host', 'container:<container-name>', 'image:<image-name>', 'firecracker:<vm-id>:<host-path>', or 'cloudflare:<sandbox-id>'`);
|
|
32
|
+
throw new SandboxError(`Error: Invalid sandbox type '${value}'. Use 'host', 'container:<container-name>', 'image:<image-name>', 'gondolin:default', 'firecracker:<vm-id>:<host-path>', or 'cloudflare:<sandbox-id>'`);
|
|
31
33
|
}
|
|
32
34
|
export async function validateSandbox(config) {
|
|
33
35
|
const adapter = sandboxAdapterByType.get(config.type);
|
|
@@ -37,7 +39,7 @@ export async function validateSandbox(config) {
|
|
|
37
39
|
await adapter.validate?.(config);
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
40
|
-
* Create an executor that runs commands on host, in Docker, in a Firecracker VM, or through a Cloudflare sandbox bridge.
|
|
42
|
+
* Create an executor that runs commands on host, in Docker, in a microVM, in a Firecracker VM, or through a Cloudflare sandbox bridge.
|
|
41
43
|
*/
|
|
42
44
|
export function createExecutor(config, env, ensureReady) {
|
|
43
45
|
const adapter = sandboxAdapterByType.get(config.type);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAY3C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAY3C,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,GACjB,CAAC;AACF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,eAAe,GAAG;IACtB,kBAAkB;IAClB,uBAAuB;IACvB,mBAAmB;IACnB,sBAAsB;IACtB,yBAAyB;IACzB,wBAAwB;CAChB,CAAC;AACX,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAClC,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CACZ,CAAC;AAEhD,MAAM,UAAU,kBAAkB;IAChC,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,YAAY,CACpB,WAAW,KAAK,mJAAmJ,CACpK,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,YAAY,CACpB,gCAAgC,KAAK,wJAAwJ,CAC9L,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAqB;IACzD,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,YAAY,CAAC,oCAAoC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAqB,EACrB,GAA4B,EAC5B,WAAiC;IAEjC,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,YAAY,CAAC,oCAAoC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,IAAI,YAAY,CAAC,oEAAoE,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;AAC1D,CAAC","sourcesContent":["import { ContainerExecutor, containerSandboxAdapter } from \"./container.js\";\nimport { FirecrackerExecutor, firecrackerSandboxAdapter } from \"./firecracker.js\";\nimport { CloudflareSandboxExecutor, cloudflareSandboxAdapter } from \"./cloudflare.js\";\nimport { HostExecutor, hostSandboxAdapter } from \"./host.js\";\nimport { imageSandboxAdapter } from \"./image.js\";\nimport { GondolinExecutor, gondolinSandboxAdapter } from \"./gondolin.js\";\nimport { SandboxError } from \"./errors.js\";\nimport type { Executor, SandboxAdapter, SandboxConfig } from \"./types.js\";\n\nexport type {\n CloudflareSandboxConfig,\n ExecOptions,\n ExecResult,\n Executor,\n RuntimePathContext,\n SandboxAdapter,\n SandboxConfig,\n} from \"./types.js\";\nexport {\n CloudflareSandboxExecutor,\n ContainerExecutor,\n FirecrackerExecutor,\n HostExecutor,\n GondolinExecutor,\n};\nexport { SandboxError } from \"./errors.js\";\n\nconst sandboxAdapters = [\n hostSandboxAdapter,\n containerSandboxAdapter,\n imageSandboxAdapter,\n gondolinSandboxAdapter,\n firecrackerSandboxAdapter,\n cloudflareSandboxAdapter,\n] as const;\nconst sandboxAdapterByType = new Map(\n sandboxAdapters.map((adapter) => [adapter.type, adapter]),\n) as Map<SandboxConfig[\"type\"], SandboxAdapter>;\n\nexport function getSandboxAdapters(): readonly [...typeof sandboxAdapters] {\n return sandboxAdapters;\n}\n\nexport function parseSandboxArg(value: string): SandboxConfig {\n for (const adapter of sandboxAdapters) {\n const config = adapter.parse(value);\n if (config) {\n return config;\n }\n }\n\n if (value.startsWith(\"docker:\")) {\n throw new SandboxError(\n `Error: '${value}' is not supported. Use 'container:<container-name>' for the shared-container mode or 'image:<image-name>' for mikan-managed per-user containers.`,\n );\n }\n\n throw new SandboxError(\n `Error: Invalid sandbox type '${value}'. Use 'host', 'container:<container-name>', 'image:<image-name>', 'gondolin:default', 'firecracker:<vm-id>:<host-path>', or 'cloudflare:<sandbox-id>'`,\n );\n}\n\nexport async function validateSandbox(config: SandboxConfig): Promise<void> {\n const adapter = sandboxAdapterByType.get(config.type);\n if (!adapter) {\n throw new SandboxError(`Error: Unsupported sandbox type '${config.type}'`);\n }\n\n await adapter.validate?.(config);\n}\n\n/**\n * Create an executor that runs commands on host, in Docker, in a microVM, in a Firecracker VM, or through a Cloudflare sandbox bridge.\n */\nexport function createExecutor(\n config: SandboxConfig,\n env?: Record<string, string>,\n ensureReady?: () => Promise<void>,\n): Executor {\n const adapter = sandboxAdapterByType.get(config.type);\n if (!adapter) {\n throw new SandboxError(`Error: Unsupported sandbox type '${config.type}'`);\n }\n if (!adapter.createExecutor) {\n throw new SandboxError(\"Error: image sandbox must resolve to a concrete container executor\");\n }\n return adapter.createExecutor(config, env, ensureReady);\n}\n"]}
|
package/dist/sandbox/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type SandboxConfig = HostSandboxConfig | ContainerSandboxConfig | ImageSandboxConfig | FirecrackerSandboxConfig | CloudflareSandboxConfig;
|
|
1
|
+
export type SandboxConfig = HostSandboxConfig | ContainerSandboxConfig | ImageSandboxConfig | GondolinSandboxConfig | FirecrackerSandboxConfig | CloudflareSandboxConfig;
|
|
2
2
|
export interface HostSandboxConfig {
|
|
3
3
|
type: "host";
|
|
4
4
|
}
|
|
@@ -10,6 +10,19 @@ export interface ImageSandboxConfig {
|
|
|
10
10
|
type: "image";
|
|
11
11
|
image: string;
|
|
12
12
|
}
|
|
13
|
+
export interface GondolinSandboxConfig {
|
|
14
|
+
type: "gondolin";
|
|
15
|
+
profile: "default" | "remote";
|
|
16
|
+
/** Local-only runtime details supplied after actor/workspace resolution. */
|
|
17
|
+
image?: string;
|
|
18
|
+
workspacePath?: string;
|
|
19
|
+
mounts?: Array<{
|
|
20
|
+
source: string;
|
|
21
|
+
target: string;
|
|
22
|
+
}>;
|
|
23
|
+
instanceId?: string;
|
|
24
|
+
resourceKey?: string;
|
|
25
|
+
}
|
|
13
26
|
export interface FirecrackerSandboxConfig {
|
|
14
27
|
type: "firecracker";
|
|
15
28
|
vmId: string;
|
|
@@ -26,6 +39,18 @@ export interface Executor {
|
|
|
26
39
|
* Execute a bash command.
|
|
27
40
|
*/
|
|
28
41
|
exec(command: string, options?: ExecOptions): Promise<ExecResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Read a runtime file as UTF-8 text. The executor owns the transport, so
|
|
44
|
+
* file contents never pass through shell argv or extra shell parse layers.
|
|
45
|
+
*/
|
|
46
|
+
readFile(path: string, options?: ExecOptions): Promise<string>;
|
|
47
|
+
/**
|
|
48
|
+
* Write a runtime file, creating parent directories and replacing via a
|
|
49
|
+
* staging file so an aborted write never truncates the target. Like
|
|
50
|
+
* readFile, transport is the executor's concern — content must survive
|
|
51
|
+
* arbitrary quoting and ARG_MAX limits.
|
|
52
|
+
*/
|
|
53
|
+
writeFile(path: string, content: string, options?: ExecOptions): Promise<void>;
|
|
29
54
|
/**
|
|
30
55
|
* Get the workspace path prefix for this executor.
|
|
31
56
|
* Host: returns the actual path.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB,iBAAiB,GACjB,sBAAsB,GACtB,kBAAkB,GAClB,wBAAwB,GACxB,uBAAuB,CAAC;AAE5B,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAElE;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3C;;OAEG;IACH,cAAc,CAAC,iBAAiB,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAE9D;;OAEG;IACH,gBAAgB,IAAI,aAAa,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;CACrD;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc,CAAC,OAAO,SAAS,aAAa,GAAG,aAAa;IAC3E,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,cAAc,CAAC,CACb,MAAM,EAAE,OAAO,EACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAChC,QAAQ,CAAC;CACb"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"","sourcesContent":["export type SandboxConfig =\n | HostSandboxConfig\n | ContainerSandboxConfig\n | ImageSandboxConfig\n | FirecrackerSandboxConfig\n | CloudflareSandboxConfig;\n\nexport interface HostSandboxConfig {\n type: \"host\";\n}\n\nexport interface ContainerSandboxConfig {\n type: \"container\";\n container: string;\n}\n\nexport interface ImageSandboxConfig {\n type: \"image\";\n image: string;\n}\n\nexport interface FirecrackerSandboxConfig {\n type: \"firecracker\";\n vmId: string;\n hostPath: string;\n sshUser?: string;\n sshPort?: number;\n}\n\nexport interface CloudflareSandboxConfig {\n type: \"cloudflare\";\n sandboxId: string;\n}\n\nexport interface Executor {\n /**\n * Execute a bash command.\n */\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n\n /**\n * Get the workspace path prefix for this executor.\n * Host: returns the actual path.\n * Container/Firecracker: returns /workspace.\n */\n getWorkspacePath(hostPath: string): string;\n\n /**\n * Return explicit host/control-plane/runtime path semantics for this executor.\n */\n getPathContext(hostWorkspaceRoot: string): RuntimePathContext;\n\n /**\n * Get the current sandbox config used by this executor.\n */\n getSandboxConfig(): SandboxConfig;\n}\n\nexport interface RuntimePathContext {\n /** Host-side workspace root used by mikan's control plane. */\n hostWorkspaceRoot: string;\n /** Workspace root as seen by bash/read/write/edit inside the runtime. */\n runtimeWorkspaceRoot: string;\n /** Translate a runtime path back to a host path when the runtime is host-backed. */\n runtimeToHostPath?: (runtimePath: string) => string;\n}\n\nexport interface ExecOptions {\n timeout?: number;\n signal?: AbortSignal;\n}\n\nexport interface ExecResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\nexport interface SandboxAdapter<TConfig extends SandboxConfig = SandboxConfig> {\n type: TConfig[\"type\"];\n parse(value: string): TConfig | undefined;\n validate?(config: TConfig): Promise<void>;\n createExecutor?(\n config: TConfig,\n env?: Record<string, string>,\n ensureReady?: () => Promise<void>,\n ): Executor;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"","sourcesContent":["export type SandboxConfig =\n | HostSandboxConfig\n | ContainerSandboxConfig\n | ImageSandboxConfig\n | GondolinSandboxConfig\n | FirecrackerSandboxConfig\n | CloudflareSandboxConfig;\n\nexport interface HostSandboxConfig {\n type: \"host\";\n}\n\nexport interface ContainerSandboxConfig {\n type: \"container\";\n container: string;\n}\n\nexport interface ImageSandboxConfig {\n type: \"image\";\n image: string;\n}\n\nexport interface GondolinSandboxConfig {\n type: \"gondolin\";\n profile: \"default\" | \"remote\";\n /** Local-only runtime details supplied after actor/workspace resolution. */\n image?: string;\n workspacePath?: string;\n mounts?: Array<{ source: string; target: string }>;\n instanceId?: string;\n resourceKey?: string;\n}\n\nexport interface FirecrackerSandboxConfig {\n type: \"firecracker\";\n vmId: string;\n hostPath: string;\n sshUser?: string;\n sshPort?: number;\n}\n\nexport interface CloudflareSandboxConfig {\n type: \"cloudflare\";\n sandboxId: string;\n}\n\nexport interface Executor {\n /**\n * Execute a bash command.\n */\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n\n /**\n * Read a runtime file as UTF-8 text. The executor owns the transport, so\n * file contents never pass through shell argv or extra shell parse layers.\n */\n readFile(path: string, options?: ExecOptions): Promise<string>;\n\n /**\n * Write a runtime file, creating parent directories and replacing via a\n * staging file so an aborted write never truncates the target. Like\n * readFile, transport is the executor's concern — content must survive\n * arbitrary quoting and ARG_MAX limits.\n */\n writeFile(path: string, content: string, options?: ExecOptions): Promise<void>;\n\n /**\n * Get the workspace path prefix for this executor.\n * Host: returns the actual path.\n * Container/Firecracker: returns /workspace.\n */\n getWorkspacePath(hostPath: string): string;\n\n /**\n * Return explicit host/control-plane/runtime path semantics for this executor.\n */\n getPathContext(hostWorkspaceRoot: string): RuntimePathContext;\n\n /**\n * Get the current sandbox config used by this executor.\n */\n getSandboxConfig(): SandboxConfig;\n}\n\nexport interface RuntimePathContext {\n /** Host-side workspace root used by mikan's control plane. */\n hostWorkspaceRoot: string;\n /** Workspace root as seen by bash/read/write/edit inside the runtime. */\n runtimeWorkspaceRoot: string;\n /** Translate a runtime path back to a host path when the runtime is host-backed. */\n runtimeToHostPath?: (runtimePath: string) => string;\n}\n\nexport interface ExecOptions {\n timeout?: number;\n signal?: AbortSignal;\n}\n\nexport interface ExecResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\nexport interface SandboxAdapter<TConfig extends SandboxConfig = SandboxConfig> {\n type: TConfig[\"type\"];\n parse(value: string): TConfig | undefined;\n validate?(config: TConfig): Promise<void>;\n createExecutor?(\n config: TConfig,\n env?: Record<string, string>,\n ensureReady?: () => Promise<void>,\n ): Executor;\n}\n"]}
|
package/dist/sandbox/utils.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
export declare function execSimple(cmd: string, args: string[]): Promise<string>;
|
|
2
2
|
export declare function killProcessTree(pid: number): void;
|
|
3
3
|
export declare function shellEscape(s: string): string;
|
|
4
|
+
interface ExecLikeResult {
|
|
5
|
+
stdout: string;
|
|
6
|
+
stderr: string;
|
|
7
|
+
code: number;
|
|
8
|
+
}
|
|
9
|
+
interface ExecLike<TOptions> {
|
|
10
|
+
exec(command: string, options?: TOptions): Promise<ExecLikeResult>;
|
|
11
|
+
}
|
|
12
|
+
export declare function execReadFile<TOptions>(executor: ExecLike<TOptions>, path: string, options?: TOptions): Promise<string>;
|
|
13
|
+
export declare function execWriteFile<TOptions>(executor: ExecLike<TOptions>, path: string, content: string, options?: TOptions): Promise<void>;
|
|
14
|
+
export {};
|
|
4
15
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sandbox/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBvE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAqBjD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7C"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sandbox/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBvE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAqBjD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7C;AAWD,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,QAAQ,CAAC,QAAQ;IACzB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACpE;AAED,wBAAsB,YAAY,CAAC,QAAQ,EACzC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAC1C,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,IAAI,CAAC,CAuBf"}
|
package/dist/sandbox/utils.js
CHANGED
|
@@ -48,4 +48,39 @@ export function shellEscape(s) {
|
|
|
48
48
|
// Escape for passing to sh -c
|
|
49
49
|
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Shared exec-backed file transport for executors whose only channel into the
|
|
53
|
+
* runtime is `exec` (docker exec, ssh, HTTP). Contents travel base64-encoded —
|
|
54
|
+
* the base64 alphabet is inert under every shell parse layer — and writes are
|
|
55
|
+
* chunked so no single command approaches the per-argument ARG_MAX limit,
|
|
56
|
+
* staged, then moved into place so an aborted write never truncates the file.
|
|
57
|
+
*/
|
|
58
|
+
const WRITE_CHUNK_CHARS = 65536;
|
|
59
|
+
export async function execReadFile(executor, path, options) {
|
|
60
|
+
const result = await executor.exec(`base64 < ${shellEscape(path)}`, options);
|
|
61
|
+
if (result.code !== 0) {
|
|
62
|
+
throw new Error(result.stderr.trim() || `Failed to read file: ${path}`);
|
|
63
|
+
}
|
|
64
|
+
return Buffer.from(result.stdout.replace(/\s+/g, ""), "base64").toString("utf-8");
|
|
65
|
+
}
|
|
66
|
+
export async function execWriteFile(executor, path, content, options) {
|
|
67
|
+
const encoded = Buffer.from(content, "utf-8").toString("base64");
|
|
68
|
+
const escapedPath = shellEscape(path);
|
|
69
|
+
const stage = shellEscape(`${path}.mikan-stage`);
|
|
70
|
+
const stageB64 = shellEscape(`${path}.mikan-stage.b64`);
|
|
71
|
+
const run = async (command) => {
|
|
72
|
+
const result = await executor.exec(command, options);
|
|
73
|
+
if (result.code !== 0) {
|
|
74
|
+
await executor.exec(`rm -f ${stage} ${stageB64}`, options).catch(() => { });
|
|
75
|
+
throw new Error(result.stderr.trim() || `Failed to write file: ${path}`);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const dir = path.includes("/") ? path.slice(0, path.lastIndexOf("/")) || "/" : ".";
|
|
79
|
+
await run(`mkdir -p ${shellEscape(dir)} && : > ${stageB64}`);
|
|
80
|
+
for (let offset = 0; offset === 0 || offset < encoded.length; offset += WRITE_CHUNK_CHARS) {
|
|
81
|
+
const chunk = encoded.slice(offset, offset + WRITE_CHUNK_CHARS);
|
|
82
|
+
await run(`printf '%s' ${shellEscape(chunk)} >> ${stageB64}`);
|
|
83
|
+
}
|
|
84
|
+
await run(`base64 -d < ${stageB64} > ${stage} && mv ${stage} ${escapedPath} && rm -f ${stageB64}`);
|
|
85
|
+
}
|
|
51
86
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/sandbox/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,IAAc;IACpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACtE,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;YAC7B,MAAM,IAAI,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;YAC7B,MAAM,IAAI,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,CAAC,MAAM,CAAC,CAAC;;gBAC3B,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,KAAK,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;gBACnD,KAAK,EAAE,QAAQ;gBACf,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,uBAAuB;YACzB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,8BAA8B;IAC9B,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AACzC,CAAC","sourcesContent":["import { spawn } from \"child_process\";\n\nexport function execSimple(cmd: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout?.on(\"data\", (d) => {\n stdout += d;\n });\n child.stderr?.on(\"data\", (d) => {\n stderr += d;\n });\n child.on(\"close\", (code) => {\n if (code === 0) resolve(stdout);\n else reject(new Error(stderr || `Exit code ${code}`));\n });\n });\n}\n\nexport function killProcessTree(pid: number): void {\n if (process.platform === \"win32\") {\n try {\n spawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n stdio: \"ignore\",\n detached: true,\n });\n } catch {\n // Ignore errors\n }\n } else {\n try {\n process.kill(-pid, \"SIGKILL\");\n } catch {\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {\n // Process already dead\n }\n }\n }\n}\n\nexport function shellEscape(s: string): string {\n // Escape for passing to sh -c\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/sandbox/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"child_process\";\n\nexport function execSimple(cmd: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout?.on(\"data\", (d) => {\n stdout += d;\n });\n child.stderr?.on(\"data\", (d) => {\n stderr += d;\n });\n child.on(\"close\", (code) => {\n if (code === 0) resolve(stdout);\n else reject(new Error(stderr || `Exit code ${code}`));\n });\n });\n}\n\nexport function killProcessTree(pid: number): void {\n if (process.platform === \"win32\") {\n try {\n spawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n stdio: \"ignore\",\n detached: true,\n });\n } catch {\n // Ignore errors\n }\n } else {\n try {\n process.kill(-pid, \"SIGKILL\");\n } catch {\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {\n // Process already dead\n }\n }\n }\n}\n\nexport function shellEscape(s: string): string {\n // Escape for passing to sh -c\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\n/**\n * Shared exec-backed file transport for executors whose only channel into the\n * runtime is `exec` (docker exec, ssh, HTTP). Contents travel base64-encoded —\n * the base64 alphabet is inert under every shell parse layer — and writes are\n * chunked so no single command approaches the per-argument ARG_MAX limit,\n * staged, then moved into place so an aborted write never truncates the file.\n */\nconst WRITE_CHUNK_CHARS = 65536;\n\ninterface ExecLikeResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\ninterface ExecLike<TOptions> {\n exec(command: string, options?: TOptions): Promise<ExecLikeResult>;\n}\n\nexport async function execReadFile<TOptions>(\n executor: ExecLike<TOptions>,\n path: string,\n options?: TOptions,\n): Promise<string> {\n const result = await executor.exec(`base64 < ${shellEscape(path)}`, options);\n if (result.code !== 0) {\n throw new Error(result.stderr.trim() || `Failed to read file: ${path}`);\n }\n return Buffer.from(result.stdout.replace(/\\s+/g, \"\"), \"base64\").toString(\"utf-8\");\n}\n\nexport async function execWriteFile<TOptions>(\n executor: ExecLike<TOptions>,\n path: string,\n content: string,\n options?: TOptions,\n): Promise<void> {\n const encoded = Buffer.from(content, \"utf-8\").toString(\"base64\");\n const escapedPath = shellEscape(path);\n const stage = shellEscape(`${path}.mikan-stage`);\n const stageB64 = shellEscape(`${path}.mikan-stage.b64`);\n\n const run = async (command: string) => {\n const result = await executor.exec(command, options);\n if (result.code !== 0) {\n await executor.exec(`rm -f ${stage} ${stageB64}`, options).catch(() => {});\n throw new Error(result.stderr.trim() || `Failed to write file: ${path}`);\n }\n };\n\n const dir = path.includes(\"/\") ? path.slice(0, path.lastIndexOf(\"/\")) || \"/\" : \".\";\n await run(`mkdir -p ${shellEscape(dir)} && : > ${stageB64}`);\n for (let offset = 0; offset === 0 || offset < encoded.length; offset += WRITE_CHUNK_CHARS) {\n const chunk = encoded.slice(offset, offset + WRITE_CHUNK_CHARS);\n await run(`printf '%s' ${shellEscape(chunk)} >> ${stageB64}`);\n }\n await run(\n `base64 -d < ${stageB64} > ${stage} && mv ${stage} ${escapedPath} && rm -f ${stageB64}`,\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-memory-file-manager.d.ts","sourceRoot":"","sources":["../../src/sessions/agent-memory-file-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-memory-file-manager.d.ts","sourceRoot":"","sources":["../../src/sessions/agent-memory-file-manager.ts"],"names":[],"mappings":"AASA,OAAO,EAUL,KAAK,oBAAoB,EAE1B,MAAM,YAAY,CAAC;AAepB,YAAY,EACV,6BAA6B,EAC7B,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,iCAAiC,EACjC,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,6BAA6B,EAC7B,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,iCAAiC,EACjC,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AAEpB,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,CAQ1F;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,MAAM,GAAG,IAAI,CAQ1F;AAED,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IAEjC,YAAY,OAAO,GAAE,6BAAkC,EAItD;IAEK,mBAAmB,CACvB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,oBAAoB,CAAC,CAsB/B;IAED,kBAAkB,CAAC,OAAO,EAAE,iCAAiC,GAAG,IAAI,CAUnE;IAED,YAAY,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAUrD;IAED,OAAO,CAAC,0BAA0B;IA2ClC,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,yBAAyB;CA4ClC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { join } from "path";
|
|
2
2
|
import { isRecord, parseJsonValue, readTextFileIfExists } from "../utils/file-guards.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { isCommandText } from "../commands/text.js";
|
|
4
|
+
import { formatHistoryLine, stripHistoryLinePrefix } from "./history-line.js";
|
|
5
5
|
import * as log from "../log.js";
|
|
6
6
|
import { isPlatformHistorySession } from "./metadata.js";
|
|
7
|
+
import { isThreadSessionKey } from "./session-key.js";
|
|
7
8
|
import { createManagedSessionFile, createManagedSessionFileAtPath, extractSessionSuffix, getChannelSessionDir, getThreadSessionFile, openManagedSession, resolveChannelSessionFile, tryResolveCurrentSession, tryResolveThreadSession, } from "./store.js";
|
|
8
9
|
const DEFAULT_RECENT_DAYS = 14;
|
|
9
10
|
const DEFAULT_MAX_TOP_LEVEL_MESSAGES = 200;
|
|
@@ -11,14 +12,14 @@ const CHAT_SYNC_CUSTOM_TYPE = "mikan.chat_sync";
|
|
|
11
12
|
const BIWEEKLY_ROTATION_ANCHOR = new Date(2026, 0, 4); // Sunday
|
|
12
13
|
const BIWEEKLY_MS = 14 * 24 * 60 * 60 * 1000;
|
|
13
14
|
export function hasMaterializedChatSession(options) {
|
|
14
|
-
if (!options.sessionKey
|
|
15
|
+
if (!isThreadSessionKey(options.sessionKey)) {
|
|
15
16
|
return resolveChannelSessionFile(options.conversationDir) !== null;
|
|
16
17
|
}
|
|
17
18
|
return (tryResolveThreadSession(getThreadSessionFile(options.conversationDir, options.sessionKey)) !==
|
|
18
19
|
null);
|
|
19
20
|
}
|
|
20
21
|
export function registerThreadSession(options) {
|
|
21
|
-
if (!options.sessionKey
|
|
22
|
+
if (!isThreadSessionKey(options.sessionKey))
|
|
22
23
|
return null;
|
|
23
24
|
const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);
|
|
24
25
|
return (tryResolveThreadSession(threadFile) ??
|
|
@@ -26,7 +27,7 @@ export function registerThreadSession(options) {
|
|
|
26
27
|
}
|
|
27
28
|
export async function waitForThreadSessionBootstrap(options) {
|
|
28
29
|
const { parentSessionKey, sessionKey, hasThreadSession, isParentRunning, sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), pollMs = 100, } = options;
|
|
29
|
-
if (!sessionKey
|
|
30
|
+
if (!isThreadSessionKey(sessionKey))
|
|
30
31
|
return false;
|
|
31
32
|
if (sessionKey === parentSessionKey)
|
|
32
33
|
return false;
|
|
@@ -48,7 +49,7 @@ export class AgentMemoryFileManager {
|
|
|
48
49
|
async resolveSessionScope(options) {
|
|
49
50
|
const cwd = options.cwd ?? options.conversationDir;
|
|
50
51
|
const sessionDir = getChannelSessionDir(options.conversationDir);
|
|
51
|
-
if (!options.sessionKey
|
|
52
|
+
if (!isThreadSessionKey(options.sessionKey)) {
|
|
52
53
|
const contextFile = this.resolveTopLevelSessionFile({
|
|
53
54
|
conversationDir: options.conversationDir,
|
|
54
55
|
sessionDir,
|
|
@@ -69,13 +70,13 @@ export class AgentMemoryFileManager {
|
|
|
69
70
|
syncSessionManager(options) {
|
|
70
71
|
const records = readConversationLog(options.conversationDir);
|
|
71
72
|
syncSessionManagerFromLog(options.sessionManager, selectExistingSessionSyncMessages(records, {
|
|
72
|
-
sessionKey: options.sessionKey
|
|
73
|
+
sessionKey: isThreadSessionKey(options.sessionKey) ? options.sessionKey : null,
|
|
73
74
|
excludeMessageId: options.currentMessageId,
|
|
74
75
|
}), this.historyWindow());
|
|
75
76
|
}
|
|
76
77
|
resetSession(options) {
|
|
77
78
|
const cwd = options.cwd ?? options.conversationDir;
|
|
78
|
-
if (options.sessionKey
|
|
79
|
+
if (isThreadSessionKey(options.sessionKey)) {
|
|
79
80
|
return createManagedSessionFileAtPath(getThreadSessionFile(options.conversationDir, options.sessionKey), cwd);
|
|
80
81
|
}
|
|
81
82
|
return createManagedSessionFile(getChannelSessionDir(options.conversationDir), cwd);
|
|
@@ -266,9 +267,7 @@ function isRenderableConversationMessage(message, excludeMessageId) {
|
|
|
266
267
|
return !!message.text?.trim();
|
|
267
268
|
}
|
|
268
269
|
function isChatCommandMessage(message) {
|
|
269
|
-
|
|
270
|
-
return (!message.isMessagingBot &&
|
|
271
|
-
/^\/(?:pi-[\w-]+|login|session|new|stop|model|sandbox|admin|auto-reply)(?:@\w+)?(?:\s|$)/i.test(text));
|
|
270
|
+
return !message.isMessagingBot && isCommandText(message.text ?? "");
|
|
272
271
|
}
|
|
273
272
|
function dedupeAndSortRecords(records) {
|
|
274
273
|
const byKey = new Map();
|
|
@@ -306,7 +305,6 @@ function bootstrapSessionFromLog(sessionFile, cwd, records, lastMessageId = reco
|
|
|
306
305
|
messageCount: records.length,
|
|
307
306
|
lastMessageId,
|
|
308
307
|
});
|
|
309
|
-
forceRewriteSession(sessionManager, sessionFile);
|
|
310
308
|
}
|
|
311
309
|
function syncSessionFromLog(sessionFile, cwd, records, historyWindow) {
|
|
312
310
|
if (records.length === 0)
|
|
@@ -344,15 +342,6 @@ function appendLogRecordsToSession(sessionManager, records) {
|
|
|
344
342
|
sessionManager.appendMessage(message);
|
|
345
343
|
}
|
|
346
344
|
}
|
|
347
|
-
function forceRewriteSession(sessionManager, sessionFile) {
|
|
348
|
-
const header = sessionManager.getHeader();
|
|
349
|
-
if (!header)
|
|
350
|
-
return;
|
|
351
|
-
const content = [header, ...sessionManager.getEntries()]
|
|
352
|
-
.map((entry) => JSON.stringify(entry))
|
|
353
|
-
.join("\n");
|
|
354
|
-
atomicWritePrivateFile(sessionFile, `${content}\n`);
|
|
355
|
-
}
|
|
356
345
|
function getLatestChatSyncMessageId(entries) {
|
|
357
346
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
358
347
|
const entry = entries[i];
|
|
@@ -413,11 +402,7 @@ function getSessionMessageText(entry) {
|
|
|
413
402
|
.map((part) => (part.type === "text" && "text" in part ? part.text : ""))
|
|
414
403
|
.join("\n");
|
|
415
404
|
}
|
|
416
|
-
|
|
417
|
-
return text
|
|
418
|
-
.replace(/^\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:[0-9]{2}\]\s+\[[^\]]+\](?:\s+\[in-thread:[^\]]+\])?:\s*/, "")
|
|
419
|
-
.trim();
|
|
420
|
-
}
|
|
405
|
+
const normalizeComparableText = stripHistoryLinePrefix;
|
|
421
406
|
function buildHistorySessionMessage(message) {
|
|
422
407
|
const text = message.text?.trim();
|
|
423
408
|
if (!text)
|
|
@@ -466,10 +451,11 @@ function parseMessageTimestamp(message) {
|
|
|
466
451
|
return undefined;
|
|
467
452
|
}
|
|
468
453
|
function formatHistoryMessage(message) {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
454
|
+
return formatHistoryLine({
|
|
455
|
+
date: message.date ? new Date(message.date) : undefined,
|
|
456
|
+
userName: message.userName || message.user,
|
|
457
|
+
text: message.text?.trim() ?? "",
|
|
458
|
+
});
|
|
473
459
|
}
|
|
474
460
|
function zeroUsage() {
|
|
475
461
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-memory-file-manager.js","sourceRoot":"","sources":["../../src/sessions/agent-memory-file-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry, SessionStore } from \"../harness/index.js\";\nimport { join } from \"path\";\nimport type { ConversationLogMessage } from \"../types.js\";\nimport { isRecord, parseJsonValue, readTextFileIfExists } from \"../utils/file-guards.js\";\nimport { formatLocalTimestamp } from \"../utils/date.js\";\nimport { atomicWritePrivateFile } from \"../utils/fs-atomic.js\";\nimport * as log from \"../log.js\";\nimport { isPlatformHistorySession } from \"./metadata.js\";\nimport {\n createManagedSessionFile,\n createManagedSessionFileAtPath,\n extractSessionSuffix,\n getChannelSessionDir,\n getThreadSessionFile,\n openManagedSession,\n resolveChannelSessionFile,\n tryResolveCurrentSession,\n tryResolveThreadSession,\n type ResolvedSessionScope,\n type ThreadRootMessage,\n} from \"./store.js\";\n\nconst DEFAULT_RECENT_DAYS = 14;\nconst DEFAULT_MAX_TOP_LEVEL_MESSAGES = 200;\nconst CHAT_SYNC_CUSTOM_TYPE = \"mikan.chat_sync\";\nconst BIWEEKLY_ROTATION_ANCHOR = new Date(2026, 0, 4); // Sunday\nconst BIWEEKLY_MS = 14 * 24 * 60 * 60 * 1000;\n\ntype SessionAppendMessage = Parameters<SessionStore[\"appendMessage\"]>[0];\n\ninterface LogRecord {\n message: ConversationLogMessage;\n index: number;\n}\n\nexport type {\n AgentMemoryFileManagerOptions,\n HasMaterializedSessionOptions,\n RegisterThreadSessionOptions,\n ResetChatSessionOptions,\n ResolveChatSessionScopeOptions,\n SyncAgentMemoryFileManagerOptions,\n ThreadBootstrapWaitOptions,\n} from \"./types.js\";\nimport type {\n AgentMemoryFileManagerOptions,\n HasMaterializedSessionOptions,\n RegisterThreadSessionOptions,\n ResetChatSessionOptions,\n ResolveChatSessionScopeOptions,\n SyncAgentMemoryFileManagerOptions,\n ThreadBootstrapWaitOptions,\n} from \"./types.js\";\n\nexport function hasMaterializedChatSession(options: HasMaterializedSessionOptions): boolean {\n if (!options.sessionKey.includes(\":\")) {\n return resolveChannelSessionFile(options.conversationDir) !== null;\n }\n return (\n tryResolveThreadSession(getThreadSessionFile(options.conversationDir, options.sessionKey)) !==\n null\n );\n}\n\nexport function registerThreadSession(options: RegisterThreadSessionOptions): string | null {\n if (!options.sessionKey.includes(\":\")) return null;\n\n const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);\n return (\n tryResolveThreadSession(threadFile) ??\n createManagedSessionFileAtPath(threadFile, options.cwd ?? options.conversationDir)\n );\n}\n\nexport async function waitForThreadSessionBootstrap(\n options: ThreadBootstrapWaitOptions,\n): Promise<boolean> {\n const {\n parentSessionKey,\n sessionKey,\n hasThreadSession,\n isParentRunning,\n sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)),\n pollMs = 100,\n } = options;\n\n if (!sessionKey.includes(\":\")) return false;\n if (sessionKey === parentSessionKey) return false;\n if (hasThreadSession()) return false;\n\n let waited = false;\n while (isParentRunning() && !hasThreadSession()) {\n waited = true;\n await sleep(pollMs);\n }\n\n return waited;\n}\n\nexport class AgentMemoryFileManager {\n private readonly recentDays: number;\n private readonly maxTopLevelMessages: number;\n private readonly now: () => Date;\n\n constructor(options: AgentMemoryFileManagerOptions = {}) {\n this.recentDays = options.recentDays ?? DEFAULT_RECENT_DAYS;\n this.maxTopLevelMessages = options.maxTopLevelMessages ?? DEFAULT_MAX_TOP_LEVEL_MESSAGES;\n this.now = options.now ?? (() => new Date());\n }\n\n async resolveSessionScope(\n options: ResolveChatSessionScopeOptions,\n ): Promise<ResolvedSessionScope> {\n const cwd = options.cwd ?? options.conversationDir;\n const sessionDir = getChannelSessionDir(options.conversationDir);\n\n if (!options.sessionKey.includes(\":\")) {\n const contextFile = this.resolveTopLevelSessionFile({\n conversationDir: options.conversationDir,\n sessionDir,\n cwd,\n currentMessageId: options.currentMessageId,\n rotateTopLevelSession: options.rotateTopLevelSession === true,\n });\n return { sessionDir, contextFile, threadRootMessage: null };\n }\n\n return this.resolveThreadSessionScope({\n conversationDir: options.conversationDir,\n sessionDir,\n sessionKey: options.sessionKey,\n cwd,\n currentMessageId: options.currentMessageId,\n });\n }\n\n syncSessionManager(options: SyncAgentMemoryFileManagerOptions): void {\n const records = readConversationLog(options.conversationDir);\n syncSessionManagerFromLog(\n options.sessionManager,\n selectExistingSessionSyncMessages(records, {\n sessionKey: options.sessionKey.includes(\":\") ? options.sessionKey : null,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n }\n\n resetSession(options: ResetChatSessionOptions): string {\n const cwd = options.cwd ?? options.conversationDir;\n if (options.sessionKey.includes(\":\")) {\n return createManagedSessionFileAtPath(\n getThreadSessionFile(options.conversationDir, options.sessionKey),\n cwd,\n );\n }\n\n return createManagedSessionFile(getChannelSessionDir(options.conversationDir), cwd);\n }\n\n private resolveTopLevelSessionFile(options: {\n conversationDir: string;\n sessionDir: string;\n cwd: string;\n currentMessageId?: string;\n rotateTopLevelSession: boolean;\n }): string {\n const records = readConversationLog(options.conversationDir);\n const existing = tryResolveCurrentSession(options.sessionDir);\n if (existing && !isPlatformHistorySession(existing)) {\n if (!options.rotateTopLevelSession || !shouldRotateTopLevelSession(existing, this.now())) {\n syncSessionFromLog(\n existing,\n options.cwd,\n selectExistingSessionSyncMessages(records, {\n sessionKey: null,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n return existing;\n }\n }\n\n const sessionFile = createManagedSessionFile(options.sessionDir, options.cwd);\n const bootstrapRecords = selectRecentTopLevelMessages(records, {\n recentDays: this.recentDays,\n maxMessages: this.maxTopLevelMessages,\n now: this.now(),\n excludeMessageId: options.currentMessageId,\n });\n bootstrapSessionFromLog(\n sessionFile,\n options.cwd,\n bootstrapRecords,\n latestSyncMessageId(records, {\n sessionKey: null,\n excludeMessageId: options.currentMessageId,\n }),\n );\n return sessionFile;\n }\n\n private historyWindow(): HistoryWindow {\n return { recentDays: this.recentDays, maxMessages: this.maxTopLevelMessages, now: this.now() };\n }\n\n private resolveThreadSessionScope(options: {\n conversationDir: string;\n sessionDir: string;\n sessionKey: string;\n cwd: string;\n currentMessageId?: string;\n }): ResolvedSessionScope {\n const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);\n const threadId = extractSessionSuffix(options.sessionKey);\n const records = readConversationLog(options.conversationDir);\n const threadRootMessage = buildThreadRootSeed(findLogRecordById(records, threadId)?.message);\n const existing = tryResolveThreadSession(threadFile);\n if (existing) {\n syncSessionFromLog(\n existing,\n options.cwd,\n selectExistingSessionSyncMessages(records, {\n sessionKey: options.sessionKey,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n return { sessionDir: options.sessionDir, contextFile: existing, threadRootMessage };\n }\n\n createManagedSessionFileAtPath(threadFile, options.cwd);\n const bootstrapRecords = selectThreadBootstrapMessages(records, threadId, {\n recentDays: this.recentDays,\n maxTopLevelMessages: this.maxTopLevelMessages,\n now: this.now(),\n excludeMessageId: options.currentMessageId,\n });\n bootstrapSessionFromLog(\n threadFile,\n options.cwd,\n bootstrapRecords,\n latestSyncMessageId(records, {\n sessionKey: options.sessionKey,\n excludeMessageId: options.currentMessageId,\n }),\n );\n\n return { sessionDir: options.sessionDir, contextFile: threadFile, threadRootMessage };\n }\n}\n\nfunction shouldRotateTopLevelSession(sessionFile: string, now: Date): boolean {\n const timestamp = readSessionTimestamp(sessionFile);\n return timestamp !== null && biweeklyBucket(timestamp) !== biweeklyBucket(now);\n}\n\nfunction readSessionTimestamp(sessionFile: string): Date | null {\n const raw = readTextFileIfExists(sessionFile);\n if (raw === undefined) return null;\n const firstLine = raw.split(\"\\n\").find((line) => line.trim());\n if (!firstLine) return null;\n try {\n const header = parseJsonValue(\n firstLine,\n (value): value is { timestamp?: unknown } => isRecord(value),\n (detail) => (detail === \"unexpected JSON shape\" ? \"expected a JSON object\" : detail),\n );\n if (typeof header.timestamp !== \"string\") return null;\n const date = new Date(header.timestamp);\n return Number.isFinite(date.getTime()) ? date : null;\n } catch {\n return null;\n }\n}\n\nfunction biweeklyBucket(date: Date): number {\n const weekStart = sundayStart(date).getTime();\n const anchor = sundayStart(BIWEEKLY_ROTATION_ANCHOR).getTime();\n return Math.floor((weekStart - anchor) / BIWEEKLY_MS);\n}\n\nfunction sundayStart(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());\n}\n\nfunction readConversationLog(conversationDir: string): LogRecord[] {\n const logFile = join(conversationDir, \"log.jsonl\");\n const raw = readTextFileIfExists(logFile);\n if (raw === undefined) return [];\n\n const lines = raw.trim().split(\"\\n\").filter(Boolean);\n const records: LogRecord[] = [];\n for (let i = 0; i < lines.length; i++) {\n try {\n const message = parseJsonValue(\n lines[i],\n (value): value is ConversationLogMessage => isRecord(value),\n (detail) => (detail === \"unexpected JSON shape\" ? \"expected a JSON object\" : detail),\n );\n records.push({ message, index: i });\n } catch (err) {\n log.logWarning(\n `Skipping malformed log entry at ${logFile}:${i + 1}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return coalesceMessagingBotLogChunks(records);\n}\n\nfunction coalesceMessagingBotLogChunks(records: LogRecord[]): LogRecord[] {\n const coalesced: LogRecord[] = [];\n for (const record of records) {\n const previous = coalesced.at(-1);\n if (previous && canCoalesceMessagingBotLogChunk(previous.message, record.message)) {\n previous.message.text = `${previous.message.text ?? \"\"}${record.message.text ?? \"\"}`;\n continue;\n }\n coalesced.push({ ...record, message: { ...record.message } });\n }\n return coalesced;\n}\n\nfunction canCoalesceMessagingBotLogChunk(\n previous: ConversationLogMessage,\n current: ConversationLogMessage,\n): boolean {\n return (\n previous.isMessagingBot === true &&\n current.isMessagingBot === true &&\n !!previous.ts &&\n previous.ts === current.ts &&\n previous.threadTs === current.threadTs &&\n previous.user === current.user\n );\n}\n\nfunction findLogRecordById(records: LogRecord[], messageId: string): LogRecord | undefined {\n for (let i = records.length - 1; i >= 0; i--) {\n if (records[i].message.ts === messageId) return records[i];\n }\n return undefined;\n}\n\nfunction selectRecentTopLevelMessages(\n records: LogRecord[],\n options: {\n recentDays: number;\n maxMessages: number;\n now: Date;\n excludeMessageId?: string;\n },\n): LogRecord[] {\n return selectRecentMessages(\n records.filter((record) => isTopLevelHistoryMessage(record.message, options.excludeMessageId)),\n options,\n );\n}\n\nfunction selectRecentMessages(records: LogRecord[], options: HistoryWindow): LogRecord[] {\n const sinceMs = options.now.getTime() - options.recentDays * 24 * 60 * 60 * 1000;\n return records\n .filter((record) => isRecentHistoryMessage(record.message, sinceMs))\n .slice(-options.maxMessages);\n}\n\nfunction selectThreadBootstrapMessages(\n records: LogRecord[],\n threadId: string,\n options: {\n recentDays: number;\n maxTopLevelMessages: number;\n now: Date;\n excludeMessageId?: string;\n },\n): LogRecord[] {\n const rootRecord = findLogRecordById(records, threadId);\n const topLevelSource = rootRecord\n ? records.filter((record) => record.index <= rootRecord.index)\n : records;\n const topLevelRecords = selectRecentTopLevelMessages(topLevelSource, {\n recentDays: options.recentDays,\n maxMessages: options.maxTopLevelMessages,\n now: options.now,\n excludeMessageId: options.excludeMessageId,\n });\n const threadRecords = records.filter(\n (record) =>\n isRenderableConversationMessage(record.message, options.excludeMessageId) &&\n (record.message.ts === threadId || record.message.threadTs === threadId),\n );\n\n return dedupeAndSortRecords([...topLevelRecords, ...threadRecords]);\n}\n\nfunction isTopLevelHistoryMessage(\n message: ConversationLogMessage,\n excludeMessageId?: string,\n): boolean {\n if (!isRenderableConversationMessage(message, excludeMessageId)) return false;\n return !message.threadTs;\n}\n\nfunction isRecentHistoryMessage(message: ConversationLogMessage, sinceMs: number): boolean {\n if (!message.date) return true;\n const dateMs = new Date(message.date).getTime();\n return !Number.isFinite(dateMs) || dateMs >= sinceMs;\n}\n\nfunction selectExistingSessionSyncMessages(\n records: LogRecord[],\n options: { sessionKey: string | null; excludeMessageId?: string },\n): LogRecord[] {\n const threadId = options.sessionKey ? extractSessionSuffix(options.sessionKey) : null;\n return dedupeAndSortRecords(\n records.filter((record) => {\n if (!isRenderableConversationMessage(record.message, options.excludeMessageId)) return false;\n if (!threadId) return !record.message.threadTs;\n return record.message.ts === threadId || record.message.threadTs === threadId;\n }),\n );\n}\n\nfunction latestSyncMessageId(\n records: LogRecord[],\n options: { sessionKey: string | null; excludeMessageId?: string },\n): string | undefined {\n return selectExistingSessionSyncMessages(records, options).at(-1)?.message.ts;\n}\n\nfunction isRenderableConversationMessage(\n message: ConversationLogMessage,\n excludeMessageId?: string,\n): boolean {\n if (excludeMessageId && message.ts === excludeMessageId) return false;\n if (isChatCommandMessage(message)) return false;\n return !!message.text?.trim();\n}\n\nfunction isChatCommandMessage(message: ConversationLogMessage): boolean {\n const text = message.text?.trim() ?? \"\";\n return (\n !message.isMessagingBot &&\n /^\\/(?:pi-[\\w-]+|login|session|new|stop|model|sandbox|admin|auto-reply)(?:@\\w+)?(?:\\s|$)/i.test(\n text,\n )\n );\n}\n\nfunction dedupeAndSortRecords(records: LogRecord[]): LogRecord[] {\n const byKey = new Map<string, LogRecord>();\n for (const record of records) {\n byKey.set(record.message.ts ?? `line:${record.index}`, record);\n }\n\n return Array.from(byKey.values()).toSorted((a, b) => {\n const aTime = sortTime(a);\n const bTime = sortTime(b);\n if (aTime !== bTime) return aTime - bTime;\n return a.index - b.index;\n });\n}\n\nfunction sortTime(record: LogRecord): number {\n if (record.message.date) {\n const dateMs = new Date(record.message.date).getTime();\n if (Number.isFinite(dateMs)) return dateMs;\n }\n\n if (record.message.ts) {\n const tsMs = Number(record.message.ts) * 1000;\n if (Number.isFinite(tsMs)) return tsMs;\n }\n\n return record.index;\n}\n\nfunction bootstrapSessionFromLog(\n sessionFile: string,\n cwd: string,\n records: LogRecord[],\n lastMessageId = records.at(-1)?.message.ts,\n): void {\n if (records.length === 0 && !lastMessageId) return;\n\n const sessionManager = openManagedSession(sessionFile, cwd);\n appendLogRecordsToSession(sessionManager, records);\n sessionManager.appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {\n source: \"log.jsonl\",\n messageCount: records.length,\n lastMessageId,\n });\n forceRewriteSession(sessionManager, sessionFile);\n}\n\ninterface HistoryWindow {\n recentDays: number;\n maxMessages: number;\n now: Date;\n}\n\nfunction syncSessionFromLog(\n sessionFile: string,\n cwd: string,\n records: LogRecord[],\n historyWindow: HistoryWindow,\n): void {\n if (records.length === 0) return;\n syncSessionManagerFromLog(openManagedSession(sessionFile, cwd), records, historyWindow);\n}\n\nfunction syncSessionManagerFromLog(\n sessionManager: SessionStore,\n records: LogRecord[],\n historyWindow: HistoryWindow,\n): void {\n if (records.length === 0) return;\n\n const existingEntries = sessionManager.getEntries();\n const lastSyncedMessageId = getLatestChatSyncMessageId(existingEntries);\n const lastSyncedIndex = lastSyncedMessageId\n ? records.findIndex((record) => record.message.ts === lastSyncedMessageId)\n : -1;\n if (lastSyncedMessageId && lastSyncedIndex === -1) return;\n\n const syncCandidates = selectRecentMessages(records.slice(lastSyncedIndex + 1), historyWindow);\n if (syncCandidates.length === 0) return;\n\n const represented = buildRepresentedMessageCounts(existingEntries);\n const newRecords = syncCandidates.filter(\n (record) => !consumeRepresentedLogMessage(record, represented),\n );\n if (newRecords.length === 0) return;\n\n appendLogRecordsToSession(sessionManager, newRecords);\n sessionManager.appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {\n source: \"log.jsonl\",\n messageCount: newRecords.length,\n lastMessageId: syncCandidates.at(-1)?.message.ts,\n });\n}\n\nfunction appendLogRecordsToSession(sessionManager: SessionStore, records: LogRecord[]): void {\n for (const record of records) {\n const message = buildHistorySessionMessage(record.message);\n if (message) sessionManager.appendMessage(message);\n }\n}\n\nfunction forceRewriteSession(sessionManager: SessionStore, sessionFile: string): void {\n const header = sessionManager.getHeader();\n if (!header) return;\n\n const content = [header, ...sessionManager.getEntries()]\n .map((entry) => JSON.stringify(entry))\n .join(\"\\n\");\n atomicWritePrivateFile(sessionFile, `${content}\\n`);\n}\n\nfunction getLatestChatSyncMessageId(entries: SessionEntry[]): string | undefined {\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n if (entry.type !== \"custom\" || entry.customType !== CHAT_SYNC_CUSTOM_TYPE) continue;\n if (!isRecord(entry.data)) return undefined;\n return typeof entry.data.lastMessageId === \"string\" ? entry.data.lastMessageId : undefined;\n }\n return undefined;\n}\n\nfunction buildRepresentedMessageCounts(entries: SessionEntry[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const entry of entries) {\n const comparable = comparableSessionMessage(entry);\n if (!comparable) continue;\n counts.set(comparable, (counts.get(comparable) ?? 0) + 1);\n }\n return counts;\n}\n\nfunction consumeRepresentedLogMessage(record: LogRecord, counts: Map<string, number>): boolean {\n const comparable = comparableLogMessage(record.message);\n if (!comparable) return false;\n\n const count = counts.get(comparable) ?? 0;\n if (count <= 0) return false;\n counts.set(comparable, count - 1);\n return true;\n}\n\nfunction comparableSessionMessage(entry: SessionEntry): string | null {\n if (entry.type !== \"message\") return null;\n const role = entry.message.role;\n if (role !== \"user\" && role !== \"assistant\") return null;\n\n const text = normalizeComparableText(getSessionMessageText(entry));\n if (!text) return null;\n return `${role}:${text}`;\n}\n\nfunction comparableLogMessage(message: ConversationLogMessage): string | null {\n const text = message.text?.trim();\n if (!text) return null;\n return `${message.isMessagingBot ? \"assistant\" : \"user\"}:${normalizeComparableText(text)}`;\n}\n\nfunction getSessionMessageText(entry: SessionEntry): string {\n if (entry.type !== \"message\" || !(\"content\" in entry.message)) return \"\";\n const content = entry.message.content;\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n return content\n .map((part) => (part.type === \"text\" && \"text\" in part ? part.text : \"\"))\n .join(\"\\n\");\n}\n\nfunction normalizeComparableText(text: string): string {\n return text\n .replace(\n /^\\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:[0-9]{2}\\]\\s+\\[[^\\]]+\\](?:\\s+\\[in-thread:[^\\]]+\\])?:\\s*/,\n \"\",\n )\n .trim();\n}\n\nfunction buildHistorySessionMessage(message: ConversationLogMessage): SessionAppendMessage | null {\n const text = message.text?.trim();\n if (!text) return null;\n\n const timestamp = parseMessageTimestamp(message);\n if (!message.isMessagingBot) {\n return {\n role: \"user\",\n content: [{ type: \"text\", text: formatHistoryMessage(message) }],\n ...(timestamp !== undefined ? { timestamp } : {}),\n } as SessionAppendMessage;\n }\n\n return {\n role: \"assistant\",\n content: [{ type: \"text\", text }],\n api: \"platform-history\",\n provider: \"platform-history\",\n model: \"platform-history\",\n usage: zeroUsage(),\n stopReason: \"stop\",\n ...(timestamp !== undefined ? { timestamp } : {}),\n } as SessionAppendMessage;\n}\n\nfunction buildThreadRootSeed(\n message: ConversationLogMessage | undefined,\n): ThreadRootMessage | null {\n if (!message) return null;\n return {\n text: message.text,\n userName: message.userName,\n user: message.user,\n loggedAt: message.date ? new Date(message.date).getTime() : undefined,\n isMessagingBot: message.isMessagingBot,\n };\n}\n\nfunction parseMessageTimestamp(message: ConversationLogMessage): number | undefined {\n if (message.date) {\n const dateMs = new Date(message.date).getTime();\n if (Number.isFinite(dateMs)) return dateMs;\n }\n\n if (message.ts) {\n const tsMs = Number(message.ts) * 1000;\n if (Number.isFinite(tsMs)) return tsMs;\n }\n\n return undefined;\n}\n\nfunction formatHistoryMessage(message: ConversationLogMessage): string {\n const text = message.text?.trim() ?? \"\";\n const userLabel = message.userName || message.user || \"unknown\";\n const timestamp = message.date ? formatLocalTimestamp(new Date(message.date)) : null;\n return timestamp ? `[${timestamp}] [${userLabel}]: ${text}` : `[${userLabel}]: ${text}`;\n}\n\nfunction zeroUsage(): object {\n return {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-memory-file-manager.js","sourceRoot":"","sources":["../../src/sessions/agent-memory-file-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry, SessionStore } from \"../harness/index.js\";\nimport { join } from \"path\";\nimport type { ConversationLogMessage } from \"../types.js\";\nimport { isRecord, parseJsonValue, readTextFileIfExists } from \"../utils/file-guards.js\";\nimport { isCommandText } from \"../commands/text.js\";\nimport { formatHistoryLine, stripHistoryLinePrefix } from \"./history-line.js\";\nimport * as log from \"../log.js\";\nimport { isPlatformHistorySession } from \"./metadata.js\";\nimport { isThreadSessionKey } from \"./session-key.js\";\nimport {\n createManagedSessionFile,\n createManagedSessionFileAtPath,\n extractSessionSuffix,\n getChannelSessionDir,\n getThreadSessionFile,\n openManagedSession,\n resolveChannelSessionFile,\n tryResolveCurrentSession,\n tryResolveThreadSession,\n type ResolvedSessionScope,\n type ThreadRootMessage,\n} from \"./store.js\";\n\nconst DEFAULT_RECENT_DAYS = 14;\nconst DEFAULT_MAX_TOP_LEVEL_MESSAGES = 200;\nconst CHAT_SYNC_CUSTOM_TYPE = \"mikan.chat_sync\";\nconst BIWEEKLY_ROTATION_ANCHOR = new Date(2026, 0, 4); // Sunday\nconst BIWEEKLY_MS = 14 * 24 * 60 * 60 * 1000;\n\ntype SessionAppendMessage = Parameters<SessionStore[\"appendMessage\"]>[0];\n\ninterface LogRecord {\n message: ConversationLogMessage;\n index: number;\n}\n\nexport type {\n AgentMemoryFileManagerOptions,\n HasMaterializedSessionOptions,\n RegisterThreadSessionOptions,\n ResetChatSessionOptions,\n ResolveChatSessionScopeOptions,\n SyncAgentMemoryFileManagerOptions,\n ThreadBootstrapWaitOptions,\n} from \"./types.js\";\nimport type {\n AgentMemoryFileManagerOptions,\n HasMaterializedSessionOptions,\n RegisterThreadSessionOptions,\n ResetChatSessionOptions,\n ResolveChatSessionScopeOptions,\n SyncAgentMemoryFileManagerOptions,\n ThreadBootstrapWaitOptions,\n} from \"./types.js\";\n\nexport function hasMaterializedChatSession(options: HasMaterializedSessionOptions): boolean {\n if (!isThreadSessionKey(options.sessionKey)) {\n return resolveChannelSessionFile(options.conversationDir) !== null;\n }\n return (\n tryResolveThreadSession(getThreadSessionFile(options.conversationDir, options.sessionKey)) !==\n null\n );\n}\n\nexport function registerThreadSession(options: RegisterThreadSessionOptions): string | null {\n if (!isThreadSessionKey(options.sessionKey)) return null;\n\n const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);\n return (\n tryResolveThreadSession(threadFile) ??\n createManagedSessionFileAtPath(threadFile, options.cwd ?? options.conversationDir)\n );\n}\n\nexport async function waitForThreadSessionBootstrap(\n options: ThreadBootstrapWaitOptions,\n): Promise<boolean> {\n const {\n parentSessionKey,\n sessionKey,\n hasThreadSession,\n isParentRunning,\n sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)),\n pollMs = 100,\n } = options;\n\n if (!isThreadSessionKey(sessionKey)) return false;\n if (sessionKey === parentSessionKey) return false;\n if (hasThreadSession()) return false;\n\n let waited = false;\n while (isParentRunning() && !hasThreadSession()) {\n waited = true;\n await sleep(pollMs);\n }\n\n return waited;\n}\n\nexport class AgentMemoryFileManager {\n private readonly recentDays: number;\n private readonly maxTopLevelMessages: number;\n private readonly now: () => Date;\n\n constructor(options: AgentMemoryFileManagerOptions = {}) {\n this.recentDays = options.recentDays ?? DEFAULT_RECENT_DAYS;\n this.maxTopLevelMessages = options.maxTopLevelMessages ?? DEFAULT_MAX_TOP_LEVEL_MESSAGES;\n this.now = options.now ?? (() => new Date());\n }\n\n async resolveSessionScope(\n options: ResolveChatSessionScopeOptions,\n ): Promise<ResolvedSessionScope> {\n const cwd = options.cwd ?? options.conversationDir;\n const sessionDir = getChannelSessionDir(options.conversationDir);\n\n if (!isThreadSessionKey(options.sessionKey)) {\n const contextFile = this.resolveTopLevelSessionFile({\n conversationDir: options.conversationDir,\n sessionDir,\n cwd,\n currentMessageId: options.currentMessageId,\n rotateTopLevelSession: options.rotateTopLevelSession === true,\n });\n return { sessionDir, contextFile, threadRootMessage: null };\n }\n\n return this.resolveThreadSessionScope({\n conversationDir: options.conversationDir,\n sessionDir,\n sessionKey: options.sessionKey,\n cwd,\n currentMessageId: options.currentMessageId,\n });\n }\n\n syncSessionManager(options: SyncAgentMemoryFileManagerOptions): void {\n const records = readConversationLog(options.conversationDir);\n syncSessionManagerFromLog(\n options.sessionManager,\n selectExistingSessionSyncMessages(records, {\n sessionKey: isThreadSessionKey(options.sessionKey) ? options.sessionKey : null,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n }\n\n resetSession(options: ResetChatSessionOptions): string {\n const cwd = options.cwd ?? options.conversationDir;\n if (isThreadSessionKey(options.sessionKey)) {\n return createManagedSessionFileAtPath(\n getThreadSessionFile(options.conversationDir, options.sessionKey),\n cwd,\n );\n }\n\n return createManagedSessionFile(getChannelSessionDir(options.conversationDir), cwd);\n }\n\n private resolveTopLevelSessionFile(options: {\n conversationDir: string;\n sessionDir: string;\n cwd: string;\n currentMessageId?: string;\n rotateTopLevelSession: boolean;\n }): string {\n const records = readConversationLog(options.conversationDir);\n const existing = tryResolveCurrentSession(options.sessionDir);\n if (existing && !isPlatformHistorySession(existing)) {\n if (!options.rotateTopLevelSession || !shouldRotateTopLevelSession(existing, this.now())) {\n syncSessionFromLog(\n existing,\n options.cwd,\n selectExistingSessionSyncMessages(records, {\n sessionKey: null,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n return existing;\n }\n }\n\n const sessionFile = createManagedSessionFile(options.sessionDir, options.cwd);\n const bootstrapRecords = selectRecentTopLevelMessages(records, {\n recentDays: this.recentDays,\n maxMessages: this.maxTopLevelMessages,\n now: this.now(),\n excludeMessageId: options.currentMessageId,\n });\n bootstrapSessionFromLog(\n sessionFile,\n options.cwd,\n bootstrapRecords,\n latestSyncMessageId(records, {\n sessionKey: null,\n excludeMessageId: options.currentMessageId,\n }),\n );\n return sessionFile;\n }\n\n private historyWindow(): HistoryWindow {\n return { recentDays: this.recentDays, maxMessages: this.maxTopLevelMessages, now: this.now() };\n }\n\n private resolveThreadSessionScope(options: {\n conversationDir: string;\n sessionDir: string;\n sessionKey: string;\n cwd: string;\n currentMessageId?: string;\n }): ResolvedSessionScope {\n const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);\n const threadId = extractSessionSuffix(options.sessionKey);\n const records = readConversationLog(options.conversationDir);\n const threadRootMessage = buildThreadRootSeed(findLogRecordById(records, threadId)?.message);\n const existing = tryResolveThreadSession(threadFile);\n if (existing) {\n syncSessionFromLog(\n existing,\n options.cwd,\n selectExistingSessionSyncMessages(records, {\n sessionKey: options.sessionKey,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n return { sessionDir: options.sessionDir, contextFile: existing, threadRootMessage };\n }\n\n createManagedSessionFileAtPath(threadFile, options.cwd);\n const bootstrapRecords = selectThreadBootstrapMessages(records, threadId, {\n recentDays: this.recentDays,\n maxTopLevelMessages: this.maxTopLevelMessages,\n now: this.now(),\n excludeMessageId: options.currentMessageId,\n });\n bootstrapSessionFromLog(\n threadFile,\n options.cwd,\n bootstrapRecords,\n latestSyncMessageId(records, {\n sessionKey: options.sessionKey,\n excludeMessageId: options.currentMessageId,\n }),\n );\n\n return { sessionDir: options.sessionDir, contextFile: threadFile, threadRootMessage };\n }\n}\n\nfunction shouldRotateTopLevelSession(sessionFile: string, now: Date): boolean {\n const timestamp = readSessionTimestamp(sessionFile);\n return timestamp !== null && biweeklyBucket(timestamp) !== biweeklyBucket(now);\n}\n\nfunction readSessionTimestamp(sessionFile: string): Date | null {\n const raw = readTextFileIfExists(sessionFile);\n if (raw === undefined) return null;\n const firstLine = raw.split(\"\\n\").find((line) => line.trim());\n if (!firstLine) return null;\n try {\n const header = parseJsonValue(\n firstLine,\n (value): value is { timestamp?: unknown } => isRecord(value),\n (detail) => (detail === \"unexpected JSON shape\" ? \"expected a JSON object\" : detail),\n );\n if (typeof header.timestamp !== \"string\") return null;\n const date = new Date(header.timestamp);\n return Number.isFinite(date.getTime()) ? date : null;\n } catch {\n return null;\n }\n}\n\nfunction biweeklyBucket(date: Date): number {\n const weekStart = sundayStart(date).getTime();\n const anchor = sundayStart(BIWEEKLY_ROTATION_ANCHOR).getTime();\n return Math.floor((weekStart - anchor) / BIWEEKLY_MS);\n}\n\nfunction sundayStart(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());\n}\n\nfunction readConversationLog(conversationDir: string): LogRecord[] {\n const logFile = join(conversationDir, \"log.jsonl\");\n const raw = readTextFileIfExists(logFile);\n if (raw === undefined) return [];\n\n const lines = raw.trim().split(\"\\n\").filter(Boolean);\n const records: LogRecord[] = [];\n for (let i = 0; i < lines.length; i++) {\n try {\n const message = parseJsonValue(\n lines[i],\n (value): value is ConversationLogMessage => isRecord(value),\n (detail) => (detail === \"unexpected JSON shape\" ? \"expected a JSON object\" : detail),\n );\n records.push({ message, index: i });\n } catch (err) {\n log.logWarning(\n `Skipping malformed log entry at ${logFile}:${i + 1}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return coalesceMessagingBotLogChunks(records);\n}\n\nfunction coalesceMessagingBotLogChunks(records: LogRecord[]): LogRecord[] {\n const coalesced: LogRecord[] = [];\n for (const record of records) {\n const previous = coalesced.at(-1);\n if (previous && canCoalesceMessagingBotLogChunk(previous.message, record.message)) {\n previous.message.text = `${previous.message.text ?? \"\"}${record.message.text ?? \"\"}`;\n continue;\n }\n coalesced.push({ ...record, message: { ...record.message } });\n }\n return coalesced;\n}\n\nfunction canCoalesceMessagingBotLogChunk(\n previous: ConversationLogMessage,\n current: ConversationLogMessage,\n): boolean {\n return (\n previous.isMessagingBot === true &&\n current.isMessagingBot === true &&\n !!previous.ts &&\n previous.ts === current.ts &&\n previous.threadTs === current.threadTs &&\n previous.user === current.user\n );\n}\n\nfunction findLogRecordById(records: LogRecord[], messageId: string): LogRecord | undefined {\n for (let i = records.length - 1; i >= 0; i--) {\n if (records[i].message.ts === messageId) return records[i];\n }\n return undefined;\n}\n\nfunction selectRecentTopLevelMessages(\n records: LogRecord[],\n options: {\n recentDays: number;\n maxMessages: number;\n now: Date;\n excludeMessageId?: string;\n },\n): LogRecord[] {\n return selectRecentMessages(\n records.filter((record) => isTopLevelHistoryMessage(record.message, options.excludeMessageId)),\n options,\n );\n}\n\nfunction selectRecentMessages(records: LogRecord[], options: HistoryWindow): LogRecord[] {\n const sinceMs = options.now.getTime() - options.recentDays * 24 * 60 * 60 * 1000;\n return records\n .filter((record) => isRecentHistoryMessage(record.message, sinceMs))\n .slice(-options.maxMessages);\n}\n\nfunction selectThreadBootstrapMessages(\n records: LogRecord[],\n threadId: string,\n options: {\n recentDays: number;\n maxTopLevelMessages: number;\n now: Date;\n excludeMessageId?: string;\n },\n): LogRecord[] {\n const rootRecord = findLogRecordById(records, threadId);\n const topLevelSource = rootRecord\n ? records.filter((record) => record.index <= rootRecord.index)\n : records;\n const topLevelRecords = selectRecentTopLevelMessages(topLevelSource, {\n recentDays: options.recentDays,\n maxMessages: options.maxTopLevelMessages,\n now: options.now,\n excludeMessageId: options.excludeMessageId,\n });\n const threadRecords = records.filter(\n (record) =>\n isRenderableConversationMessage(record.message, options.excludeMessageId) &&\n (record.message.ts === threadId || record.message.threadTs === threadId),\n );\n\n return dedupeAndSortRecords([...topLevelRecords, ...threadRecords]);\n}\n\nfunction isTopLevelHistoryMessage(\n message: ConversationLogMessage,\n excludeMessageId?: string,\n): boolean {\n if (!isRenderableConversationMessage(message, excludeMessageId)) return false;\n return !message.threadTs;\n}\n\nfunction isRecentHistoryMessage(message: ConversationLogMessage, sinceMs: number): boolean {\n if (!message.date) return true;\n const dateMs = new Date(message.date).getTime();\n return !Number.isFinite(dateMs) || dateMs >= sinceMs;\n}\n\nfunction selectExistingSessionSyncMessages(\n records: LogRecord[],\n options: { sessionKey: string | null; excludeMessageId?: string },\n): LogRecord[] {\n const threadId = options.sessionKey ? extractSessionSuffix(options.sessionKey) : null;\n return dedupeAndSortRecords(\n records.filter((record) => {\n if (!isRenderableConversationMessage(record.message, options.excludeMessageId)) return false;\n if (!threadId) return !record.message.threadTs;\n return record.message.ts === threadId || record.message.threadTs === threadId;\n }),\n );\n}\n\nfunction latestSyncMessageId(\n records: LogRecord[],\n options: { sessionKey: string | null; excludeMessageId?: string },\n): string | undefined {\n return selectExistingSessionSyncMessages(records, options).at(-1)?.message.ts;\n}\n\nfunction isRenderableConversationMessage(\n message: ConversationLogMessage,\n excludeMessageId?: string,\n): boolean {\n if (excludeMessageId && message.ts === excludeMessageId) return false;\n if (isChatCommandMessage(message)) return false;\n return !!message.text?.trim();\n}\n\nfunction isChatCommandMessage(message: ConversationLogMessage): boolean {\n return !message.isMessagingBot && isCommandText(message.text ?? \"\");\n}\n\nfunction dedupeAndSortRecords(records: LogRecord[]): LogRecord[] {\n const byKey = new Map<string, LogRecord>();\n for (const record of records) {\n byKey.set(record.message.ts ?? `line:${record.index}`, record);\n }\n\n return Array.from(byKey.values()).toSorted((a, b) => {\n const aTime = sortTime(a);\n const bTime = sortTime(b);\n if (aTime !== bTime) return aTime - bTime;\n return a.index - b.index;\n });\n}\n\nfunction sortTime(record: LogRecord): number {\n if (record.message.date) {\n const dateMs = new Date(record.message.date).getTime();\n if (Number.isFinite(dateMs)) return dateMs;\n }\n\n if (record.message.ts) {\n const tsMs = Number(record.message.ts) * 1000;\n if (Number.isFinite(tsMs)) return tsMs;\n }\n\n return record.index;\n}\n\nfunction bootstrapSessionFromLog(\n sessionFile: string,\n cwd: string,\n records: LogRecord[],\n lastMessageId = records.at(-1)?.message.ts,\n): void {\n if (records.length === 0 && !lastMessageId) return;\n\n const sessionManager = openManagedSession(sessionFile, cwd);\n appendLogRecordsToSession(sessionManager, records);\n sessionManager.appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {\n source: \"log.jsonl\",\n messageCount: records.length,\n lastMessageId,\n });\n}\n\ninterface HistoryWindow {\n recentDays: number;\n maxMessages: number;\n now: Date;\n}\n\nfunction syncSessionFromLog(\n sessionFile: string,\n cwd: string,\n records: LogRecord[],\n historyWindow: HistoryWindow,\n): void {\n if (records.length === 0) return;\n syncSessionManagerFromLog(openManagedSession(sessionFile, cwd), records, historyWindow);\n}\n\nfunction syncSessionManagerFromLog(\n sessionManager: SessionStore,\n records: LogRecord[],\n historyWindow: HistoryWindow,\n): void {\n if (records.length === 0) return;\n\n const existingEntries = sessionManager.getEntries();\n const lastSyncedMessageId = getLatestChatSyncMessageId(existingEntries);\n const lastSyncedIndex = lastSyncedMessageId\n ? records.findIndex((record) => record.message.ts === lastSyncedMessageId)\n : -1;\n if (lastSyncedMessageId && lastSyncedIndex === -1) return;\n\n const syncCandidates = selectRecentMessages(records.slice(lastSyncedIndex + 1), historyWindow);\n if (syncCandidates.length === 0) return;\n\n const represented = buildRepresentedMessageCounts(existingEntries);\n const newRecords = syncCandidates.filter(\n (record) => !consumeRepresentedLogMessage(record, represented),\n );\n if (newRecords.length === 0) return;\n\n appendLogRecordsToSession(sessionManager, newRecords);\n sessionManager.appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {\n source: \"log.jsonl\",\n messageCount: newRecords.length,\n lastMessageId: syncCandidates.at(-1)?.message.ts,\n });\n}\n\nfunction appendLogRecordsToSession(sessionManager: SessionStore, records: LogRecord[]): void {\n for (const record of records) {\n const message = buildHistorySessionMessage(record.message);\n if (message) sessionManager.appendMessage(message);\n }\n}\n\nfunction getLatestChatSyncMessageId(entries: SessionEntry[]): string | undefined {\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n if (entry.type !== \"custom\" || entry.customType !== CHAT_SYNC_CUSTOM_TYPE) continue;\n if (!isRecord(entry.data)) return undefined;\n return typeof entry.data.lastMessageId === \"string\" ? entry.data.lastMessageId : undefined;\n }\n return undefined;\n}\n\nfunction buildRepresentedMessageCounts(entries: SessionEntry[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const entry of entries) {\n const comparable = comparableSessionMessage(entry);\n if (!comparable) continue;\n counts.set(comparable, (counts.get(comparable) ?? 0) + 1);\n }\n return counts;\n}\n\nfunction consumeRepresentedLogMessage(record: LogRecord, counts: Map<string, number>): boolean {\n const comparable = comparableLogMessage(record.message);\n if (!comparable) return false;\n\n const count = counts.get(comparable) ?? 0;\n if (count <= 0) return false;\n counts.set(comparable, count - 1);\n return true;\n}\n\nfunction comparableSessionMessage(entry: SessionEntry): string | null {\n if (entry.type !== \"message\") return null;\n const role = entry.message.role;\n if (role !== \"user\" && role !== \"assistant\") return null;\n\n const text = normalizeComparableText(getSessionMessageText(entry));\n if (!text) return null;\n return `${role}:${text}`;\n}\n\nfunction comparableLogMessage(message: ConversationLogMessage): string | null {\n const text = message.text?.trim();\n if (!text) return null;\n return `${message.isMessagingBot ? \"assistant\" : \"user\"}:${normalizeComparableText(text)}`;\n}\n\nfunction getSessionMessageText(entry: SessionEntry): string {\n if (entry.type !== \"message\" || !(\"content\" in entry.message)) return \"\";\n const content = entry.message.content;\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n return content\n .map((part) => (part.type === \"text\" && \"text\" in part ? part.text : \"\"))\n .join(\"\\n\");\n}\n\nconst normalizeComparableText = stripHistoryLinePrefix;\n\nfunction buildHistorySessionMessage(message: ConversationLogMessage): SessionAppendMessage | null {\n const text = message.text?.trim();\n if (!text) return null;\n\n const timestamp = parseMessageTimestamp(message);\n if (!message.isMessagingBot) {\n return {\n role: \"user\",\n content: [{ type: \"text\", text: formatHistoryMessage(message) }],\n ...(timestamp !== undefined ? { timestamp } : {}),\n } as SessionAppendMessage;\n }\n\n return {\n role: \"assistant\",\n content: [{ type: \"text\", text }],\n api: \"platform-history\",\n provider: \"platform-history\",\n model: \"platform-history\",\n usage: zeroUsage(),\n stopReason: \"stop\",\n ...(timestamp !== undefined ? { timestamp } : {}),\n } as SessionAppendMessage;\n}\n\nfunction buildThreadRootSeed(\n message: ConversationLogMessage | undefined,\n): ThreadRootMessage | null {\n if (!message) return null;\n return {\n text: message.text,\n userName: message.userName,\n user: message.user,\n loggedAt: message.date ? new Date(message.date).getTime() : undefined,\n isMessagingBot: message.isMessagingBot,\n };\n}\n\nfunction parseMessageTimestamp(message: ConversationLogMessage): number | undefined {\n if (message.date) {\n const dateMs = new Date(message.date).getTime();\n if (Number.isFinite(dateMs)) return dateMs;\n }\n\n if (message.ts) {\n const tsMs = Number(message.ts) * 1000;\n if (Number.isFinite(tsMs)) return tsMs;\n }\n\n return undefined;\n}\n\nfunction formatHistoryMessage(message: ConversationLogMessage): string {\n return formatHistoryLine({\n date: message.date ? new Date(message.date) : undefined,\n userName: message.userName || message.user,\n text: message.text?.trim() ?? \"\",\n });\n}\n\nfunction zeroUsage(): object {\n return {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n };\n}\n"]}
|