@earendil-works/pi-coding-agent 0.84.3 → 0.85.0
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 +98 -2
- package/README.md +8 -5
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +10 -7
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/runtime-setup.d.ts +2 -0
- package/dist/bun/runtime-setup.d.ts.map +1 -0
- package/dist/bun/runtime-setup.js +9 -0
- package/dist/bun/runtime-setup.js.map +1 -0
- package/dist/bundle/chunks/anthropic-messages-QAQLEQIY.js +6 -0
- package/dist/bundle/chunks/{azure-openai-responses-5ENVCQ7U.js → azure-openai-responses-Q7MJBRE6.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
- package/dist/bundle/chunks/{chunk-GPPBJGBU.js → chunk-2KVJKXS2.js} +1 -1
- package/dist/bundle/chunks/chunk-7ZC4UXSL.js +2 -0
- package/dist/bundle/chunks/chunk-EQ6DR6XK.js +5 -0
- package/dist/bundle/chunks/{chunk-MNAIPA3J.js → chunk-IDDQWTHI.js} +1 -1
- package/dist/bundle/chunks/chunk-LZKJTKCT.js +2 -0
- package/dist/bundle/chunks/{chunk-NBBFIJUL.js → chunk-OUXLLA64.js} +2 -2
- package/dist/bundle/chunks/chunk-R7UUJ4C2.js +42 -0
- package/dist/bundle/chunks/chunk-USJZMAIR.js +2 -0
- package/dist/bundle/chunks/chunk-WBE4J4AU.js +9 -0
- package/dist/bundle/chunks/chunk-WZB2R5YO.js +1558 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{google-generative-ai-XDKMGBCJ.js → google-generative-ai-BSMTYDAM.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-D5FGEO3Y.js → google-vertex-5C3HASOJ.js} +1 -1
- package/dist/bundle/chunks/https-proxy-agent-2VXB7436.js +13 -0
- package/dist/bundle/chunks/image-resize-worker.js +1 -1
- package/dist/bundle/chunks/{mistral-conversations-YK73UAOZ.js → mistral-conversations-4M6BZBX6.js} +2 -2
- package/dist/bundle/chunks/node-EM5FIVUN.js +16 -0
- package/dist/bundle/chunks/node-TWVVAGPO.js +2 -0
- package/dist/bundle/chunks/openai-codex-responses-YJOO52RW.js +10 -0
- package/dist/bundle/chunks/openai-completions-QOT3QX7D.js +7 -0
- package/dist/bundle/chunks/openai-responses-U7LNPQN4.js +2 -0
- package/dist/bundle/chunks/{pi-messages-TPFH44NP.js → pi-messages-EGZIFQGG.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/client.js +1 -1
- package/dist/bundle/coordinator.js +3 -0
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +2 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/experimental/cli.d.ts +7 -3
- package/dist/cli/experimental/cli.d.ts.map +1 -1
- package/dist/cli/experimental/cli.js +6 -2
- package/dist/cli/experimental/cli.js.map +1 -1
- package/dist/cli/experimental/command-options.d.ts +23 -12
- package/dist/cli/experimental/command-options.d.ts.map +1 -1
- package/dist/cli/experimental/command-options.js +69 -20
- package/dist/cli/experimental/command-options.js.map +1 -1
- package/dist/cli/experimental/command.d.ts +10 -3
- package/dist/cli/experimental/command.d.ts.map +1 -1
- package/dist/cli/experimental/command.js +28 -14
- package/dist/cli/experimental/command.js.map +1 -1
- package/dist/cli/experimental/commands/client.d.ts +8 -2
- package/dist/cli/experimental/commands/client.d.ts.map +1 -1
- package/dist/cli/experimental/commands/client.js +43 -5
- package/dist/cli/experimental/commands/client.js.map +1 -1
- package/dist/cli/experimental/commands/server.d.ts +7 -3
- package/dist/cli/experimental/commands/server.d.ts.map +1 -1
- package/dist/cli/experimental/commands/server.js +27 -8
- package/dist/cli/experimental/commands/server.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +2 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +23 -14
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts +1 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -2
- package/dist/client/index.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +15 -7
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +14 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +91 -15
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +6 -4
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +5 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +19 -5
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +1 -2
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +45 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +26 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +2 -0
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/messages.d.ts +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts +15 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +3 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-runtime.d.ts +1 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +5 -2
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +8 -2
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +44 -15
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +8 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +17 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +4 -2
- package/dist/core/skills.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +8 -9
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +3 -117
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +1 -12
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +5 -163
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +4 -55
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +4 -60
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +4 -49
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +4 -120
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts +12 -0
- package/dist/core/tools/renderers/bash.d.ts.map +1 -0
- package/dist/core/tools/renderers/bash.js +130 -0
- package/dist/core/tools/renderers/bash.js.map +1 -0
- package/dist/core/tools/renderers/edit.d.ts +23 -0
- package/dist/core/tools/renderers/edit.d.ts.map +1 -0
- package/dist/core/tools/renderers/edit.js +167 -0
- package/dist/core/tools/renderers/edit.js.map +1 -0
- package/dist/core/tools/renderers/find.d.ts +10 -0
- package/dist/core/tools/renderers/find.d.ts.map +1 -0
- package/dist/core/tools/renderers/find.js +64 -0
- package/dist/core/tools/renderers/find.js.map +1 -0
- package/dist/core/tools/renderers/grep.d.ts +10 -0
- package/dist/core/tools/renderers/grep.d.ts.map +1 -0
- package/dist/core/tools/renderers/grep.js +69 -0
- package/dist/core/tools/renderers/grep.js.map +1 -0
- package/dist/core/tools/renderers/index.d.ts +28 -0
- package/dist/core/tools/renderers/index.d.ts.map +1 -0
- package/dist/core/tools/renderers/index.js +47 -0
- package/dist/core/tools/renderers/index.js.map +1 -0
- package/dist/core/tools/renderers/ls.d.ts +10 -0
- package/dist/core/tools/renderers/ls.d.ts.map +1 -0
- package/dist/core/tools/renderers/ls.js +58 -0
- package/dist/core/tools/renderers/ls.js.map +1 -0
- package/dist/core/tools/renderers/read.d.ts +11 -0
- package/dist/core/tools/renderers/read.d.ts.map +1 -0
- package/dist/core/tools/renderers/read.js +129 -0
- package/dist/core/tools/renderers/read.js.map +1 -0
- package/dist/core/tools/renderers/write.d.ts +10 -0
- package/dist/core/tools/renderers/write.d.ts.map +1 -0
- package/dist/core/tools/renderers/write.js +153 -0
- package/dist/core/tools/renderers/write.js.map +1 -0
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +5 -146
- package/dist/core/tools/write.js.map +1 -1
- package/dist/experimental/client-runtime.d.ts +43 -0
- package/dist/experimental/client-runtime.d.ts.map +1 -0
- package/dist/experimental/client-runtime.js +183 -0
- package/dist/experimental/client-runtime.js.map +1 -0
- package/dist/experimental/client-tui-chat.d.ts +14 -0
- package/dist/experimental/client-tui-chat.d.ts.map +1 -0
- package/dist/experimental/client-tui-chat.js +171 -0
- package/dist/experimental/client-tui-chat.js.map +1 -0
- package/dist/experimental/client-tui.d.ts +37 -0
- package/dist/experimental/client-tui.d.ts.map +1 -0
- package/dist/experimental/client-tui.js +702 -0
- package/dist/experimental/client-tui.js.map +1 -0
- package/dist/experimental/client.d.ts +25 -0
- package/dist/experimental/client.d.ts.map +1 -0
- package/dist/experimental/client.js +99 -0
- package/dist/experimental/client.js.map +1 -0
- package/dist/experimental/coordinator-entry.d.ts +3 -0
- package/dist/experimental/coordinator-entry.d.ts.map +1 -0
- package/dist/experimental/coordinator-entry.js +11 -0
- package/dist/experimental/coordinator-entry.js.map +1 -0
- package/dist/experimental/coordinator.d.ts +38 -0
- package/dist/experimental/coordinator.d.ts.map +1 -0
- package/dist/experimental/coordinator.js +570 -0
- package/dist/experimental/coordinator.js.map +1 -0
- package/dist/experimental/mini/main.d.ts +7 -0
- package/dist/experimental/mini/main.d.ts.map +1 -0
- package/dist/experimental/mini/main.js +21 -0
- package/dist/experimental/mini/main.js.map +1 -0
- package/dist/experimental/mini/server/entry.d.ts +3 -0
- package/dist/experimental/mini/server/entry.d.ts.map +1 -0
- package/dist/experimental/mini/server/entry.js +11 -0
- package/dist/experimental/mini/server/entry.js.map +1 -0
- package/dist/experimental/mini/server/run.d.ts +13 -0
- package/dist/experimental/mini/server/run.d.ts.map +1 -0
- package/dist/experimental/mini/server/run.js +150 -0
- package/dist/experimental/mini/server/run.js.map +1 -0
- package/dist/experimental/mini/shared/protocol.d.ts +127 -0
- package/dist/experimental/mini/shared/protocol.d.ts.map +1 -0
- package/dist/experimental/mini/shared/protocol.js +13 -0
- package/dist/experimental/mini/shared/protocol.js.map +1 -0
- package/dist/experimental/mini/shared/rpc.d.ts +49 -0
- package/dist/experimental/mini/shared/rpc.d.ts.map +1 -0
- package/dist/experimental/mini/shared/rpc.js +171 -0
- package/dist/experimental/mini/shared/rpc.js.map +1 -0
- package/dist/experimental/mini/shared/transport.d.ts +35 -0
- package/dist/experimental/mini/shared/transport.d.ts.map +1 -0
- package/dist/experimental/mini/shared/transport.js +94 -0
- package/dist/experimental/mini/shared/transport.js.map +1 -0
- package/dist/experimental/mini/tui/run.d.ts +9 -0
- package/dist/experimental/mini/tui/run.d.ts.map +1 -0
- package/dist/experimental/mini/tui/run.js +62 -0
- package/dist/experimental/mini/tui/run.js.map +1 -0
- package/dist/experimental/mini/tui/session.d.ts +26 -0
- package/dist/experimental/mini/tui/session.d.ts.map +1 -0
- package/dist/experimental/mini/tui/session.js +94 -0
- package/dist/experimental/mini/tui/session.js.map +1 -0
- package/dist/experimental/mini/tui/view.d.ts +10 -0
- package/dist/experimental/mini/tui/view.d.ts.map +1 -0
- package/dist/experimental/mini/tui/view.js +459 -0
- package/dist/experimental/mini/tui/view.js.map +1 -0
- package/dist/experimental/mini/worker/entry.d.ts +3 -0
- package/dist/experimental/mini/worker/entry.d.ts.map +1 -0
- package/dist/experimental/mini/worker/entry.js +10 -0
- package/dist/experimental/mini/worker/entry.js.map +1 -0
- package/dist/experimental/mini/worker/lane-service.d.ts +44 -0
- package/dist/experimental/mini/worker/lane-service.d.ts.map +1 -0
- package/dist/experimental/mini/worker/lane-service.js +97 -0
- package/dist/experimental/mini/worker/lane-service.js.map +1 -0
- package/dist/experimental/mini/worker/models-service.d.ts +19 -0
- package/dist/experimental/mini/worker/models-service.d.ts.map +1 -0
- package/dist/experimental/mini/worker/models-service.js +136 -0
- package/dist/experimental/mini/worker/models-service.js.map +1 -0
- package/dist/experimental/mini/worker/run.d.ts +14 -0
- package/dist/experimental/mini/worker/run.d.ts.map +1 -0
- package/dist/experimental/mini/worker/run.js +88 -0
- package/dist/experimental/mini/worker/run.js.map +1 -0
- package/dist/experimental/plugin.d.ts +4 -0
- package/dist/experimental/plugin.d.ts.map +1 -0
- package/dist/experimental/plugin.js +4 -0
- package/dist/experimental/plugin.js.map +1 -0
- package/dist/experimental/plugins/bundled.d.ts +7 -0
- package/dist/experimental/plugins/bundled.d.ts.map +1 -0
- package/dist/experimental/plugins/bundled.js +48 -0
- package/dist/experimental/plugins/bundled.js.map +1 -0
- package/dist/experimental/plugins/package.d.ts +18 -0
- package/dist/experimental/plugins/package.d.ts.map +1 -0
- package/dist/experimental/plugins/package.js +113 -0
- package/dist/experimental/plugins/package.js.map +1 -0
- package/dist/experimental/process.d.ts +20 -0
- package/dist/experimental/process.d.ts.map +1 -0
- package/dist/experimental/process.js +85 -0
- package/dist/experimental/process.js.map +1 -0
- package/dist/experimental/radius-auth.d.ts +17 -0
- package/dist/experimental/radius-auth.d.ts.map +1 -0
- package/dist/experimental/radius-auth.js +52 -0
- package/dist/experimental/radius-auth.js.map +1 -0
- package/dist/experimental/radius-relay.d.ts +90 -0
- package/dist/experimental/radius-relay.d.ts.map +1 -0
- package/dist/experimental/radius-relay.js +582 -0
- package/dist/experimental/radius-relay.js.map +1 -0
- package/dist/experimental/server.d.ts +75 -0
- package/dist/experimental/server.d.ts.map +1 -0
- package/dist/experimental/server.js +682 -0
- package/dist/experimental/server.js.map +1 -0
- package/dist/experimental/services/agent-controller-provider.d.ts +4 -0
- package/dist/experimental/services/agent-controller-provider.d.ts.map +1 -0
- package/dist/experimental/services/agent-controller-provider.js +84 -0
- package/dist/experimental/services/agent-controller-provider.js.map +1 -0
- package/dist/experimental/services/agent-controller.d.ts +57 -0
- package/dist/experimental/services/agent-controller.d.ts.map +1 -0
- package/dist/experimental/services/agent-controller.js +3 -0
- package/dist/experimental/services/agent-controller.js.map +1 -0
- package/dist/experimental/services/connection.d.ts +40 -0
- package/dist/experimental/services/connection.d.ts.map +1 -0
- package/dist/experimental/services/connection.js +300 -0
- package/dist/experimental/services/connection.js.map +1 -0
- package/dist/experimental/services/models-provider.d.ts +16 -0
- package/dist/experimental/services/models-provider.d.ts.map +1 -0
- package/dist/experimental/services/models-provider.js +116 -0
- package/dist/experimental/services/models-provider.js.map +1 -0
- package/dist/experimental/services/models.d.ts +36 -0
- package/dist/experimental/services/models.d.ts.map +1 -0
- package/dist/experimental/services/models.js +3 -0
- package/dist/experimental/services/models.js.map +1 -0
- package/dist/experimental/services/plugins.d.ts +16 -0
- package/dist/experimental/services/plugins.d.ts.map +1 -0
- package/dist/experimental/services/plugins.js +4 -0
- package/dist/experimental/services/plugins.js.map +1 -0
- package/dist/experimental/services/presentation-ui.d.ts +13 -0
- package/dist/experimental/services/presentation-ui.d.ts.map +1 -0
- package/dist/experimental/services/presentation-ui.js +3 -0
- package/dist/experimental/services/presentation-ui.js.map +1 -0
- package/dist/experimental/services/server.d.ts +19 -0
- package/dist/experimental/services/server.d.ts.map +1 -0
- package/dist/experimental/services/server.js +104 -0
- package/dist/experimental/services/server.js.map +1 -0
- package/dist/experimental/services/sessions.d.ts +28 -0
- package/dist/experimental/services/sessions.d.ts.map +1 -0
- package/dist/experimental/services/sessions.js +4 -0
- package/dist/experimental/services/sessions.js.map +1 -0
- package/dist/experimental/services/slash-commands-provider.d.ts +14 -0
- package/dist/experimental/services/slash-commands-provider.d.ts.map +1 -0
- package/dist/experimental/services/slash-commands-provider.js +200 -0
- package/dist/experimental/services/slash-commands-provider.js.map +1 -0
- package/dist/experimental/services/slash-commands.d.ts +24 -0
- package/dist/experimental/services/slash-commands.d.ts.map +1 -0
- package/dist/experimental/services/slash-commands.js +3 -0
- package/dist/experimental/services/slash-commands.js.map +1 -0
- package/dist/experimental/services/transcript-provider.d.ts +12 -0
- package/dist/experimental/services/transcript-provider.d.ts.map +1 -0
- package/dist/experimental/services/transcript-provider.js +109 -0
- package/dist/experimental/services/transcript-provider.js.map +1 -0
- package/dist/experimental/services/transcript.d.ts +13 -0
- package/dist/experimental/services/transcript.d.ts.map +1 -0
- package/dist/experimental/services/transcript.js +3 -0
- package/dist/experimental/services/transcript.js.map +1 -0
- package/dist/experimental/services/worker.d.ts +28 -0
- package/dist/experimental/services/worker.d.ts.map +1 -0
- package/dist/experimental/services/worker.js +107 -0
- package/dist/experimental/services/worker.js.map +1 -0
- package/dist/experimental/session-worker-manager.d.ts +24 -0
- package/dist/experimental/session-worker-manager.d.ts.map +1 -0
- package/dist/experimental/session-worker-manager.js +691 -0
- package/dist/experimental/session-worker-manager.js.map +1 -0
- package/dist/experimental/session-worker.d.ts +188 -0
- package/dist/experimental/session-worker.d.ts.map +1 -0
- package/dist/experimental/session-worker.js +785 -0
- package/dist/experimental/session-worker.js.map +1 -0
- package/dist/experimental/source-resolver.d.ts +2 -0
- package/dist/experimental/source-resolver.d.ts.map +1 -0
- package/dist/experimental/source-resolver.js +71 -0
- package/dist/experimental/source-resolver.js.map +1 -0
- package/dist/extensions/llama/client.d.ts +6 -0
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +7 -0
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts +3 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +27 -6
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +128 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/chat-viewport.d.ts +20 -0
- package/dist/modes/interactive/chat-viewport.d.ts.map +1 -0
- package/dist/modes/interactive/chat-viewport.js +28 -0
- package/dist/modes/interactive/chat-viewport.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +18 -10
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +39 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +5 -14
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +13 -15
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +24 -10
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +10 -3
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +2 -2
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +35 -33
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js +2 -2
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +11 -14
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +140 -101
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts.map +1 -1
- package/dist/modes/interactive/session-share.js +8 -12
- package/dist/modes/interactive/session-share.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +2 -1
- package/dist/modes/interactive/theme/light.json +2 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +5 -0
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-json.d.ts +84 -0
- package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme-json.js +130 -0
- package/dist/modes/interactive/theme/theme-json.js.map +1 -0
- package/dist/modes/interactive/theme/theme-schema.json +6 -2
- package/dist/modes/interactive/theme/theme.d.ts +14 -5
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +18 -119
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/interactive/tui-renderer.d.ts +21 -0
- package/dist/modes/interactive/tui-renderer.d.ts.map +1 -0
- package/dist/modes/interactive/tui-renderer.js +66 -0
- package/dist/modes/interactive/tui-renderer.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +7 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +3 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +12 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js +2 -3
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +6 -4
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +41 -19
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/compaction.md +2 -0
- package/docs/custom-provider.md +7 -7
- package/docs/environment-variables.md +5 -0
- package/docs/extensions.md +23 -2
- package/docs/keybindings.md +4 -2
- package/docs/models.md +3 -0
- package/docs/quickstart.md +1 -1
- package/docs/rpc.md +24 -1
- package/docs/sdk.md +5 -0
- package/docs/settings.md +17 -9
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +27 -0
- package/docs/themes.md +8 -6
- package/docs/tui.md +20 -1
- package/docs/usage.md +4 -3
- package/examples/README.md +3 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/dynamic-resources/dynamic.json +2 -0
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/plugins/pi-example-plugin/README.md +38 -0
- package/examples/plugins/pi-example-plugin/package.json +10 -0
- package/examples/plugins/pi-example-plugin/src/contract.ts +13 -0
- package/examples/plugins/pi-example-plugin/src/session.ts +23 -0
- package/examples/plugins/pi-example-plugin/src/tui.ts +31 -0
- package/npm-shrinkwrap.json +523 -28
- package/package.json +12 -6
- package/dist/bun/register-bedrock.d.ts +0 -2
- package/dist/bun/register-bedrock.d.ts.map +0 -1
- package/dist/bun/register-bedrock.js +0 -4
- package/dist/bun/register-bedrock.js.map +0 -1
- package/dist/bundle/chunks/anthropic-messages-JWX2WP65.js +0 -45
- package/dist/bundle/chunks/chunk-E5KXRMZK.js +0 -1547
- package/dist/bundle/chunks/chunk-JUUC5AZY.js +0 -2
- package/dist/bundle/chunks/dist-RDWOYWHR.js +0 -13
- package/dist/bundle/chunks/openai-codex-responses-GJVBJXLB.js +0 -8
- package/dist/bundle/chunks/openai-completions-JD4WAC3R.js +0 -7
- package/dist/bundle/chunks/openai-responses-BSOJMSEV.js +0 -2
- package/dist/cli/experimental/auth.d.ts +0 -16
- package/dist/cli/experimental/auth.d.ts.map +0 -1
- package/dist/cli/experimental/auth.js +0 -13
- package/dist/cli/experimental/auth.js.map +0 -1
- package/dist/cli/experimental/commands/pi.d.ts +0 -15
- package/dist/cli/experimental/commands/pi.d.ts.map +0 -1
- package/dist/cli/experimental/commands/pi.js +0 -28
- package/dist/cli/experimental/commands/pi.js.map +0 -1
- package/dist/cli/experimental/transport-address.d.ts +0 -10
- package/dist/cli/experimental/transport-address.d.ts.map +0 -1
- package/dist/cli/experimental/transport-address.js +0 -38
- package/dist/cli/experimental/transport-address.js.map +0 -1
- package/dist/client/remote-session.d.ts +0 -53
- package/dist/client/remote-session.d.ts.map +0 -1
- package/dist/client/remote-session.js +0 -340
- package/dist/client/remote-session.js.map +0 -1
- package/dist/client/transcript.d.ts +0 -12
- package/dist/client/transcript.d.ts.map +0 -1
- package/dist/client/transcript.js +0 -98
- package/dist/client/transcript.js.map +0 -1
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -106
- package/dist/server/create-harness.js.map +0 -1
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { chmod, lstat, unlink } from "node:fs/promises";
|
|
3
|
+
import { createConnection, createServer } from "node:net";
|
|
4
|
+
import Type from "typebox";
|
|
5
|
+
import { Check } from "typebox/value";
|
|
6
|
+
import { consumeInternalProcessRole, encodeControlLine, isDirectInternalProcessEntry, MAX_CONTROL_LINE_BYTES, spawnInternalProcess, } from "./process.js";
|
|
7
|
+
export const COORDINATOR_PROTOCOL_VERSION = 3;
|
|
8
|
+
const COORDINATOR_START_TIMEOUT_MS = 10_000;
|
|
9
|
+
const COORDINATOR_RETRY_MS = 10;
|
|
10
|
+
const CoordinatorMessageSchema = Type.Union([
|
|
11
|
+
Type.Object({
|
|
12
|
+
type: Type.Literal("server_registered"),
|
|
13
|
+
serverConnectionId: Type.String(),
|
|
14
|
+
peers: Type.Array(Type.String()),
|
|
15
|
+
}),
|
|
16
|
+
Type.Object({ type: Type.Literal("server_replaced") }),
|
|
17
|
+
Type.Object({ type: Type.Literal("peer_connected"), peerId: Type.String() }),
|
|
18
|
+
Type.Object({ type: Type.Literal("peer_disconnected"), peerId: Type.String() }),
|
|
19
|
+
Type.Object({ type: Type.Literal("message"), from: Type.String(), payload: Type.Unknown() }),
|
|
20
|
+
]);
|
|
21
|
+
/** The server-side endpoint of the coordinator's intentionally opaque message router. */
|
|
22
|
+
export class CoordinatorConnection {
|
|
23
|
+
serverConnectionId;
|
|
24
|
+
replaced;
|
|
25
|
+
peerIds = new Set();
|
|
26
|
+
#controlPath;
|
|
27
|
+
#endpoint;
|
|
28
|
+
#listeners = new Set();
|
|
29
|
+
#socket;
|
|
30
|
+
#registered = false;
|
|
31
|
+
#closed = false;
|
|
32
|
+
#replacedValue = false;
|
|
33
|
+
#resolveRegistered;
|
|
34
|
+
#rejectRegistered;
|
|
35
|
+
#resolveReplaced;
|
|
36
|
+
constructor(options) {
|
|
37
|
+
this.serverConnectionId = options.serverConnectionId ?? randomUUID();
|
|
38
|
+
this.#controlPath = options.controlPath;
|
|
39
|
+
this.#endpoint = options.endpoint;
|
|
40
|
+
this.replaced = new Promise((resolve) => {
|
|
41
|
+
this.#resolveReplaced = resolve;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
get controlPath() {
|
|
45
|
+
return this.#controlPath;
|
|
46
|
+
}
|
|
47
|
+
get wasReplaced() {
|
|
48
|
+
return this.#replacedValue;
|
|
49
|
+
}
|
|
50
|
+
onEvent(listener) {
|
|
51
|
+
this.#listeners.add(listener);
|
|
52
|
+
return () => this.#listeners.delete(listener);
|
|
53
|
+
}
|
|
54
|
+
async connect() {
|
|
55
|
+
if (this.#socket)
|
|
56
|
+
throw new Error("Coordinator server is already connected");
|
|
57
|
+
const socket = await connectSocket(this.#controlPath);
|
|
58
|
+
this.#socket = socket;
|
|
59
|
+
attachJsonLineReader(socket, (message) => this.#handleMessage(message));
|
|
60
|
+
const registered = new Promise((resolve, reject) => {
|
|
61
|
+
this.#resolveRegistered = resolve;
|
|
62
|
+
this.#rejectRegistered = reject;
|
|
63
|
+
});
|
|
64
|
+
socket.once("close", () => this.#disconnected(new Error("Coordinator connection closed")));
|
|
65
|
+
socket.once("error", (error) => this.#disconnected(error));
|
|
66
|
+
await writeJsonLine(socket, {
|
|
67
|
+
type: "register_server",
|
|
68
|
+
protocol: COORDINATOR_PROTOCOL_VERSION,
|
|
69
|
+
serverConnectionId: this.serverConnectionId,
|
|
70
|
+
endpoint: this.#endpoint,
|
|
71
|
+
});
|
|
72
|
+
await registered;
|
|
73
|
+
}
|
|
74
|
+
send(peerId, payload) {
|
|
75
|
+
return this.#write({ type: "send", to: peerId, payload });
|
|
76
|
+
}
|
|
77
|
+
broadcast(payload) {
|
|
78
|
+
return this.#write({ type: "broadcast", payload });
|
|
79
|
+
}
|
|
80
|
+
close() {
|
|
81
|
+
if (this.#closed)
|
|
82
|
+
return;
|
|
83
|
+
this.#closed = true;
|
|
84
|
+
this.#socket?.destroy();
|
|
85
|
+
this.#socket = undefined;
|
|
86
|
+
this.peerIds.clear();
|
|
87
|
+
this.#rejectRegistered?.(new Error("Coordinator server closed"));
|
|
88
|
+
this.#resolveRegistered = undefined;
|
|
89
|
+
this.#rejectRegistered = undefined;
|
|
90
|
+
}
|
|
91
|
+
async #write(message) {
|
|
92
|
+
if (!this.#registered || !this.#socket || this.#closed)
|
|
93
|
+
throw new Error("Coordinator server is not connected");
|
|
94
|
+
await writeJsonLine(this.#socket, message);
|
|
95
|
+
}
|
|
96
|
+
#handleMessage(value) {
|
|
97
|
+
if (!Check(CoordinatorMessageSchema, value)) {
|
|
98
|
+
this.#socket?.destroy(new Error("Coordinator sent an invalid message"));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const message = value;
|
|
102
|
+
if (message.type === "server_registered") {
|
|
103
|
+
if (message.serverConnectionId !== this.serverConnectionId) {
|
|
104
|
+
this.#socket?.destroy(new Error("Coordinator returned an invalid server registration"));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
for (const peerId of message.peers)
|
|
108
|
+
this.peerIds.add(peerId);
|
|
109
|
+
this.#registered = true;
|
|
110
|
+
this.#resolveRegistered?.();
|
|
111
|
+
this.#resolveRegistered = undefined;
|
|
112
|
+
this.#rejectRegistered = undefined;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (message.type === "server_replaced") {
|
|
116
|
+
this.#markReplaced();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (message.type === "peer_connected") {
|
|
120
|
+
this.peerIds.add(message.peerId);
|
|
121
|
+
this.#emit({ type: "peer_connected", peerId: message.peerId });
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (message.type === "peer_disconnected") {
|
|
125
|
+
this.peerIds.delete(message.peerId);
|
|
126
|
+
this.#emit({ type: "peer_disconnected", peerId: message.peerId });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (message.type === "message") {
|
|
130
|
+
this.#emit({ type: "message", from: message.from, payload: message.payload });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
this.#socket?.destroy(new Error("Coordinator sent an unsupported message"));
|
|
134
|
+
}
|
|
135
|
+
#emit(event) {
|
|
136
|
+
for (const listener of this.#listeners)
|
|
137
|
+
listener(event);
|
|
138
|
+
}
|
|
139
|
+
#disconnected(error) {
|
|
140
|
+
this.#socket = undefined;
|
|
141
|
+
if (this.#closed)
|
|
142
|
+
return;
|
|
143
|
+
this.#rejectRegistered?.(error);
|
|
144
|
+
this.#resolveRegistered = undefined;
|
|
145
|
+
this.#rejectRegistered = undefined;
|
|
146
|
+
this.#markReplaced();
|
|
147
|
+
}
|
|
148
|
+
#markReplaced() {
|
|
149
|
+
if (this.#replacedValue)
|
|
150
|
+
return;
|
|
151
|
+
this.#replacedValue = true;
|
|
152
|
+
this.#resolveReplaced();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export async function ensureCoordinator(publicPath, controlPath) {
|
|
156
|
+
const existing = await tryConnect(controlPath);
|
|
157
|
+
if (existing)
|
|
158
|
+
return { close: () => existing.destroy() };
|
|
159
|
+
const child = spawnInternalProcess("coordinator", [publicPath, controlPath]);
|
|
160
|
+
const deadline = Date.now() + COORDINATOR_START_TIMEOUT_MS;
|
|
161
|
+
while (true) {
|
|
162
|
+
const socket = await tryConnect(controlPath);
|
|
163
|
+
if (socket)
|
|
164
|
+
return { close: () => socket.destroy() };
|
|
165
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
166
|
+
throw new Error("Coordinator exited during startup");
|
|
167
|
+
if (Date.now() >= deadline)
|
|
168
|
+
throw new Error("Timed out waiting for coordinator startup");
|
|
169
|
+
await new Promise((resolve) => setTimeout(resolve, COORDINATOR_RETRY_MS));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function connectSocket(path) {
|
|
173
|
+
return new Promise((resolve, reject) => {
|
|
174
|
+
const socket = createConnection(path);
|
|
175
|
+
const onConnect = () => {
|
|
176
|
+
socket.off("error", onError);
|
|
177
|
+
resolve(socket);
|
|
178
|
+
};
|
|
179
|
+
const onError = (error) => {
|
|
180
|
+
socket.off("connect", onConnect);
|
|
181
|
+
reject(error);
|
|
182
|
+
};
|
|
183
|
+
socket.once("connect", onConnect);
|
|
184
|
+
socket.once("error", onError);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
async function tryConnect(path) {
|
|
188
|
+
try {
|
|
189
|
+
return await connectSocket(path);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
const code = error instanceof Error && "code" in error ? error.code : undefined;
|
|
193
|
+
if (code === "ENOENT" || code === "ECONNREFUSED")
|
|
194
|
+
return undefined;
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function attachJsonLineReader(socket, onMessage) {
|
|
199
|
+
let buffered = "";
|
|
200
|
+
socket.setEncoding("utf8");
|
|
201
|
+
socket.on("data", (chunk) => {
|
|
202
|
+
buffered += chunk;
|
|
203
|
+
if (Buffer.byteLength(buffered) > MAX_CONTROL_LINE_BYTES) {
|
|
204
|
+
socket.destroy(new Error("Coordinator message is too large"));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
while (true) {
|
|
208
|
+
const newline = buffered.indexOf("\n");
|
|
209
|
+
if (newline === -1)
|
|
210
|
+
return;
|
|
211
|
+
const line = buffered.slice(0, newline);
|
|
212
|
+
buffered = buffered.slice(newline + 1);
|
|
213
|
+
try {
|
|
214
|
+
onMessage(JSON.parse(line));
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
socket.destroy(new Error("Coordinator sent invalid JSON"));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
function writeJsonLine(socket, message) {
|
|
224
|
+
return new Promise((resolve, reject) => {
|
|
225
|
+
socket.write(encodeControlLine(message), (error) => {
|
|
226
|
+
if (error)
|
|
227
|
+
reject(error);
|
|
228
|
+
else
|
|
229
|
+
resolve();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
// This process is intentionally a transport shim. It depends only on Node
|
|
234
|
+
// built-ins and never interprets Pi, session, worker, or lifecycle payloads.
|
|
235
|
+
const EMPTY_STARTUP_GRACE_MS = 30_000;
|
|
236
|
+
const EMPTY_SHUTDOWN_GRACE_MS = 250;
|
|
237
|
+
let publicPath;
|
|
238
|
+
let controlPath;
|
|
239
|
+
let running = false;
|
|
240
|
+
const peers = new Map();
|
|
241
|
+
const controlConnections = new Set();
|
|
242
|
+
const publicConnections = new Map();
|
|
243
|
+
let currentServer;
|
|
244
|
+
let shuttingDown = false;
|
|
245
|
+
let emptyTimer;
|
|
246
|
+
const publicServer = createServer((socket) => acceptPublicConnection(socket));
|
|
247
|
+
const controlServer = createServer((socket) => acceptControlConnection(socket));
|
|
248
|
+
export async function runCoordinatorProcess(args) {
|
|
249
|
+
if (running)
|
|
250
|
+
throw new Error("Coordinator process is already running");
|
|
251
|
+
const [requestedPublicPath, requestedControlPath] = args;
|
|
252
|
+
if (!requestedPublicPath || !requestedControlPath) {
|
|
253
|
+
throw new Error("Coordinator requires public and control socket paths");
|
|
254
|
+
}
|
|
255
|
+
publicPath = requestedPublicPath;
|
|
256
|
+
controlPath = requestedControlPath;
|
|
257
|
+
running = true;
|
|
258
|
+
process.once("SIGINT", () => void shutdownCoordinator());
|
|
259
|
+
process.once("SIGTERM", () => void shutdownCoordinator());
|
|
260
|
+
await main();
|
|
261
|
+
}
|
|
262
|
+
async function main() {
|
|
263
|
+
await removeStaleSocket(controlPath);
|
|
264
|
+
await removeStaleSocket(publicPath);
|
|
265
|
+
try {
|
|
266
|
+
await listen(controlServer, controlPath);
|
|
267
|
+
await restrictSocket(controlPath);
|
|
268
|
+
await listen(publicServer, publicPath);
|
|
269
|
+
await restrictSocket(publicPath);
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
await Promise.all([cleanupSocket(controlPath), cleanupSocket(publicPath)]);
|
|
273
|
+
throw error;
|
|
274
|
+
}
|
|
275
|
+
scheduleEmptyShutdown(EMPTY_STARTUP_GRACE_MS);
|
|
276
|
+
}
|
|
277
|
+
function acceptControlConnection(socket) {
|
|
278
|
+
if (shuttingDown) {
|
|
279
|
+
socket.destroy();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
controlConnections.add(socket);
|
|
283
|
+
let server;
|
|
284
|
+
let peer;
|
|
285
|
+
attachRoutedLineReader(socket, (message) => {
|
|
286
|
+
if (!server && !peer) {
|
|
287
|
+
if (message.type === "register_server") {
|
|
288
|
+
server = registerServer(socket, message);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (message.type === "register_peer") {
|
|
292
|
+
peer = registerPeer(socket, message);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
throw new Error("Coordinator connection did not register a role");
|
|
296
|
+
}
|
|
297
|
+
if (server) {
|
|
298
|
+
if (server === currentServer)
|
|
299
|
+
handleRoutedMessage("server", message);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
handleRoutedMessage(peer.peerId, message);
|
|
303
|
+
});
|
|
304
|
+
const disconnect = () => {
|
|
305
|
+
controlConnections.delete(socket);
|
|
306
|
+
if (server && currentServer === server) {
|
|
307
|
+
currentServer = undefined;
|
|
308
|
+
notifyPeers({ type: "server_disconnected", serverConnectionId: server.serverConnectionId });
|
|
309
|
+
}
|
|
310
|
+
if (peer && peers.get(peer.peerId) === peer) {
|
|
311
|
+
peers.delete(peer.peerId);
|
|
312
|
+
if (currentServer)
|
|
313
|
+
writeRoutedLine(currentServer.socket, { type: "peer_disconnected", peerId: peer.peerId });
|
|
314
|
+
}
|
|
315
|
+
checkEmpty();
|
|
316
|
+
};
|
|
317
|
+
socket.once("close", disconnect);
|
|
318
|
+
socket.once("error", () => socket.destroy());
|
|
319
|
+
}
|
|
320
|
+
function registerServer(socket, message) {
|
|
321
|
+
if (message.protocol !== COORDINATOR_PROTOCOL_VERSION)
|
|
322
|
+
throw new Error("Unsupported coordinator protocol");
|
|
323
|
+
if (typeof message.serverConnectionId !== "string" || message.serverConnectionId.length === 0) {
|
|
324
|
+
throw new Error("Coordinator serverConnectionId must be a string");
|
|
325
|
+
}
|
|
326
|
+
if (typeof message.endpoint !== "string" || message.endpoint.length === 0) {
|
|
327
|
+
throw new Error("Coordinator endpoint must be a string");
|
|
328
|
+
}
|
|
329
|
+
const { serverConnectionId, endpoint } = message;
|
|
330
|
+
const server = { serverConnectionId, endpoint, socket };
|
|
331
|
+
const previous = currentServer;
|
|
332
|
+
currentServer = server;
|
|
333
|
+
cancelEmptyShutdown();
|
|
334
|
+
writeRoutedLine(socket, {
|
|
335
|
+
type: "server_registered",
|
|
336
|
+
serverConnectionId,
|
|
337
|
+
peers: [...peers.keys()],
|
|
338
|
+
});
|
|
339
|
+
if (previous && previous !== server) {
|
|
340
|
+
closePublicConnections();
|
|
341
|
+
notifyPeers({ type: "server_disconnected", serverConnectionId: previous.serverConnectionId });
|
|
342
|
+
writeRoutedLine(previous.socket, { type: "server_replaced" });
|
|
343
|
+
}
|
|
344
|
+
notifyPeers({ type: "server_connected", serverConnectionId });
|
|
345
|
+
return server;
|
|
346
|
+
}
|
|
347
|
+
function registerPeer(socket, message) {
|
|
348
|
+
if (message.protocol !== COORDINATOR_PROTOCOL_VERSION)
|
|
349
|
+
throw new Error("Unsupported coordinator protocol");
|
|
350
|
+
if (typeof message.peerId !== "string" || message.peerId.length === 0) {
|
|
351
|
+
throw new Error("Coordinator peerId must be a string");
|
|
352
|
+
}
|
|
353
|
+
const { peerId } = message;
|
|
354
|
+
if (peerId === "server" || peers.has(peerId))
|
|
355
|
+
throw new Error(`Coordinator peer is already connected: ${peerId}`);
|
|
356
|
+
const peer = { peerId, socket };
|
|
357
|
+
peers.set(peerId, peer);
|
|
358
|
+
cancelEmptyShutdown();
|
|
359
|
+
writeRoutedLine(socket, {
|
|
360
|
+
type: "peer_registered",
|
|
361
|
+
peerId,
|
|
362
|
+
...(currentServer === undefined ? {} : { serverConnectionId: currentServer.serverConnectionId }),
|
|
363
|
+
});
|
|
364
|
+
if (currentServer) {
|
|
365
|
+
writeRoutedLine(currentServer.socket, { type: "peer_connected", peerId });
|
|
366
|
+
}
|
|
367
|
+
return peer;
|
|
368
|
+
}
|
|
369
|
+
function notifyPeers(message) {
|
|
370
|
+
for (const peer of peers.values())
|
|
371
|
+
writeRoutedLine(peer.socket, message);
|
|
372
|
+
}
|
|
373
|
+
function handleRoutedMessage(from, message) {
|
|
374
|
+
if (message.type === "send") {
|
|
375
|
+
if (typeof message.to !== "string" || message.to.length === 0) {
|
|
376
|
+
throw new Error("Coordinator message target must be a string");
|
|
377
|
+
}
|
|
378
|
+
const { to } = message;
|
|
379
|
+
const target = to === "server" ? currentServer?.socket : peers.get(to)?.socket;
|
|
380
|
+
if (target)
|
|
381
|
+
writeRoutedLine(target, { type: "message", from, payload: message.payload });
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (message.type === "broadcast") {
|
|
385
|
+
if (from !== "server")
|
|
386
|
+
throw new Error("Only the current server may broadcast");
|
|
387
|
+
for (const peer of peers.values()) {
|
|
388
|
+
writeRoutedLine(peer.socket, { type: "message", from, payload: message.payload });
|
|
389
|
+
}
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
throw new Error(`Unknown coordinator routing message: ${message.type}`);
|
|
393
|
+
}
|
|
394
|
+
function acceptPublicConnection(client) {
|
|
395
|
+
if (shuttingDown || !currentServer) {
|
|
396
|
+
client.destroy();
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
cancelEmptyShutdown();
|
|
400
|
+
const upstream = createConnection(currentServer.endpoint);
|
|
401
|
+
publicConnections.set(client, upstream);
|
|
402
|
+
let finalized = false;
|
|
403
|
+
const finalize = () => {
|
|
404
|
+
if (finalized)
|
|
405
|
+
return;
|
|
406
|
+
finalized = true;
|
|
407
|
+
publicConnections.delete(client);
|
|
408
|
+
checkEmpty();
|
|
409
|
+
};
|
|
410
|
+
upstream.once("connect", () => {
|
|
411
|
+
client.pipe(upstream);
|
|
412
|
+
upstream.pipe(client);
|
|
413
|
+
});
|
|
414
|
+
upstream.once("error", () => client.destroy());
|
|
415
|
+
upstream.once("close", () => {
|
|
416
|
+
client.destroy();
|
|
417
|
+
finalize();
|
|
418
|
+
});
|
|
419
|
+
client.once("error", () => upstream.destroy());
|
|
420
|
+
client.once("close", () => {
|
|
421
|
+
upstream.destroy();
|
|
422
|
+
finalize();
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
function closePublicConnections() {
|
|
426
|
+
for (const [client, upstream] of publicConnections) {
|
|
427
|
+
client.destroy();
|
|
428
|
+
upstream.destroy();
|
|
429
|
+
}
|
|
430
|
+
publicConnections.clear();
|
|
431
|
+
}
|
|
432
|
+
function checkEmpty() {
|
|
433
|
+
if (shuttingDown || currentServer || peers.size > 0 || publicConnections.size > 0 || controlConnections.size > 0) {
|
|
434
|
+
cancelEmptyShutdown();
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
scheduleEmptyShutdown(EMPTY_SHUTDOWN_GRACE_MS);
|
|
438
|
+
}
|
|
439
|
+
function scheduleEmptyShutdown(delayMs) {
|
|
440
|
+
if (emptyTimer || shuttingDown)
|
|
441
|
+
return;
|
|
442
|
+
emptyTimer = setTimeout(() => {
|
|
443
|
+
emptyTimer = undefined;
|
|
444
|
+
if (!currentServer && peers.size === 0 && publicConnections.size === 0 && controlConnections.size === 0) {
|
|
445
|
+
void shutdownCoordinator();
|
|
446
|
+
}
|
|
447
|
+
}, delayMs);
|
|
448
|
+
emptyTimer.unref();
|
|
449
|
+
}
|
|
450
|
+
function cancelEmptyShutdown() {
|
|
451
|
+
if (!emptyTimer)
|
|
452
|
+
return;
|
|
453
|
+
clearTimeout(emptyTimer);
|
|
454
|
+
emptyTimer = undefined;
|
|
455
|
+
}
|
|
456
|
+
async function shutdownCoordinator() {
|
|
457
|
+
if (shuttingDown)
|
|
458
|
+
return;
|
|
459
|
+
shuttingDown = true;
|
|
460
|
+
cancelEmptyShutdown();
|
|
461
|
+
closePublicConnections();
|
|
462
|
+
for (const connection of controlConnections)
|
|
463
|
+
connection.destroy();
|
|
464
|
+
await Promise.all([closeServer(publicServer), closeServer(controlServer)]);
|
|
465
|
+
await Promise.all([cleanupSocket(publicPath), cleanupSocket(controlPath)]);
|
|
466
|
+
process.exit(0);
|
|
467
|
+
}
|
|
468
|
+
function writeRoutedLine(socket, message) {
|
|
469
|
+
if (!socket.destroyed)
|
|
470
|
+
socket.write(encodeControlLine(message));
|
|
471
|
+
}
|
|
472
|
+
function attachRoutedLineReader(socket, onMessage) {
|
|
473
|
+
let buffered = "";
|
|
474
|
+
socket.setEncoding("utf8");
|
|
475
|
+
socket.on("data", (chunk) => {
|
|
476
|
+
buffered += chunk;
|
|
477
|
+
if (Buffer.byteLength(buffered) > MAX_CONTROL_LINE_BYTES) {
|
|
478
|
+
socket.destroy(new Error("Coordinator message is too large"));
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
while (true) {
|
|
482
|
+
const newline = buffered.indexOf("\n");
|
|
483
|
+
if (newline === -1)
|
|
484
|
+
return;
|
|
485
|
+
const line = buffered.slice(0, newline);
|
|
486
|
+
buffered = buffered.slice(newline + 1);
|
|
487
|
+
try {
|
|
488
|
+
const message = JSON.parse(line);
|
|
489
|
+
if (typeof message?.type !== "string")
|
|
490
|
+
throw new Error("Coordinator message must have a type");
|
|
491
|
+
onMessage(message);
|
|
492
|
+
}
|
|
493
|
+
catch (error) {
|
|
494
|
+
socket.destroy(error instanceof Error ? error : new Error(String(error)));
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
function listen(server, path) {
|
|
501
|
+
return new Promise((resolve, reject) => {
|
|
502
|
+
const onError = (error) => {
|
|
503
|
+
server.off("listening", onListening);
|
|
504
|
+
reject(error);
|
|
505
|
+
};
|
|
506
|
+
const onListening = () => {
|
|
507
|
+
server.off("error", onError);
|
|
508
|
+
resolve();
|
|
509
|
+
};
|
|
510
|
+
server.once("error", onError);
|
|
511
|
+
server.once("listening", onListening);
|
|
512
|
+
server.listen(path);
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
function closeServer(server) {
|
|
516
|
+
if (!server.listening)
|
|
517
|
+
return Promise.resolve();
|
|
518
|
+
return new Promise((resolve) => server.close(() => resolve()));
|
|
519
|
+
}
|
|
520
|
+
async function restrictSocket(path) {
|
|
521
|
+
if (process.platform !== "win32")
|
|
522
|
+
await chmod(path, 0o600);
|
|
523
|
+
}
|
|
524
|
+
async function removeStaleSocket(path) {
|
|
525
|
+
try {
|
|
526
|
+
const stats = await lstat(path);
|
|
527
|
+
if (!stats.isSocket())
|
|
528
|
+
throw new Error(`Coordinator path is not a socket: ${path}`);
|
|
529
|
+
}
|
|
530
|
+
catch (error) {
|
|
531
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
532
|
+
return;
|
|
533
|
+
throw error;
|
|
534
|
+
}
|
|
535
|
+
const live = await new Promise((resolve, reject) => {
|
|
536
|
+
const socket = createConnection(path);
|
|
537
|
+
socket.once("connect", () => {
|
|
538
|
+
socket.destroy();
|
|
539
|
+
resolve(true);
|
|
540
|
+
});
|
|
541
|
+
socket.once("error", (error) => {
|
|
542
|
+
socket.destroy();
|
|
543
|
+
if (error.code === "ECONNREFUSED" || error.code === "ENOENT")
|
|
544
|
+
resolve(false);
|
|
545
|
+
else
|
|
546
|
+
reject(error);
|
|
547
|
+
});
|
|
548
|
+
});
|
|
549
|
+
if (live)
|
|
550
|
+
throw new Error(`Coordinator socket is already active: ${path}`);
|
|
551
|
+
await cleanupSocket(path);
|
|
552
|
+
}
|
|
553
|
+
async function cleanupSocket(path) {
|
|
554
|
+
if (process.platform === "win32")
|
|
555
|
+
return;
|
|
556
|
+
await unlink(path).catch((error) => {
|
|
557
|
+
if (!(error instanceof Error && "code" in error && error.code === "ENOENT"))
|
|
558
|
+
throw error;
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
if (isDirectInternalProcessEntry(import.meta.url)) {
|
|
562
|
+
const role = consumeInternalProcessRole();
|
|
563
|
+
if (role !== "coordinator")
|
|
564
|
+
throw new Error("Coordinator entrypoint requires an internal coordinator invocation");
|
|
565
|
+
void runCoordinatorProcess(process.argv.slice(2)).catch((error) => {
|
|
566
|
+
console.error(error);
|
|
567
|
+
process.exit(1);
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
//# sourceMappingURL=coordinator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../src/experimental/coordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { chmod, lstat, unlink } from \"node:fs/promises\";\nimport { createConnection, createServer, type Server, type Socket } from \"node:net\";\nimport Type, { type Static } from \"typebox\";\nimport { Check } from \"typebox/value\";\nimport {\n\tconsumeInternalProcessRole,\n\tencodeControlLine,\n\tisDirectInternalProcessEntry,\n\tMAX_CONTROL_LINE_BYTES,\n\tspawnInternalProcess,\n} from \"./process.ts\";\n\nexport const COORDINATOR_PROTOCOL_VERSION = 3;\nconst COORDINATOR_START_TIMEOUT_MS = 10_000;\nconst COORDINATOR_RETRY_MS = 10;\n\nconst CoordinatorMessageSchema = Type.Union([\n\tType.Object({\n\t\ttype: Type.Literal(\"server_registered\"),\n\t\tserverConnectionId: Type.String(),\n\t\tpeers: Type.Array(Type.String()),\n\t}),\n\tType.Object({ type: Type.Literal(\"server_replaced\") }),\n\tType.Object({ type: Type.Literal(\"peer_connected\"), peerId: Type.String() }),\n\tType.Object({ type: Type.Literal(\"peer_disconnected\"), peerId: Type.String() }),\n\tType.Object({ type: Type.Literal(\"message\"), from: Type.String(), payload: Type.Unknown() }),\n]);\ntype CoordinatorMessage = Static<typeof CoordinatorMessageSchema>;\n\nexport type CoordinatorConnectionEvent =\n\t| { readonly type: \"peer_connected\"; readonly peerId: string }\n\t| { readonly type: \"peer_disconnected\"; readonly peerId: string }\n\t| { readonly type: \"message\"; readonly from: string; readonly payload: unknown };\n\nexport interface CoordinatorConnectionOptions {\n\treadonly controlPath: string;\n\treadonly endpoint: string;\n\treadonly serverConnectionId?: string;\n}\n\n/** The server-side endpoint of the coordinator's intentionally opaque message router. */\nexport class CoordinatorConnection {\n\treadonly serverConnectionId: string;\n\treadonly replaced: Promise<void>;\n\treadonly peerIds = new Set<string>();\n\treadonly #controlPath: string;\n\treadonly #endpoint: string;\n\treadonly #listeners = new Set<(event: CoordinatorConnectionEvent) => void>();\n\t#socket?: Socket;\n\t#registered = false;\n\t#closed = false;\n\t#replacedValue = false;\n\t#resolveRegistered?: () => void;\n\t#rejectRegistered?: (error: Error) => void;\n\t#resolveReplaced!: () => void;\n\n\tconstructor(options: CoordinatorConnectionOptions) {\n\t\tthis.serverConnectionId = options.serverConnectionId ?? randomUUID();\n\t\tthis.#controlPath = options.controlPath;\n\t\tthis.#endpoint = options.endpoint;\n\t\tthis.replaced = new Promise((resolve) => {\n\t\t\tthis.#resolveReplaced = resolve;\n\t\t});\n\t}\n\n\tget controlPath(): string {\n\t\treturn this.#controlPath;\n\t}\n\n\tget wasReplaced(): boolean {\n\t\treturn this.#replacedValue;\n\t}\n\n\tonEvent(listener: (event: CoordinatorConnectionEvent) => void): () => void {\n\t\tthis.#listeners.add(listener);\n\t\treturn () => this.#listeners.delete(listener);\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tif (this.#socket) throw new Error(\"Coordinator server is already connected\");\n\t\tconst socket = await connectSocket(this.#controlPath);\n\t\tthis.#socket = socket;\n\t\tattachJsonLineReader(socket, (message) => this.#handleMessage(message));\n\t\tconst registered = new Promise<void>((resolve, reject) => {\n\t\t\tthis.#resolveRegistered = resolve;\n\t\t\tthis.#rejectRegistered = reject;\n\t\t});\n\t\tsocket.once(\"close\", () => this.#disconnected(new Error(\"Coordinator connection closed\")));\n\t\tsocket.once(\"error\", (error) => this.#disconnected(error));\n\t\tawait writeJsonLine(socket, {\n\t\t\ttype: \"register_server\",\n\t\t\tprotocol: COORDINATOR_PROTOCOL_VERSION,\n\t\t\tserverConnectionId: this.serverConnectionId,\n\t\t\tendpoint: this.#endpoint,\n\t\t});\n\t\tawait registered;\n\t}\n\n\tsend(peerId: string, payload: unknown): Promise<void> {\n\t\treturn this.#write({ type: \"send\", to: peerId, payload });\n\t}\n\n\tbroadcast(payload: unknown): Promise<void> {\n\t\treturn this.#write({ type: \"broadcast\", payload });\n\t}\n\n\tclose(): void {\n\t\tif (this.#closed) return;\n\t\tthis.#closed = true;\n\t\tthis.#socket?.destroy();\n\t\tthis.#socket = undefined;\n\t\tthis.peerIds.clear();\n\t\tthis.#rejectRegistered?.(new Error(\"Coordinator server closed\"));\n\t\tthis.#resolveRegistered = undefined;\n\t\tthis.#rejectRegistered = undefined;\n\t}\n\n\tasync #write(message: unknown): Promise<void> {\n\t\tif (!this.#registered || !this.#socket || this.#closed) throw new Error(\"Coordinator server is not connected\");\n\t\tawait writeJsonLine(this.#socket, message);\n\t}\n\n\t#handleMessage(value: unknown): void {\n\t\tif (!Check(CoordinatorMessageSchema, value)) {\n\t\t\tthis.#socket?.destroy(new Error(\"Coordinator sent an invalid message\"));\n\t\t\treturn;\n\t\t}\n\t\tconst message: CoordinatorMessage = value;\n\t\tif (message.type === \"server_registered\") {\n\t\t\tif (message.serverConnectionId !== this.serverConnectionId) {\n\t\t\t\tthis.#socket?.destroy(new Error(\"Coordinator returned an invalid server registration\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const peerId of message.peers) this.peerIds.add(peerId);\n\t\t\tthis.#registered = true;\n\t\t\tthis.#resolveRegistered?.();\n\t\t\tthis.#resolveRegistered = undefined;\n\t\t\tthis.#rejectRegistered = undefined;\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"server_replaced\") {\n\t\t\tthis.#markReplaced();\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"peer_connected\") {\n\t\t\tthis.peerIds.add(message.peerId);\n\t\t\tthis.#emit({ type: \"peer_connected\", peerId: message.peerId });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"peer_disconnected\") {\n\t\t\tthis.peerIds.delete(message.peerId);\n\t\t\tthis.#emit({ type: \"peer_disconnected\", peerId: message.peerId });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"message\") {\n\t\t\tthis.#emit({ type: \"message\", from: message.from, payload: message.payload });\n\t\t\treturn;\n\t\t}\n\t\tthis.#socket?.destroy(new Error(\"Coordinator sent an unsupported message\"));\n\t}\n\n\t#emit(event: CoordinatorConnectionEvent): void {\n\t\tfor (const listener of this.#listeners) listener(event);\n\t}\n\n\t#disconnected(error: Error): void {\n\t\tthis.#socket = undefined;\n\t\tif (this.#closed) return;\n\t\tthis.#rejectRegistered?.(error);\n\t\tthis.#resolveRegistered = undefined;\n\t\tthis.#rejectRegistered = undefined;\n\t\tthis.#markReplaced();\n\t}\n\n\t#markReplaced(): void {\n\t\tif (this.#replacedValue) return;\n\t\tthis.#replacedValue = true;\n\t\tthis.#resolveReplaced();\n\t}\n}\n\nexport interface CoordinatorStartupLease {\n\tclose(): void;\n}\n\nexport async function ensureCoordinator(publicPath: string, controlPath: string): Promise<CoordinatorStartupLease> {\n\tconst existing = await tryConnect(controlPath);\n\tif (existing) return { close: () => existing.destroy() };\n\tconst child = spawnInternalProcess(\"coordinator\", [publicPath, controlPath]);\n\tconst deadline = Date.now() + COORDINATOR_START_TIMEOUT_MS;\n\twhile (true) {\n\t\tconst socket = await tryConnect(controlPath);\n\t\tif (socket) return { close: () => socket.destroy() };\n\t\tif (child.exitCode !== null || child.signalCode !== null) throw new Error(\"Coordinator exited during startup\");\n\t\tif (Date.now() >= deadline) throw new Error(\"Timed out waiting for coordinator startup\");\n\t\tawait new Promise<void>((resolve) => setTimeout(resolve, COORDINATOR_RETRY_MS));\n\t}\n}\n\nfunction connectSocket(path: string): Promise<Socket> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst socket = createConnection(path);\n\t\tconst onConnect = (): void => {\n\t\t\tsocket.off(\"error\", onError);\n\t\t\tresolve(socket);\n\t\t};\n\t\tconst onError = (error: Error): void => {\n\t\t\tsocket.off(\"connect\", onConnect);\n\t\t\treject(error);\n\t\t};\n\t\tsocket.once(\"connect\", onConnect);\n\t\tsocket.once(\"error\", onError);\n\t});\n}\n\nasync function tryConnect(path: string): Promise<Socket | undefined> {\n\ttry {\n\t\treturn await connectSocket(path);\n\t} catch (error) {\n\t\tconst code = error instanceof Error && \"code\" in error ? error.code : undefined;\n\t\tif (code === \"ENOENT\" || code === \"ECONNREFUSED\") return undefined;\n\t\tthrow error;\n\t}\n}\n\nfunction attachJsonLineReader(socket: Socket, onMessage: (message: unknown) => void): void {\n\tlet buffered = \"\";\n\tsocket.setEncoding(\"utf8\");\n\tsocket.on(\"data\", (chunk: string) => {\n\t\tbuffered += chunk;\n\t\tif (Buffer.byteLength(buffered) > MAX_CONTROL_LINE_BYTES) {\n\t\t\tsocket.destroy(new Error(\"Coordinator message is too large\"));\n\t\t\treturn;\n\t\t}\n\t\twhile (true) {\n\t\t\tconst newline = buffered.indexOf(\"\\n\");\n\t\t\tif (newline === -1) return;\n\t\t\tconst line = buffered.slice(0, newline);\n\t\t\tbuffered = buffered.slice(newline + 1);\n\t\t\ttry {\n\t\t\t\tonMessage(JSON.parse(line));\n\t\t\t} catch {\n\t\t\t\tsocket.destroy(new Error(\"Coordinator sent invalid JSON\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction writeJsonLine(socket: Socket, message: unknown): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tsocket.write(encodeControlLine(message), (error) => {\n\t\t\tif (error) reject(error);\n\t\t\telse resolve();\n\t\t});\n\t});\n}\n\n// This process is intentionally a transport shim. It depends only on Node\n// built-ins and never interprets Pi, session, worker, or lifecycle payloads.\n\nconst EMPTY_STARTUP_GRACE_MS = 30_000;\nconst EMPTY_SHUTDOWN_GRACE_MS = 250;\n\ninterface ServerPeer {\n\treadonly serverConnectionId: string;\n\treadonly endpoint: string;\n\treadonly socket: Socket;\n}\n\ninterface RoutedPeer {\n\treadonly peerId: string;\n\treadonly socket: Socket;\n}\n\ninterface ControlMessage {\n\treadonly type: string;\n\treadonly protocol?: unknown;\n\treadonly serverConnectionId?: unknown;\n\treadonly endpoint?: unknown;\n\treadonly peerId?: unknown;\n\treadonly to?: unknown;\n\treadonly payload?: unknown;\n}\n\nlet publicPath: string;\nlet controlPath: string;\nlet running = false;\n\nconst peers = new Map<string, RoutedPeer>();\nconst controlConnections = new Set<Socket>();\nconst publicConnections = new Map<Socket, Socket>();\nlet currentServer: ServerPeer | undefined;\nlet shuttingDown = false;\nlet emptyTimer: NodeJS.Timeout | undefined;\n\nconst publicServer = createServer((socket) => acceptPublicConnection(socket));\nconst controlServer = createServer((socket) => acceptControlConnection(socket));\n\nexport async function runCoordinatorProcess(args: readonly string[]): Promise<void> {\n\tif (running) throw new Error(\"Coordinator process is already running\");\n\tconst [requestedPublicPath, requestedControlPath] = args;\n\tif (!requestedPublicPath || !requestedControlPath) {\n\t\tthrow new Error(\"Coordinator requires public and control socket paths\");\n\t}\n\tpublicPath = requestedPublicPath;\n\tcontrolPath = requestedControlPath;\n\trunning = true;\n\tprocess.once(\"SIGINT\", () => void shutdownCoordinator());\n\tprocess.once(\"SIGTERM\", () => void shutdownCoordinator());\n\tawait main();\n}\n\nasync function main(): Promise<void> {\n\tawait removeStaleSocket(controlPath);\n\tawait removeStaleSocket(publicPath);\n\ttry {\n\t\tawait listen(controlServer, controlPath);\n\t\tawait restrictSocket(controlPath);\n\t\tawait listen(publicServer, publicPath);\n\t\tawait restrictSocket(publicPath);\n\t} catch (error) {\n\t\tawait Promise.all([cleanupSocket(controlPath), cleanupSocket(publicPath)]);\n\t\tthrow error;\n\t}\n\tscheduleEmptyShutdown(EMPTY_STARTUP_GRACE_MS);\n}\n\nfunction acceptControlConnection(socket: Socket): void {\n\tif (shuttingDown) {\n\t\tsocket.destroy();\n\t\treturn;\n\t}\n\tcontrolConnections.add(socket);\n\tlet server: ServerPeer | undefined;\n\tlet peer: RoutedPeer | undefined;\n\tattachRoutedLineReader(socket, (message) => {\n\t\tif (!server && !peer) {\n\t\t\tif (message.type === \"register_server\") {\n\t\t\t\tserver = registerServer(socket, message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (message.type === \"register_peer\") {\n\t\t\t\tpeer = registerPeer(socket, message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new Error(\"Coordinator connection did not register a role\");\n\t\t}\n\t\tif (server) {\n\t\t\tif (server === currentServer) handleRoutedMessage(\"server\", message);\n\t\t\treturn;\n\t\t}\n\t\thandleRoutedMessage(peer!.peerId, message);\n\t});\n\tconst disconnect = (): void => {\n\t\tcontrolConnections.delete(socket);\n\t\tif (server && currentServer === server) {\n\t\t\tcurrentServer = undefined;\n\t\t\tnotifyPeers({ type: \"server_disconnected\", serverConnectionId: server.serverConnectionId });\n\t\t}\n\t\tif (peer && peers.get(peer.peerId) === peer) {\n\t\t\tpeers.delete(peer.peerId);\n\t\t\tif (currentServer) writeRoutedLine(currentServer.socket, { type: \"peer_disconnected\", peerId: peer.peerId });\n\t\t}\n\t\tcheckEmpty();\n\t};\n\tsocket.once(\"close\", disconnect);\n\tsocket.once(\"error\", () => socket.destroy());\n}\n\nfunction registerServer(socket: Socket, message: ControlMessage): ServerPeer {\n\tif (message.protocol !== COORDINATOR_PROTOCOL_VERSION) throw new Error(\"Unsupported coordinator protocol\");\n\tif (typeof message.serverConnectionId !== \"string\" || message.serverConnectionId.length === 0) {\n\t\tthrow new Error(\"Coordinator serverConnectionId must be a string\");\n\t}\n\tif (typeof message.endpoint !== \"string\" || message.endpoint.length === 0) {\n\t\tthrow new Error(\"Coordinator endpoint must be a string\");\n\t}\n\tconst { serverConnectionId, endpoint } = message;\n\tconst server = { serverConnectionId, endpoint, socket };\n\tconst previous = currentServer;\n\tcurrentServer = server;\n\tcancelEmptyShutdown();\n\twriteRoutedLine(socket, {\n\t\ttype: \"server_registered\",\n\t\tserverConnectionId,\n\t\tpeers: [...peers.keys()],\n\t});\n\tif (previous && previous !== server) {\n\t\tclosePublicConnections();\n\t\tnotifyPeers({ type: \"server_disconnected\", serverConnectionId: previous.serverConnectionId });\n\t\twriteRoutedLine(previous.socket, { type: \"server_replaced\" });\n\t}\n\tnotifyPeers({ type: \"server_connected\", serverConnectionId });\n\treturn server;\n}\n\nfunction registerPeer(socket: Socket, message: ControlMessage): RoutedPeer {\n\tif (message.protocol !== COORDINATOR_PROTOCOL_VERSION) throw new Error(\"Unsupported coordinator protocol\");\n\tif (typeof message.peerId !== \"string\" || message.peerId.length === 0) {\n\t\tthrow new Error(\"Coordinator peerId must be a string\");\n\t}\n\tconst { peerId } = message;\n\tif (peerId === \"server\" || peers.has(peerId)) throw new Error(`Coordinator peer is already connected: ${peerId}`);\n\tconst peer = { peerId, socket };\n\tpeers.set(peerId, peer);\n\tcancelEmptyShutdown();\n\twriteRoutedLine(socket, {\n\t\ttype: \"peer_registered\",\n\t\tpeerId,\n\t\t...(currentServer === undefined ? {} : { serverConnectionId: currentServer.serverConnectionId }),\n\t});\n\tif (currentServer) {\n\t\twriteRoutedLine(currentServer.socket, { type: \"peer_connected\", peerId });\n\t}\n\treturn peer;\n}\n\nfunction notifyPeers(message: unknown): void {\n\tfor (const peer of peers.values()) writeRoutedLine(peer.socket, message);\n}\n\nfunction handleRoutedMessage(from: string, message: ControlMessage): void {\n\tif (message.type === \"send\") {\n\t\tif (typeof message.to !== \"string\" || message.to.length === 0) {\n\t\t\tthrow new Error(\"Coordinator message target must be a string\");\n\t\t}\n\t\tconst { to } = message;\n\t\tconst target = to === \"server\" ? currentServer?.socket : peers.get(to)?.socket;\n\t\tif (target) writeRoutedLine(target, { type: \"message\", from, payload: message.payload });\n\t\treturn;\n\t}\n\tif (message.type === \"broadcast\") {\n\t\tif (from !== \"server\") throw new Error(\"Only the current server may broadcast\");\n\t\tfor (const peer of peers.values()) {\n\t\t\twriteRoutedLine(peer.socket, { type: \"message\", from, payload: message.payload });\n\t\t}\n\t\treturn;\n\t}\n\tthrow new Error(`Unknown coordinator routing message: ${message.type}`);\n}\n\nfunction acceptPublicConnection(client: Socket): void {\n\tif (shuttingDown || !currentServer) {\n\t\tclient.destroy();\n\t\treturn;\n\t}\n\tcancelEmptyShutdown();\n\tconst upstream = createConnection(currentServer.endpoint);\n\tpublicConnections.set(client, upstream);\n\tlet finalized = false;\n\tconst finalize = (): void => {\n\t\tif (finalized) return;\n\t\tfinalized = true;\n\t\tpublicConnections.delete(client);\n\t\tcheckEmpty();\n\t};\n\tupstream.once(\"connect\", () => {\n\t\tclient.pipe(upstream);\n\t\tupstream.pipe(client);\n\t});\n\tupstream.once(\"error\", () => client.destroy());\n\tupstream.once(\"close\", () => {\n\t\tclient.destroy();\n\t\tfinalize();\n\t});\n\tclient.once(\"error\", () => upstream.destroy());\n\tclient.once(\"close\", () => {\n\t\tupstream.destroy();\n\t\tfinalize();\n\t});\n}\n\nfunction closePublicConnections(): void {\n\tfor (const [client, upstream] of publicConnections) {\n\t\tclient.destroy();\n\t\tupstream.destroy();\n\t}\n\tpublicConnections.clear();\n}\n\nfunction checkEmpty(): void {\n\tif (shuttingDown || currentServer || peers.size > 0 || publicConnections.size > 0 || controlConnections.size > 0) {\n\t\tcancelEmptyShutdown();\n\t\treturn;\n\t}\n\tscheduleEmptyShutdown(EMPTY_SHUTDOWN_GRACE_MS);\n}\n\nfunction scheduleEmptyShutdown(delayMs: number): void {\n\tif (emptyTimer || shuttingDown) return;\n\temptyTimer = setTimeout(() => {\n\t\temptyTimer = undefined;\n\t\tif (!currentServer && peers.size === 0 && publicConnections.size === 0 && controlConnections.size === 0) {\n\t\t\tvoid shutdownCoordinator();\n\t\t}\n\t}, delayMs);\n\temptyTimer.unref();\n}\n\nfunction cancelEmptyShutdown(): void {\n\tif (!emptyTimer) return;\n\tclearTimeout(emptyTimer);\n\temptyTimer = undefined;\n}\n\nasync function shutdownCoordinator(): Promise<void> {\n\tif (shuttingDown) return;\n\tshuttingDown = true;\n\tcancelEmptyShutdown();\n\tclosePublicConnections();\n\tfor (const connection of controlConnections) connection.destroy();\n\tawait Promise.all([closeServer(publicServer), closeServer(controlServer)]);\n\tawait Promise.all([cleanupSocket(publicPath), cleanupSocket(controlPath)]);\n\tprocess.exit(0);\n}\n\nfunction writeRoutedLine(socket: Socket, message: unknown): void {\n\tif (!socket.destroyed) socket.write(encodeControlLine(message));\n}\n\nfunction attachRoutedLineReader(socket: Socket, onMessage: (message: ControlMessage) => void): void {\n\tlet buffered = \"\";\n\tsocket.setEncoding(\"utf8\");\n\tsocket.on(\"data\", (chunk: string) => {\n\t\tbuffered += chunk;\n\t\tif (Buffer.byteLength(buffered) > MAX_CONTROL_LINE_BYTES) {\n\t\t\tsocket.destroy(new Error(\"Coordinator message is too large\"));\n\t\t\treturn;\n\t\t}\n\t\twhile (true) {\n\t\t\tconst newline = buffered.indexOf(\"\\n\");\n\t\t\tif (newline === -1) return;\n\t\t\tconst line = buffered.slice(0, newline);\n\t\t\tbuffered = buffered.slice(newline + 1);\n\t\t\ttry {\n\t\t\t\tconst message = JSON.parse(line) as ControlMessage | null;\n\t\t\t\tif (typeof message?.type !== \"string\") throw new Error(\"Coordinator message must have a type\");\n\t\t\t\tonMessage(message);\n\t\t\t} catch (error) {\n\t\t\t\tsocket.destroy(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction listen(server: Server, path: string): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst onError = (error: Error): void => {\n\t\t\tserver.off(\"listening\", onListening);\n\t\t\treject(error);\n\t\t};\n\t\tconst onListening = (): void => {\n\t\t\tserver.off(\"error\", onError);\n\t\t\tresolve();\n\t\t};\n\t\tserver.once(\"error\", onError);\n\t\tserver.once(\"listening\", onListening);\n\t\tserver.listen(path);\n\t});\n}\n\nfunction closeServer(server: Server): Promise<void> {\n\tif (!server.listening) return Promise.resolve();\n\treturn new Promise((resolve) => server.close(() => resolve()));\n}\n\nasync function restrictSocket(path: string): Promise<void> {\n\tif (process.platform !== \"win32\") await chmod(path, 0o600);\n}\n\nasync function removeStaleSocket(path: string): Promise<void> {\n\ttry {\n\t\tconst stats = await lstat(path);\n\t\tif (!stats.isSocket()) throw new Error(`Coordinator path is not a socket: ${path}`);\n\t} catch (error) {\n\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return;\n\t\tthrow error;\n\t}\n\tconst live = await new Promise<boolean>((resolve, reject) => {\n\t\tconst socket = createConnection(path);\n\t\tsocket.once(\"connect\", () => {\n\t\t\tsocket.destroy();\n\t\t\tresolve(true);\n\t\t});\n\t\tsocket.once(\"error\", (error: NodeJS.ErrnoException) => {\n\t\t\tsocket.destroy();\n\t\t\tif (error.code === \"ECONNREFUSED\" || error.code === \"ENOENT\") resolve(false);\n\t\t\telse reject(error);\n\t\t});\n\t});\n\tif (live) throw new Error(`Coordinator socket is already active: ${path}`);\n\tawait cleanupSocket(path);\n}\n\nasync function cleanupSocket(path: string): Promise<void> {\n\tif (process.platform === \"win32\") return;\n\tawait unlink(path).catch((error: unknown) => {\n\t\tif (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n\t});\n}\n\nif (isDirectInternalProcessEntry(import.meta.url)) {\n\tconst role = consumeInternalProcessRole();\n\tif (role !== \"coordinator\") throw new Error(\"Coordinator entrypoint requires an internal coordinator invocation\");\n\tvoid runCoordinatorProcess(process.argv.slice(2)).catch((error: unknown) => {\n\t\tconsole.error(error);\n\t\tprocess.exit(1);\n\t});\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/experimental/mini/main.ts"],"names":[],"mappings":"AAAA;;;;GAIG","sourcesContent":["/**\n * The `mini` command. Runs the presentation host.\n *\n * Run: node packages/coding-agent/src/experimental/mini/main.ts [--continue]\n */\n\nimport { runTui, type TuiOptions } from \"./tui/run.ts\";\n\nfunction parseArgs(argv: readonly string[]): TuiOptions {\n\tconst options: TuiOptions = {};\n\tfor (const arg of argv) {\n\t\tif (arg === \"--continue\" || arg === \"-c\") options.continueSession = true;\n\t\telse throw new Error(`Unknown argument: ${arg}`);\n\t}\n\treturn options;\n}\n\nrunTui(parseArgs(process.argv.slice(2))).then(\n\t() => process.exit(0),\n\t(error: unknown) => {\n\t\tconsole.error(error);\n\t\tprocess.exit(1);\n\t},\n);\n"]}
|