@geminixiang/mikan 1.0.0-beta.3 → 1.0.0-beta.30
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 +563 -0
- package/README.md +60 -24
- 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 +47 -65
- 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 +46 -211
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +86 -0
- package/dist/adapters/github/bot.d.ts.map +1 -0
- package/dist/adapters/github/bot.js +640 -0
- package/dist/adapters/github/bot.js.map +1 -0
- package/dist/adapters/github/client.d.ts +122 -0
- package/dist/adapters/github/client.d.ts.map +1 -0
- package/dist/adapters/github/client.js +314 -0
- package/dist/adapters/github/client.js.map +1 -0
- package/dist/adapters/github/cloudbuild.d.ts +19 -0
- package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
- package/dist/adapters/github/cloudbuild.js +71 -0
- package/dist/adapters/github/cloudbuild.js.map +1 -0
- package/dist/adapters/github/context.d.ts +9 -0
- package/dist/adapters/github/context.d.ts.map +1 -0
- package/dist/adapters/github/context.js +98 -0
- package/dist/adapters/github/context.js.map +1 -0
- package/dist/adapters/github/gcp-auth.d.ts +28 -0
- package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
- package/dist/adapters/github/gcp-auth.js +196 -0
- package/dist/adapters/github/gcp-auth.js.map +1 -0
- package/dist/adapters/github/github-ops.d.ts +90 -0
- package/dist/adapters/github/github-ops.d.ts.map +1 -0
- package/dist/adapters/github/github-ops.js +405 -0
- package/dist/adapters/github/github-ops.js.map +1 -0
- package/dist/adapters/github/ids.d.ts +34 -0
- package/dist/adapters/github/ids.d.ts.map +1 -0
- package/dist/adapters/github/ids.js +53 -0
- package/dist/adapters/github/ids.js.map +1 -0
- package/dist/adapters/github/repo.d.ts +32 -0
- package/dist/adapters/github/repo.d.ts.map +1 -0
- package/dist/adapters/github/repo.js +141 -0
- package/dist/adapters/github/repo.js.map +1 -0
- package/dist/adapters/github/tool-pack.d.ts +14 -0
- package/dist/adapters/github/tool-pack.d.ts.map +1 -0
- package/dist/adapters/github/tool-pack.js +56 -0
- package/dist/adapters/github/tool-pack.js.map +1 -0
- package/dist/adapters/github/tools/checks.d.ts +19 -0
- package/dist/adapters/github/tools/checks.d.ts.map +1 -0
- package/dist/adapters/github/tools/checks.js +105 -0
- package/dist/adapters/github/tools/checks.js.map +1 -0
- package/dist/adapters/github/tools/issue.d.ts +21 -0
- package/dist/adapters/github/tools/issue.d.ts.map +1 -0
- package/dist/adapters/github/tools/issue.js +48 -0
- package/dist/adapters/github/tools/issue.js.map +1 -0
- package/dist/adapters/github/tools/pr.d.ts +22 -0
- package/dist/adapters/github/tools/pr.d.ts.map +1 -0
- package/dist/adapters/github/tools/pr.js +48 -0
- package/dist/adapters/github/tools/pr.js.map +1 -0
- package/dist/adapters/github/tools/read.d.ts +21 -0
- package/dist/adapters/github/tools/read.d.ts.map +1 -0
- package/dist/adapters/github/tools/read.js +141 -0
- package/dist/adapters/github/tools/read.js.map +1 -0
- package/dist/adapters/github/tools/review-reply.d.ts +17 -0
- package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
- package/dist/adapters/github/tools/review-reply.js +38 -0
- package/dist/adapters/github/tools/review-reply.js.map +1 -0
- package/dist/adapters/github/tools/sync.d.ts +17 -0
- package/dist/adapters/github/tools/sync.d.ts.map +1 -0
- package/dist/adapters/github/tools/sync.js +34 -0
- package/dist/adapters/github/tools/sync.js.map +1 -0
- package/dist/adapters/github/types.d.ts +372 -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 +84 -22
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/progressive-renderer.d.ts +7 -0
- package/dist/adapters/progressive-renderer.d.ts.map +1 -0
- package/dist/adapters/progressive-renderer.js +383 -0
- package/dist/adapters/progressive-renderer.js.map +1 -0
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +111 -111
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +10 -6
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +173 -145
- 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 +126 -323
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/session.d.ts.map +1 -1
- package/dist/adapters/slack/session.js +5 -8
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/slack/tool-pack.d.ts +11 -0
- package/dist/adapters/slack/tool-pack.d.ts.map +1 -0
- package/dist/adapters/slack/tool-pack.js +45 -0
- package/dist/adapters/slack/tool-pack.js.map +1 -0
- package/dist/adapters/slack/tools/blockkit.d.ts +14 -0
- package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -0
- package/dist/adapters/slack/tools/blockkit.js +106 -0
- package/dist/adapters/slack/tools/blockkit.js.map +1 -0
- package/dist/adapters/slack/types.d.ts +37 -0
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +1 -2
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +51 -63
- 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 +55 -182
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +86 -10
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent.d.ts +14 -19
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +745 -243
- package/dist/agent.js.map +1 -1
- package/dist/cli/arg-grammar.d.ts +25 -0
- package/dist/cli/arg-grammar.d.ts.map +1 -0
- package/dist/cli/arg-grammar.js +59 -0
- package/dist/cli/arg-grammar.js.map +1 -0
- package/dist/cli/boot.d.ts +5 -0
- package/dist/cli/boot.d.ts.map +1 -0
- package/dist/cli/boot.js +112 -0
- package/dist/cli/boot.js.map +1 -0
- package/dist/cli/download.d.ts.map +1 -0
- package/dist/cli/download.js.map +1 -0
- package/dist/cli/ext-dev.d.ts +2 -0
- package/dist/cli/ext-dev.d.ts.map +1 -0
- package/dist/cli/ext-dev.js +177 -0
- package/dist/cli/ext-dev.js.map +1 -0
- package/dist/cli/ext-git.d.ts +17 -0
- package/dist/cli/ext-git.d.ts.map +1 -0
- package/dist/cli/ext-git.js +107 -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 +222 -0
- package/dist/cli/ext.js.map +1 -0
- package/dist/cli/types.d.ts +20 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +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 +18 -8
- 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 +35 -3
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/manifest.d.ts +30 -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 +2 -3
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +57 -20
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +10 -2
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/registry.d.ts +2 -2
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +1 -2
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +23 -17
- 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 +70 -2
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +1 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +102 -95
- package/dist/config.js.map +1 -1
- package/dist/env-manifest.d.ts +28 -0
- package/dist/env-manifest.d.ts.map +1 -0
- package/dist/env-manifest.js +214 -0
- package/dist/env-manifest.js.map +1 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +9 -73
- package/dist/events.js.map +1 -1
- package/dist/execution-resolver.d.ts +7 -6
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +105 -110
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/auth.d.ts +2 -1
- package/dist/harness/auth.d.ts.map +1 -1
- package/dist/harness/auth.js +6 -0
- package/dist/harness/auth.js.map +1 -1
- package/dist/harness/event-format.d.ts +25 -0
- package/dist/harness/event-format.d.ts.map +1 -0
- package/dist/harness/event-format.js +159 -0
- package/dist/harness/event-format.js.map +1 -0
- package/dist/harness/extensions/blockkit.d.ts +19 -0
- package/dist/harness/extensions/blockkit.d.ts.map +1 -0
- package/dist/harness/extensions/blockkit.js +42 -0
- package/dist/harness/extensions/blockkit.js.map +1 -0
- package/dist/harness/extensions/loader.d.ts +25 -48
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +373 -113
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/extensions/registry.d.ts +75 -2
- package/dist/harness/extensions/registry.d.ts.map +1 -1
- package/dist/harness/extensions/registry.js +239 -0
- package/dist/harness/extensions/registry.js.map +1 -1
- package/dist/harness/extensions/types.d.ts +318 -25
- package/dist/harness/extensions/types.d.ts.map +1 -1
- package/dist/harness/extensions/types.js.map +1 -1
- package/dist/harness/index.d.ts +18 -8
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +7 -4
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/models.d.ts +7 -4
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +10 -0
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/runner.d.ts +50 -54
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +230 -44
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session-store.d.ts +9 -5
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +131 -30
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/settings.d.ts +2 -20
- package/dist/harness/settings.d.ts.map +1 -1
- package/dist/harness/settings.js +11 -0
- package/dist/harness/settings.js.map +1 -1
- package/dist/harness/skills.d.ts +2 -29
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/subagent-profiles.d.ts +8 -0
- package/dist/harness/subagent-profiles.d.ts.map +1 -0
- package/dist/harness/subagent-profiles.js +290 -0
- package/dist/harness/subagent-profiles.js.map +1 -0
- package/dist/harness/subagent-runner.d.ts +39 -0
- package/dist/harness/subagent-runner.d.ts.map +1 -0
- package/dist/harness/subagent-runner.js +615 -0
- package/dist/harness/subagent-runner.js.map +1 -0
- package/dist/harness/types.d.ts +263 -1
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage.d.ts +6 -0
- package/dist/harness/usage.d.ts.map +1 -0
- package/dist/harness/usage.js +32 -0
- package/dist/harness/usage.js.map +1 -0
- package/dist/index.d.ts +33 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -6
- package/dist/index.js.map +1 -1
- package/dist/main.js +253 -109
- package/dist/main.js.map +1 -1
- package/dist/observability/instrument.js +6 -4
- package/dist/observability/instrument.js.map +1 -1
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +3 -2
- package/dist/observability/sentry.js.map +1 -1
- package/dist/packages/admin.d.ts +17 -0
- package/dist/packages/admin.d.ts.map +1 -0
- package/dist/packages/admin.js +96 -0
- package/dist/packages/admin.js.map +1 -0
- package/dist/packages/index.d.ts +6 -0
- package/dist/packages/index.d.ts.map +1 -0
- package/dist/packages/index.js +6 -0
- package/dist/packages/index.js.map +1 -0
- package/dist/packages/inspect.d.ts +11 -0
- package/dist/packages/inspect.d.ts.map +1 -0
- package/dist/packages/inspect.js +100 -0
- package/dist/packages/inspect.js.map +1 -0
- package/dist/packages/materialize.d.ts +39 -0
- package/dist/packages/materialize.d.ts.map +1 -0
- package/dist/packages/materialize.js +300 -0
- package/dist/packages/materialize.js.map +1 -0
- package/dist/packages/resolve.d.ts +25 -0
- package/dist/packages/resolve.d.ts.map +1 -0
- package/dist/packages/resolve.js +212 -0
- package/dist/packages/resolve.js.map +1 -0
- package/dist/packages/source.d.ts +33 -0
- package/dist/packages/source.d.ts.map +1 -0
- package/dist/packages/source.js +177 -0
- package/dist/packages/source.js.map +1 -0
- package/dist/packages/types.d.ts +104 -0
- package/dist/packages/types.d.ts.map +1 -0
- package/dist/packages/types.js +2 -0
- package/dist/packages/types.js.map +1 -0
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +6 -6
- 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 +481 -98
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +28 -0
- package/dist/runtime/session-lifecycle.d.ts.map +1 -0
- package/dist/runtime/session-lifecycle.js +161 -0
- package/dist/runtime/session-lifecycle.js.map +1 -0
- package/dist/runtime/types.d.ts +45 -5
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts +3 -0
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +11 -0
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts +4 -0
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +12 -2
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/firecracker.d.ts +3 -0
- package/dist/sandbox/firecracker.d.ts.map +1 -1
- package/dist/sandbox/firecracker.js +11 -1
- package/dist/sandbox/firecracker.js.map +1 -1
- package/dist/sandbox/gondolin.d.ts +57 -0
- package/dist/sandbox/gondolin.d.ts.map +1 -0
- package/dist/sandbox/gondolin.js +764 -0
- package/dist/sandbox/gondolin.js.map +1 -0
- package/dist/sandbox/host.d.ts +4 -0
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +52 -0
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +16 -0
- package/dist/sandbox/identity.d.ts.map +1 -0
- package/dist/sandbox/identity.js +42 -0
- package/dist/sandbox/identity.js.map +1 -0
- package/dist/sandbox/image.d.ts.map +1 -1
- package/dist/sandbox/image.js +1 -0
- package/dist/sandbox/image.js.map +1 -1
- package/dist/sandbox/index.d.ts +15 -4
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +25 -3
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/path-context.js +18 -8
- package/dist/sandbox/path-context.js.map +1 -1
- package/dist/sandbox/types.d.ts +65 -1
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +12 -0
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +38 -0
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +25 -0
- package/dist/sessions/chat-history-sync.d.ts.map +1 -0
- package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +98 -124
- package/dist/sessions/chat-history-sync.js.map +1 -0
- package/dist/sessions/conversation-log.d.ts +9 -0
- package/dist/sessions/conversation-log.d.ts.map +1 -0
- package/dist/sessions/conversation-log.js +47 -0
- package/dist/sessions/conversation-log.js.map +1 -0
- 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/rotation.d.ts +2 -0
- package/dist/sessions/rotation.d.ts.map +1 -0
- package/dist/sessions/rotation.js +39 -0
- package/dist/sessions/rotation.js.map +1 -0
- package/dist/sessions/session-key.d.ts +40 -0
- package/dist/sessions/session-key.d.ts.map +1 -0
- package/dist/sessions/session-key.js +92 -0
- package/dist/sessions/session-key.js.map +1 -0
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +40 -18
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +17 -4
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings-mutation.d.ts +8 -0
- package/dist/settings-mutation.d.ts.map +1 -0
- package/dist/settings-mutation.js +43 -0
- package/dist/settings-mutation.js.map +1 -0
- package/dist/subagent-progress.d.ts +43 -0
- package/dist/subagent-progress.d.ts.map +1 -0
- package/dist/subagent-progress.js +220 -0
- package/dist/subagent-progress.js.map +1 -0
- package/dist/tools/bash.d.ts +3 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +25 -17
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +10 -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 +53 -43
- 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/host-fn-tool.d.ts +21 -0
- package/dist/tools/host-fn-tool.d.ts.map +1 -0
- package/dist/tools/host-fn-tool.js +32 -0
- package/dist/tools/host-fn-tool.js.map +1 -0
- package/dist/tools/index.d.ts +14 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +28 -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 +29 -0
- package/dist/tools/react.js.map +1 -0
- package/dist/tools/read.d.ts +1 -0
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +37 -31
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/sandbox.d.ts +2 -2
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/sandbox.js +14 -9
- package/dist/tools/sandbox.js.map +1 -1
- package/dist/tools/subagent-slots.d.ts +28 -0
- package/dist/tools/subagent-slots.d.ts.map +1 -0
- package/dist/tools/subagent-slots.js +72 -0
- package/dist/tools/subagent-slots.js.map +1 -0
- package/dist/tools/subagent.d.ts +54 -0
- package/dist/tools/subagent.d.ts.map +1 -0
- package/dist/tools/subagent.js +401 -0
- package/dist/tools/subagent.js.map +1 -0
- package/dist/tools/types.d.ts +40 -6
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +2 -8
- package/dist/tools/write.js.map +1 -1
- package/dist/trigger.d.ts.map +1 -1
- package/dist/trigger.js +1 -2
- package/dist/trigger.js.map +1 -1
- package/dist/types.d.ts +232 -32
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/date.d.ts +1 -1
- package/dist/utils/date.js +1 -1
- package/dist/utils/date.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 +22 -0
- package/dist/vault/disabled.js.map +1 -0
- package/dist/vault/index.d.ts +0 -2
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +30 -33
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/injection.d.ts +10 -0
- package/dist/vault/injection.d.ts.map +1 -0
- package/dist/vault/injection.js +30 -0
- package/dist/vault/injection.js.map +1 -0
- 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/types.d.ts +4 -2
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/dist/web/admin/portal.d.ts +17 -2
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +385 -155
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/types.d.ts +18 -0
- package/dist/web/admin/types.d.ts.map +1 -1
- package/dist/web/admin/types.js.map +1 -1
- package/dist/web/agent-events/portal.d.ts.map +1 -1
- package/dist/web/agent-events/portal.js +2 -1
- package/dist/web/agent-events/portal.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/dist/workspace-projection/index.d.ts +5 -0
- package/dist/workspace-projection/index.d.ts.map +1 -0
- package/dist/workspace-projection/index.js +71 -0
- package/dist/workspace-projection/index.js.map +1 -0
- package/dist/workspace-projection/types.d.ts +7 -0
- package/dist/workspace-projection/types.d.ts.map +1 -0
- package/dist/workspace-projection/types.js +2 -0
- package/dist/workspace-projection/types.js.map +1 -0
- package/package.json +28 -15
- package/dist/adapters/streaming.d.ts +0 -18
- package/dist/adapters/streaming.d.ts.map +0 -1
- package/dist/adapters/streaming.js +0 -44
- package/dist/adapters/streaming.js.map +0 -1
- package/dist/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/sessions/agent-memory-file-manager.d.ts +0 -19
- package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
- package/dist/sessions/agent-memory-file-manager.js.map +0 -1
- package/dist/vault/routing.d.ts +0 -3
- package/dist/vault/routing.d.ts.map +0 -1
- package/dist/vault/routing.js +0 -13
- package/dist/vault/routing.js.map +0 -1
- /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
- /package/dist/{download.js → cli/download.js} +0 -0
package/dist/sandbox/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import type { ResourceLimits } from "../types.js";
|
|
2
|
+
export type SandboxConfig = HostSandboxConfig | ContainerSandboxConfig | ImageSandboxConfig | GondolinSandboxConfig | FirecrackerSandboxConfig | CloudflareSandboxConfig;
|
|
2
3
|
export interface HostSandboxConfig {
|
|
3
4
|
type: "host";
|
|
4
5
|
}
|
|
@@ -10,6 +11,41 @@ export interface ImageSandboxConfig {
|
|
|
10
11
|
type: "image";
|
|
11
12
|
image: string;
|
|
12
13
|
}
|
|
14
|
+
export interface GondolinSandboxConfig {
|
|
15
|
+
type: "gondolin";
|
|
16
|
+
profile: "default";
|
|
17
|
+
/** Local-only runtime details supplied after actor/workspace resolution. */
|
|
18
|
+
image?: string;
|
|
19
|
+
workspacePath?: string;
|
|
20
|
+
mounts?: Array<{
|
|
21
|
+
source: string;
|
|
22
|
+
target: string;
|
|
23
|
+
readOnly?: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
instanceId?: string;
|
|
26
|
+
resourceKey?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface GondolinBootstrapOptions {
|
|
29
|
+
/** Default per-runtime resource limits. */
|
|
30
|
+
limits?: ResourceLimits;
|
|
31
|
+
/** Boosted limits applied while a runtime holds a boost. */
|
|
32
|
+
boostLimits?: ResourceLimits;
|
|
33
|
+
}
|
|
34
|
+
export interface SessionClientCallbacks {
|
|
35
|
+
onJson: (message: {
|
|
36
|
+
type: string;
|
|
37
|
+
id?: number;
|
|
38
|
+
exit_code?: number | null;
|
|
39
|
+
code?: string;
|
|
40
|
+
message?: string;
|
|
41
|
+
}) => void;
|
|
42
|
+
onBinary: (frame: Buffer) => void;
|
|
43
|
+
onClose: (error?: Error) => void;
|
|
44
|
+
}
|
|
45
|
+
export interface SessionClient {
|
|
46
|
+
send(message: object): void;
|
|
47
|
+
close(): void;
|
|
48
|
+
}
|
|
13
49
|
export interface FirecrackerSandboxConfig {
|
|
14
50
|
type: "firecracker";
|
|
15
51
|
vmId: string;
|
|
@@ -26,6 +62,29 @@ export interface Executor {
|
|
|
26
62
|
* Execute a bash command.
|
|
27
63
|
*/
|
|
28
64
|
exec(command: string, options?: ExecOptions): Promise<ExecResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Read a runtime file as UTF-8 text. The executor owns the transport, so
|
|
67
|
+
* file contents never pass through shell argv or extra shell parse layers.
|
|
68
|
+
*/
|
|
69
|
+
readFile(path: string, options?: ExecOptions): Promise<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Read a runtime file as base64 (for binary content, e.g. images). Same
|
|
72
|
+
* transport ownership as readFile.
|
|
73
|
+
*/
|
|
74
|
+
readFileBase64(path: string, options?: ExecOptions): Promise<string>;
|
|
75
|
+
/**
|
|
76
|
+
* Read an attachment without following any symlink in the path. Executors
|
|
77
|
+
* that cannot provide this atomically must omit the capability; attachment
|
|
78
|
+
* uploads then fail closed.
|
|
79
|
+
*/
|
|
80
|
+
readFileBase64NoSymlinks?(path: string, options?: ExecOptions): Promise<string>;
|
|
81
|
+
/**
|
|
82
|
+
* Write a runtime file, creating parent directories and replacing via a
|
|
83
|
+
* staging file so an aborted write never truncates the target. Like
|
|
84
|
+
* readFile, transport is the executor's concern — content must survive
|
|
85
|
+
* arbitrary quoting and ARG_MAX limits.
|
|
86
|
+
*/
|
|
87
|
+
writeFile(path: string, content: string, options?: ExecOptions): Promise<void>;
|
|
29
88
|
/**
|
|
30
89
|
* Get the workspace path prefix for this executor.
|
|
31
90
|
* Host: returns the actual path.
|
|
@@ -58,8 +117,13 @@ export interface ExecResult {
|
|
|
58
117
|
stderr: string;
|
|
59
118
|
code: number;
|
|
60
119
|
}
|
|
120
|
+
export interface SandboxCredentialCapabilities {
|
|
121
|
+
env: boolean;
|
|
122
|
+
fileMounts: boolean;
|
|
123
|
+
}
|
|
61
124
|
export interface SandboxAdapter<TConfig extends SandboxConfig = SandboxConfig> {
|
|
62
125
|
type: TConfig["type"];
|
|
126
|
+
credentials: SandboxCredentialCapabilities;
|
|
63
127
|
parse(value: string): TConfig | undefined;
|
|
64
128
|
validate?(config: TConfig): Promise<void>;
|
|
65
129
|
createExecutor?(config: TConfig, env?: Record<string, string>, ensureReady?: () => Promise<void>): Executor;
|
|
@@ -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":["
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ResourceLimits } from \"../types.js\";\n\nexport 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\";\n /** Local-only runtime details supplied after actor/workspace resolution. */\n image?: string;\n workspacePath?: string;\n mounts?: Array<{ source: string; target: string; readOnly?: boolean }>;\n instanceId?: string;\n resourceKey?: string;\n}\n\nexport interface GondolinBootstrapOptions {\n /** Default per-runtime resource limits. */\n limits?: ResourceLimits;\n /** Boosted limits applied while a runtime holds a boost. */\n boostLimits?: ResourceLimits;\n}\n\nexport interface SessionClientCallbacks {\n onJson: (message: {\n type: string;\n id?: number;\n exit_code?: number | null;\n code?: string;\n message?: string;\n }) => void;\n onBinary: (frame: Buffer) => void;\n onClose: (error?: Error) => void;\n}\n\nexport interface SessionClient {\n send(message: object): void;\n close(): void;\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 * Read a runtime file as base64 (for binary content, e.g. images). Same\n * transport ownership as readFile.\n */\n readFileBase64(path: string, options?: ExecOptions): Promise<string>;\n\n /**\n * Read an attachment without following any symlink in the path. Executors\n * that cannot provide this atomically must omit the capability; attachment\n * uploads then fail closed.\n */\n readFileBase64NoSymlinks?(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 SandboxCredentialCapabilities {\n env: boolean;\n fileMounts: boolean;\n}\n\nexport interface SandboxAdapter<TConfig extends SandboxConfig = SandboxConfig> {\n type: TConfig[\"type\"];\n credentials: SandboxCredentialCapabilities;\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,16 @@
|
|
|
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 execReadFileBase64<TOptions>(executor: ExecLike<TOptions>, path: string, options?: TOptions): Promise<string>;
|
|
13
|
+
export declare function execReadFile<TOptions>(executor: ExecLike<TOptions>, path: string, options?: TOptions): Promise<string>;
|
|
14
|
+
export declare function execWriteFile<TOptions>(executor: ExecLike<TOptions>, path: string, content: string, options?: TOptions): Promise<void>;
|
|
15
|
+
export {};
|
|
4
16
|
//# 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,kBAAkB,CAAC,QAAQ,EAC/C,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,MAAM,CAAC,CAMjB;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,CAEjB;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,42 @@ 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 execReadFileBase64(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 result.stdout.replace(/\s+/g, "");
|
|
65
|
+
}
|
|
66
|
+
export async function execReadFile(executor, path, options) {
|
|
67
|
+
return Buffer.from(await execReadFileBase64(executor, path, options), "base64").toString("utf-8");
|
|
68
|
+
}
|
|
69
|
+
export async function execWriteFile(executor, path, content, options) {
|
|
70
|
+
const encoded = Buffer.from(content, "utf-8").toString("base64");
|
|
71
|
+
const escapedPath = shellEscape(path);
|
|
72
|
+
const stage = shellEscape(`${path}.mikan-stage`);
|
|
73
|
+
const stageB64 = shellEscape(`${path}.mikan-stage.b64`);
|
|
74
|
+
const run = async (command) => {
|
|
75
|
+
const result = await executor.exec(command, options);
|
|
76
|
+
if (result.code !== 0) {
|
|
77
|
+
await executor.exec(`rm -f ${stage} ${stageB64}`, options).catch(() => { });
|
|
78
|
+
throw new Error(result.stderr.trim() || `Failed to write file: ${path}`);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const dir = path.includes("/") ? path.slice(0, path.lastIndexOf("/")) || "/" : ".";
|
|
82
|
+
await run(`mkdir -p ${shellEscape(dir)} && : > ${stageB64}`);
|
|
83
|
+
for (let offset = 0; offset === 0 || offset < encoded.length; offset += WRITE_CHUNK_CHARS) {
|
|
84
|
+
const chunk = encoded.slice(offset, offset + WRITE_CHUNK_CHARS);
|
|
85
|
+
await run(`printf '%s' ${shellEscape(chunk)} >> ${stageB64}`);
|
|
86
|
+
}
|
|
87
|
+
await run(`base64 -d < ${stageB64} > ${stage} && mv ${stage} ${escapedPath} && rm -f ${stageB64}`);
|
|
88
|
+
}
|
|
51
89
|
//# 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 execReadFileBase64<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 result.stdout.replace(/\\s+/g, \"\");\n}\n\nexport async function execReadFile<TOptions>(\n executor: ExecLike<TOptions>,\n path: string,\n options?: TOptions,\n): Promise<string> {\n return Buffer.from(await execReadFileBase64(executor, path, options), \"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"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ResolvedSessionScope } from "./store.js";
|
|
2
|
+
export type { ChatHistorySyncOptions, HasMaterializedSessionOptions, RegisterThreadSessionOptions, ResetChatSessionOptions, ResolveChatSessionScopeOptions, SyncChatSessionOptions, ThreadBootstrapWaitOptions, ChatSyncReport, } from "./types.js";
|
|
3
|
+
import type { ChatHistorySyncOptions, HasMaterializedSessionOptions, RegisterThreadSessionOptions, ResetChatSessionOptions, ResolveChatSessionScopeOptions, SyncChatSessionOptions, ThreadBootstrapWaitOptions, ChatSyncReport } from "./types.js";
|
|
4
|
+
export declare function hasMaterializedChatSession(options: HasMaterializedSessionOptions): boolean;
|
|
5
|
+
export declare function registerThreadSession(options: RegisterThreadSessionOptions): string | null;
|
|
6
|
+
export declare function waitForThreadSessionBootstrap(options: ThreadBootstrapWaitOptions): Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Syncs the platform chat transcript (log.jsonl) into managed session files:
|
|
9
|
+
* resolves which session file a message belongs to (top-level vs thread,
|
|
10
|
+
* with biweekly rotation), bootstraps new sessions from recent history, and
|
|
11
|
+
* incrementally appends log messages the session does not yet represent.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ChatHistorySync {
|
|
14
|
+
private readonly recentDays;
|
|
15
|
+
private readonly maxTopLevelMessages;
|
|
16
|
+
private readonly now;
|
|
17
|
+
constructor(options?: ChatHistorySyncOptions);
|
|
18
|
+
resolveSessionScope(options: ResolveChatSessionScopeOptions): Promise<ResolvedSessionScope>;
|
|
19
|
+
syncSessionManager(options: SyncChatSessionOptions): ChatSyncReport;
|
|
20
|
+
resetSession(options: ResetChatSessionOptions): string;
|
|
21
|
+
private resolveTopLevelSessionFile;
|
|
22
|
+
private historyWindow;
|
|
23
|
+
private resolveThreadSessionScope;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=chat-history-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-history-sync.d.ts","sourceRoot":"","sources":["../../src/sessions/chat-history-sync.ts"],"names":[],"mappings":"AASA,OAAO,EAUL,KAAK,oBAAoB,EAE1B,MAAM,YAAY,CAAC;AAQpB,YAAY,EACV,sBAAsB,EACtB,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,sBAAsB,EACtB,0BAA0B,EAC1B,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,sBAAsB,EACtB,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,sBAAsB,EACtB,0BAA0B,EAC1B,cAAc,EAEf,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;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IAEjC,YAAY,OAAO,GAAE,sBAA2B,EAI/C;IAEK,mBAAmB,CACvB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,oBAAoB,CAAC,CAsB/B;IAED,kBAAkB,CAAC,OAAO,EAAE,sBAAsB,GAAG,cAAc,CAUlE;IAED,YAAY,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAmBrD;IAED,OAAO,CAAC,0BAA0B;IA2ClC,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,yBAAyB;CA4ClC"}
|
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import * as log from "../log.js";
|
|
1
|
+
import { isRecord } from "../utils/file-guards.js";
|
|
2
|
+
import { isCommandText } from "../commands/text.js";
|
|
3
|
+
import { readConversationLog } from "./conversation-log.js";
|
|
4
|
+
import { formatHistoryLine, stripHistoryLinePrefix } from "./history-line.js";
|
|
6
5
|
import { isPlatformHistorySession } from "./metadata.js";
|
|
6
|
+
import { shouldRotateTopLevelSession } from "./rotation.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;
|
|
10
11
|
const CHAT_SYNC_CUSTOM_TYPE = "mikan.chat_sync";
|
|
11
|
-
const BIWEEKLY_ROTATION_ANCHOR = new Date(2026, 0, 4); // Sunday
|
|
12
|
-
const BIWEEKLY_MS = 14 * 24 * 60 * 60 * 1000;
|
|
13
12
|
export function hasMaterializedChatSession(options) {
|
|
14
|
-
if (!options.sessionKey
|
|
13
|
+
if (!isThreadSessionKey(options.sessionKey)) {
|
|
15
14
|
return resolveChannelSessionFile(options.conversationDir) !== null;
|
|
16
15
|
}
|
|
17
16
|
return (tryResolveThreadSession(getThreadSessionFile(options.conversationDir, options.sessionKey)) !==
|
|
18
17
|
null);
|
|
19
18
|
}
|
|
20
19
|
export function registerThreadSession(options) {
|
|
21
|
-
if (!options.sessionKey
|
|
20
|
+
if (!isThreadSessionKey(options.sessionKey))
|
|
22
21
|
return null;
|
|
23
22
|
const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);
|
|
24
23
|
return (tryResolveThreadSession(threadFile) ??
|
|
@@ -26,7 +25,7 @@ export function registerThreadSession(options) {
|
|
|
26
25
|
}
|
|
27
26
|
export async function waitForThreadSessionBootstrap(options) {
|
|
28
27
|
const { parentSessionKey, sessionKey, hasThreadSession, isParentRunning, sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), pollMs = 100, } = options;
|
|
29
|
-
if (!sessionKey
|
|
28
|
+
if (!isThreadSessionKey(sessionKey))
|
|
30
29
|
return false;
|
|
31
30
|
if (sessionKey === parentSessionKey)
|
|
32
31
|
return false;
|
|
@@ -39,7 +38,13 @@ export async function waitForThreadSessionBootstrap(options) {
|
|
|
39
38
|
}
|
|
40
39
|
return waited;
|
|
41
40
|
}
|
|
42
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Syncs the platform chat transcript (log.jsonl) into managed session files:
|
|
43
|
+
* resolves which session file a message belongs to (top-level vs thread,
|
|
44
|
+
* with biweekly rotation), bootstraps new sessions from recent history, and
|
|
45
|
+
* incrementally appends log messages the session does not yet represent.
|
|
46
|
+
*/
|
|
47
|
+
export class ChatHistorySync {
|
|
43
48
|
constructor(options = {}) {
|
|
44
49
|
this.recentDays = options.recentDays ?? DEFAULT_RECENT_DAYS;
|
|
45
50
|
this.maxTopLevelMessages = options.maxTopLevelMessages ?? DEFAULT_MAX_TOP_LEVEL_MESSAGES;
|
|
@@ -48,7 +53,7 @@ export class AgentMemoryFileManager {
|
|
|
48
53
|
async resolveSessionScope(options) {
|
|
49
54
|
const cwd = options.cwd ?? options.conversationDir;
|
|
50
55
|
const sessionDir = getChannelSessionDir(options.conversationDir);
|
|
51
|
-
if (!options.sessionKey
|
|
56
|
+
if (!isThreadSessionKey(options.sessionKey)) {
|
|
52
57
|
const contextFile = this.resolveTopLevelSessionFile({
|
|
53
58
|
conversationDir: options.conversationDir,
|
|
54
59
|
sessionDir,
|
|
@@ -68,17 +73,27 @@ export class AgentMemoryFileManager {
|
|
|
68
73
|
}
|
|
69
74
|
syncSessionManager(options) {
|
|
70
75
|
const records = readConversationLog(options.conversationDir);
|
|
71
|
-
syncSessionManagerFromLog(options.sessionManager, selectExistingSessionSyncMessages(records, {
|
|
72
|
-
sessionKey: options.sessionKey
|
|
76
|
+
return syncSessionManagerFromLog(options.sessionManager, selectExistingSessionSyncMessages(records, {
|
|
77
|
+
sessionKey: isThreadSessionKey(options.sessionKey) ? options.sessionKey : null,
|
|
73
78
|
excludeMessageId: options.currentMessageId,
|
|
74
79
|
}), this.historyWindow());
|
|
75
80
|
}
|
|
76
81
|
resetSession(options) {
|
|
77
82
|
const cwd = options.cwd ?? options.conversationDir;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
const sessionFile = isThreadSessionKey(options.sessionKey)
|
|
84
|
+
? createManagedSessionFileAtPath(getThreadSessionFile(options.conversationDir, options.sessionKey), cwd)
|
|
85
|
+
: createManagedSessionFile(getChannelSessionDir(options.conversationDir), cwd);
|
|
86
|
+
const records = readConversationLog(options.conversationDir);
|
|
87
|
+
const lastMessageId = latestSyncMessageId(records, {
|
|
88
|
+
sessionKey: isThreadSessionKey(options.sessionKey) ? options.sessionKey : null,
|
|
89
|
+
});
|
|
90
|
+
openManagedSession(sessionFile, cwd).appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {
|
|
91
|
+
source: "log.jsonl",
|
|
92
|
+
messageCount: 0,
|
|
93
|
+
resetAt: this.now().toISOString(),
|
|
94
|
+
...(lastMessageId ? { lastMessageId } : {}),
|
|
95
|
+
});
|
|
96
|
+
return sessionFile;
|
|
82
97
|
}
|
|
83
98
|
resolveTopLevelSessionFile(options) {
|
|
84
99
|
const records = readConversationLog(options.conversationDir);
|
|
@@ -135,74 +150,6 @@ export class AgentMemoryFileManager {
|
|
|
135
150
|
return { sessionDir: options.sessionDir, contextFile: threadFile, threadRootMessage };
|
|
136
151
|
}
|
|
137
152
|
}
|
|
138
|
-
function shouldRotateTopLevelSession(sessionFile, now) {
|
|
139
|
-
const timestamp = readSessionTimestamp(sessionFile);
|
|
140
|
-
return timestamp !== null && biweeklyBucket(timestamp) !== biweeklyBucket(now);
|
|
141
|
-
}
|
|
142
|
-
function readSessionTimestamp(sessionFile) {
|
|
143
|
-
const raw = readTextFileIfExists(sessionFile);
|
|
144
|
-
if (raw === undefined)
|
|
145
|
-
return null;
|
|
146
|
-
const firstLine = raw.split("\n").find((line) => line.trim());
|
|
147
|
-
if (!firstLine)
|
|
148
|
-
return null;
|
|
149
|
-
try {
|
|
150
|
-
const header = parseJsonValue(firstLine, (value) => isRecord(value), (detail) => (detail === "unexpected JSON shape" ? "expected a JSON object" : detail));
|
|
151
|
-
if (typeof header.timestamp !== "string")
|
|
152
|
-
return null;
|
|
153
|
-
const date = new Date(header.timestamp);
|
|
154
|
-
return Number.isFinite(date.getTime()) ? date : null;
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
function biweeklyBucket(date) {
|
|
161
|
-
const weekStart = sundayStart(date).getTime();
|
|
162
|
-
const anchor = sundayStart(BIWEEKLY_ROTATION_ANCHOR).getTime();
|
|
163
|
-
return Math.floor((weekStart - anchor) / BIWEEKLY_MS);
|
|
164
|
-
}
|
|
165
|
-
function sundayStart(date) {
|
|
166
|
-
return new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());
|
|
167
|
-
}
|
|
168
|
-
function readConversationLog(conversationDir) {
|
|
169
|
-
const logFile = join(conversationDir, "log.jsonl");
|
|
170
|
-
const raw = readTextFileIfExists(logFile);
|
|
171
|
-
if (raw === undefined)
|
|
172
|
-
return [];
|
|
173
|
-
const lines = raw.trim().split("\n").filter(Boolean);
|
|
174
|
-
const records = [];
|
|
175
|
-
for (let i = 0; i < lines.length; i++) {
|
|
176
|
-
try {
|
|
177
|
-
const message = parseJsonValue(lines[i], (value) => isRecord(value), (detail) => (detail === "unexpected JSON shape" ? "expected a JSON object" : detail));
|
|
178
|
-
records.push({ message, index: i });
|
|
179
|
-
}
|
|
180
|
-
catch (err) {
|
|
181
|
-
log.logWarning(`Skipping malformed log entry at ${logFile}:${i + 1}`, err instanceof Error ? err.message : String(err));
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return coalesceMessagingBotLogChunks(records);
|
|
185
|
-
}
|
|
186
|
-
function coalesceMessagingBotLogChunks(records) {
|
|
187
|
-
const coalesced = [];
|
|
188
|
-
for (const record of records) {
|
|
189
|
-
const previous = coalesced.at(-1);
|
|
190
|
-
if (previous && canCoalesceMessagingBotLogChunk(previous.message, record.message)) {
|
|
191
|
-
previous.message.text = `${previous.message.text ?? ""}${record.message.text ?? ""}`;
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
coalesced.push({ ...record, message: { ...record.message } });
|
|
195
|
-
}
|
|
196
|
-
return coalesced;
|
|
197
|
-
}
|
|
198
|
-
function canCoalesceMessagingBotLogChunk(previous, current) {
|
|
199
|
-
return (previous.isMessagingBot === true &&
|
|
200
|
-
current.isMessagingBot === true &&
|
|
201
|
-
!!previous.ts &&
|
|
202
|
-
previous.ts === current.ts &&
|
|
203
|
-
previous.threadTs === current.threadTs &&
|
|
204
|
-
previous.user === current.user);
|
|
205
|
-
}
|
|
206
153
|
function findLogRecordById(records, messageId) {
|
|
207
154
|
for (let i = records.length - 1; i >= 0; i--) {
|
|
208
155
|
if (records[i].message.ts === messageId)
|
|
@@ -211,7 +158,7 @@ function findLogRecordById(records, messageId) {
|
|
|
211
158
|
return undefined;
|
|
212
159
|
}
|
|
213
160
|
function selectRecentTopLevelMessages(records, options) {
|
|
214
|
-
return selectRecentMessages(records.filter((record) => isTopLevelHistoryMessage(record.message, options.excludeMessageId)), options);
|
|
161
|
+
return selectRecentMessages(recordsBeforeCurrentMessage(records, options.excludeMessageId).filter((record) => isTopLevelHistoryMessage(record.message, options.excludeMessageId)), options);
|
|
215
162
|
}
|
|
216
163
|
function selectRecentMessages(records, options) {
|
|
217
164
|
const sinceMs = options.now.getTime() - options.recentDays * 24 * 60 * 60 * 1000;
|
|
@@ -220,17 +167,18 @@ function selectRecentMessages(records, options) {
|
|
|
220
167
|
.slice(-options.maxMessages);
|
|
221
168
|
}
|
|
222
169
|
function selectThreadBootstrapMessages(records, threadId, options) {
|
|
223
|
-
const
|
|
170
|
+
const scopedRecords = recordsBeforeCurrentMessage(records, options.excludeMessageId);
|
|
171
|
+
const rootRecord = findLogRecordById(scopedRecords, threadId);
|
|
224
172
|
const topLevelSource = rootRecord
|
|
225
|
-
?
|
|
226
|
-
:
|
|
173
|
+
? scopedRecords.filter((record) => record.index <= rootRecord.index)
|
|
174
|
+
: scopedRecords;
|
|
227
175
|
const topLevelRecords = selectRecentTopLevelMessages(topLevelSource, {
|
|
228
176
|
recentDays: options.recentDays,
|
|
229
177
|
maxMessages: options.maxTopLevelMessages,
|
|
230
178
|
now: options.now,
|
|
231
179
|
excludeMessageId: options.excludeMessageId,
|
|
232
180
|
});
|
|
233
|
-
const threadRecords =
|
|
181
|
+
const threadRecords = scopedRecords.filter((record) => isRenderableConversationMessage(record.message, options.excludeMessageId) &&
|
|
234
182
|
(record.message.ts === threadId || record.message.threadTs === threadId));
|
|
235
183
|
return dedupeAndSortRecords([...topLevelRecords, ...threadRecords]);
|
|
236
184
|
}
|
|
@@ -247,7 +195,7 @@ function isRecentHistoryMessage(message, sinceMs) {
|
|
|
247
195
|
}
|
|
248
196
|
function selectExistingSessionSyncMessages(records, options) {
|
|
249
197
|
const threadId = options.sessionKey ? extractSessionSuffix(options.sessionKey) : null;
|
|
250
|
-
return dedupeAndSortRecords(records.filter((record) => {
|
|
198
|
+
return dedupeAndSortRecords(recordsBeforeCurrentMessage(records, options.excludeMessageId).filter((record) => {
|
|
251
199
|
if (!isRenderableConversationMessage(record.message, options.excludeMessageId))
|
|
252
200
|
return false;
|
|
253
201
|
if (!threadId)
|
|
@@ -255,6 +203,19 @@ function selectExistingSessionSyncMessages(records, options) {
|
|
|
255
203
|
return record.message.ts === threadId || record.message.threadTs === threadId;
|
|
256
204
|
}));
|
|
257
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Slack logs messages before enqueueing them, so a later queued turn may
|
|
208
|
+
* already be present while the current turn is being prepared. Chat history
|
|
209
|
+
* must stop at the current record rather than merely removing that one id.
|
|
210
|
+
*/
|
|
211
|
+
function recordsBeforeCurrentMessage(records, currentMessageId) {
|
|
212
|
+
if (!currentMessageId)
|
|
213
|
+
return records;
|
|
214
|
+
const currentRecord = findLogRecordById(records, currentMessageId);
|
|
215
|
+
if (!currentRecord)
|
|
216
|
+
return records;
|
|
217
|
+
return records.filter((record) => record.index < currentRecord.index);
|
|
218
|
+
}
|
|
258
219
|
function latestSyncMessageId(records, options) {
|
|
259
220
|
return selectExistingSessionSyncMessages(records, options).at(-1)?.message.ts;
|
|
260
221
|
}
|
|
@@ -266,9 +227,7 @@ function isRenderableConversationMessage(message, excludeMessageId) {
|
|
|
266
227
|
return !!message.text?.trim();
|
|
267
228
|
}
|
|
268
229
|
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));
|
|
230
|
+
return !message.isMessagingBot && isCommandText(message.text ?? "");
|
|
272
231
|
}
|
|
273
232
|
function dedupeAndSortRecords(records) {
|
|
274
233
|
const byKey = new Map();
|
|
@@ -306,36 +265,44 @@ function bootstrapSessionFromLog(sessionFile, cwd, records, lastMessageId = reco
|
|
|
306
265
|
messageCount: records.length,
|
|
307
266
|
lastMessageId,
|
|
308
267
|
});
|
|
309
|
-
forceRewriteSession(sessionManager, sessionFile);
|
|
310
268
|
}
|
|
311
269
|
function syncSessionFromLog(sessionFile, cwd, records, historyWindow) {
|
|
312
270
|
if (records.length === 0)
|
|
313
|
-
return;
|
|
314
|
-
syncSessionManagerFromLog(openManagedSession(sessionFile, cwd), records, historyWindow);
|
|
271
|
+
return { appended: 0 };
|
|
272
|
+
return syncSessionManagerFromLog(openManagedSession(sessionFile, cwd), records, historyWindow);
|
|
315
273
|
}
|
|
316
274
|
function syncSessionManagerFromLog(sessionManager, records, historyWindow) {
|
|
317
275
|
if (records.length === 0)
|
|
318
|
-
return;
|
|
276
|
+
return { appended: 0 };
|
|
319
277
|
const existingEntries = sessionManager.getEntries();
|
|
278
|
+
const resetAt = getLatestChatSyncResetAt(existingEntries);
|
|
279
|
+
const eligibleRecords = resetAt
|
|
280
|
+
? records.filter((record) => isAfterReset(record, resetAt))
|
|
281
|
+
: records;
|
|
320
282
|
const lastSyncedMessageId = getLatestChatSyncMessageId(existingEntries);
|
|
321
283
|
const lastSyncedIndex = lastSyncedMessageId
|
|
322
|
-
?
|
|
284
|
+
? eligibleRecords.findIndex((record) => record.message.ts === lastSyncedMessageId)
|
|
323
285
|
: -1;
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
const syncCandidates = selectRecentMessages(
|
|
286
|
+
// A truncated or rebuilt log may no longer contain the watermark. Replay the
|
|
287
|
+
// current bounded history; represented-message matching below prevents duplicates.
|
|
288
|
+
const syncCandidates = selectRecentMessages(eligibleRecords.slice(lastSyncedIndex + 1), historyWindow);
|
|
327
289
|
if (syncCandidates.length === 0)
|
|
328
|
-
return;
|
|
290
|
+
return { appended: 0 };
|
|
329
291
|
const represented = buildRepresentedMessageCounts(existingEntries);
|
|
330
292
|
const newRecords = syncCandidates.filter((record) => !consumeRepresentedLogMessage(record, represented));
|
|
331
293
|
if (newRecords.length === 0)
|
|
332
|
-
return;
|
|
294
|
+
return { appended: 0 };
|
|
295
|
+
const lastMessageId = syncCandidates.at(-1)?.message.ts;
|
|
333
296
|
appendLogRecordsToSession(sessionManager, newRecords);
|
|
334
297
|
sessionManager.appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {
|
|
335
298
|
source: "log.jsonl",
|
|
336
299
|
messageCount: newRecords.length,
|
|
337
|
-
lastMessageId
|
|
300
|
+
lastMessageId,
|
|
338
301
|
});
|
|
302
|
+
return {
|
|
303
|
+
appended: newRecords.length,
|
|
304
|
+
...(lastMessageId !== undefined ? { lastMessageId } : {}),
|
|
305
|
+
};
|
|
339
306
|
}
|
|
340
307
|
function appendLogRecordsToSession(sessionManager, records) {
|
|
341
308
|
for (const record of records) {
|
|
@@ -344,14 +311,24 @@ function appendLogRecordsToSession(sessionManager, records) {
|
|
|
344
311
|
sessionManager.appendMessage(message);
|
|
345
312
|
}
|
|
346
313
|
}
|
|
347
|
-
function
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
314
|
+
function getLatestChatSyncResetAt(entries) {
|
|
315
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
316
|
+
const entry = entries[i];
|
|
317
|
+
if (entry.type !== "custom" || entry.customType !== CHAT_SYNC_CUSTOM_TYPE)
|
|
318
|
+
continue;
|
|
319
|
+
if (!isRecord(entry.data) || typeof entry.data.resetAt !== "string")
|
|
320
|
+
continue;
|
|
321
|
+
const resetAt = new Date(entry.data.resetAt).getTime();
|
|
322
|
+
if (Number.isFinite(resetAt))
|
|
323
|
+
return resetAt;
|
|
324
|
+
}
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
function isAfterReset(record, resetAt) {
|
|
328
|
+
if (!record.message.date)
|
|
329
|
+
return false;
|
|
330
|
+
const messageTime = new Date(record.message.date).getTime();
|
|
331
|
+
return Number.isFinite(messageTime) && messageTime >= resetAt;
|
|
355
332
|
}
|
|
356
333
|
function getLatestChatSyncMessageId(entries) {
|
|
357
334
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
@@ -413,11 +390,7 @@ function getSessionMessageText(entry) {
|
|
|
413
390
|
.map((part) => (part.type === "text" && "text" in part ? part.text : ""))
|
|
414
391
|
.join("\n");
|
|
415
392
|
}
|
|
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
|
-
}
|
|
393
|
+
const normalizeComparableText = stripHistoryLinePrefix;
|
|
421
394
|
function buildHistorySessionMessage(message) {
|
|
422
395
|
const text = message.text?.trim();
|
|
423
396
|
if (!text)
|
|
@@ -466,10 +439,11 @@ function parseMessageTimestamp(message) {
|
|
|
466
439
|
return undefined;
|
|
467
440
|
}
|
|
468
441
|
function formatHistoryMessage(message) {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
442
|
+
return formatHistoryLine({
|
|
443
|
+
date: message.date ? new Date(message.date) : undefined,
|
|
444
|
+
userName: message.userName || message.user,
|
|
445
|
+
text: message.text?.trim() ?? "",
|
|
446
|
+
});
|
|
473
447
|
}
|
|
474
448
|
function zeroUsage() {
|
|
475
449
|
return {
|
|
@@ -481,4 +455,4 @@ function zeroUsage() {
|
|
|
481
455
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
482
456
|
};
|
|
483
457
|
}
|
|
484
|
-
//# sourceMappingURL=
|
|
458
|
+
//# sourceMappingURL=chat-history-sync.js.map
|