@earendil-works/pi-coding-agent 0.84.4 → 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 +57 -5
- package/README.md +3 -1
- 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-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-YMUPJBKR.js → google-generative-ai-BSMTYDAM.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-MPWMV4OF.js → google-vertex-5C3HASOJ.js} +1 -1
- package/dist/bundle/chunks/image-resize-worker.js +1 -1
- package/dist/bundle/chunks/{mistral-conversations-Q3AWZJAZ.js → mistral-conversations-4M6BZBX6.js} +1 -1
- 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-ERMU2SS7.js → openai-completions-QOT3QX7D.js} +3 -3
- 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.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 +2 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +14 -6
- 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 +2 -1
- package/dist/core/compaction/branch-summarization.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/types.d.ts +8 -2
- 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 +40 -13
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- 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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +126 -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.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +14 -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 +8 -15
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +95 -80
- 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/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/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/environment-variables.md +2 -0
- package/docs/extensions.md +5 -2
- package/docs/keybindings.md +3 -1
- package/docs/models.md +3 -0
- package/docs/rpc.md +1 -1
- package/docs/sdk.md +5 -0
- package/docs/settings.md +5 -5
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +15 -0
- package/docs/themes.md +8 -6
- package/docs/tui.md +20 -1
- 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-JUUC5AZY.js +0 -2
- package/dist/bundle/chunks/chunk-OMWWHBTG.js +0 -1548
- package/dist/bundle/chunks/openai-codex-responses-GJVBJXLB.js +0 -8
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"client-tui.js","sourceRoot":"","sources":["../../src/experimental/client-tui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACN,mBAAmB,EACnB,eAAe,EACf,WAAW,GAKX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EACN,4BAA4B,EAE5B,SAAS,EAET,UAAU,EACV,cAAc,EACd,IAAI,GAEJ,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,kDAAkD,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AACnH,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAiC,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAwD,MAAM,gCAAgC,CAAC;AAOvH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAuB,MAAM,wBAAwB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACN,+BAA+B,EAC/B,+BAA+B,GAC/B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAwC,MAAM,0BAA0B,CAAC;AAgC5F,MAAM,WAAW,GAAG;IACnB,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC;IAC1D,YAAY,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxD,WAAW,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC;IACtD,UAAU,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;IACnD,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC;CACpD,CAAC;AAEF,2EAA2E;AAC3E,MAAM,OAAO,qBAAqB;IACxB,GAAG,CAAM;IACT,cAAc,CAAa;IAC3B,OAAO,CAAa;IACpB,kBAAkB,GAAG,IAAI,SAAS,EAAE,CAAC;IACrC,eAAe,GAAG,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrC,yBAAyB,GAAG,IAAI,SAAS,EAAE,CAAC;IAC5C,gBAAgB,GAAG,IAAI,SAAS,EAAE,CAAC;IACnC,gBAAgB,GAAG,IAAI,SAAS,EAAE,CAAC;IACnC,gBAAgB,GAAG,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,WAAW,CAAY;IACvB,aAAa,CAAe;IAC5B,YAAY,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC;IACpD,mBAAmB,CAA2B;IAC9C,UAAU,CAAwB;IAClC,gBAAgB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IACrC,QAAQ,CAA6B;IACrC,cAAc,CAA4B;IAC1C,WAAW,CAA8B;IAChC,UAAU,CAAe;IAClC,WAAW,CAAyB;IACpC,UAAU,CAA+B;IACzC,OAAO,GAAsB,MAAM,CAAC;IACpC,iBAAiB,CAAqB;IACtC,UAAU,CAAqB;IAC/B,OAAO,GAAG,qBAAmB,CAAC;IAC9B,KAAK,GAAG,KAAK,CAAC;IACd,OAAO,GAAG,KAAK,CAAC;IAChB,aAAa,CAA4B;IACzC,mBAAmB,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IACvD,gBAAgB,CAA2B;IAC3C,SAAS,CAAmC;IAE5C,YAAoB,EAAO,EAAE,aAAyB,EAAE,MAAkB,EAAE,YAA0B,EAAE;QACvG,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAClC,IAAI,CAAC,UAAU,GAAG,IAAI,YAAY,CAAC,EAAE,EAAE,cAAc,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7F,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACtE,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACnD,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAChG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC;YACtD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;YAC9C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAC9B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC5B,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAAA,CAC/B,CAAC,CAAC;QACH,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,WAAW,GAAG,kBAAkB,CAAC;YACrC,QAAQ,EAAE,IAAI,CAAC,kBAAkB;YACjC,eAAe,EAAE,IAAI,CAAC,yBAAyB;YAC/C,MAAM,EAAE,IAAI,CAAC,gBAAgB;YAC7B,MAAM,EAAE,IAAI,CAAC,gBAAgB;YAC7B,MAAM,EAAE,IAAI,CAAC,gBAAgB;YAC7B,mBAAmB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,EAAE,IAAI,CAAC;YAC/D,mBAAmB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,EAAE,IAAI,CAAC;SAC/D,CAAC,CAAC,IAAI,CAAC;QACR,IAAI,CAAC,QAAQ,EAAE,CAAC;IAAA,CAChB;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAOnB,EAAkC;QAClC,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9E,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAC7C,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAC9D,CAAC,IAAI,EAAE,CAAC;QACT,MAAM,SAAS,GAAG,IAAI,qBAAqB,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC7G,IAAI,CAAC;YACJ,MAAM,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjC,MAAM,SAAS,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAC/C,OAAO,SAAS,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC;gBACJ,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;YACzB,CAAC;YAAC,OAAO,YAAY,EAAE,CAAC;gBACvB,MAAM,IAAI,cAAc,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE,6CAA6C,CAAC,CAAC;YAChG,CAAC;YACD,MAAM,KAAK,CAAC;QACb,CAAC;IAAA,CACD;IAED,IAAI,UAAU,GAAc;QAC3B,OAAO,IAAI,CAAC,WAAW,CAAC;IAAA,CACxB;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,OAAO;YACN,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC;YACxC,GAAG,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/C,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC;YACtC,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC;YACtC,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC;SACtC,CAAC;IAAA,CACF;IAED,WAAW,CAAC,IAAY,EAAQ;QAC/B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,IACC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC;gBAC5C,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EACtF,CAAC;gBACF,IAAI,CAAC,OAAO,EAAE,CAAC;YAChB,CAAC;YACD,OAAO;QACR,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IAAA,CACpC;IAED,UAAU,GAAS;QAClB,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;IAAA,CAC9B;IAED,OAAO,GAAS;QACf,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC;IAAA,CAClC;IAED,YAAY,GAAS;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACtC,IAAI,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,EAAE,CAAC;IAAA,CAChB;IAED,SAAS,CAAC,KAAa,EAAQ;QAC9B,IAAI,CAAC,OAAO,GAAG,UAAU,KAAK,EAAE,CAAC;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;IAAA,CAChB;IAED,KAAK,GAAkB;QACtB,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,aAAa,CAAC;IAAA,CAC1B;IAED,KAAK,CAAC,MAAM,CAAC,QAA+B,EAAiB;QAC5D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,kBAAkB,GAAG,MAAM,mBAAmB,CACjD,8BAA8B,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAC5D,CAAC,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,SAAqB,CAAC;QAC1B,MAAM,yBAAyB,GAAG,CAAC,IAAe,EAAiB,EAAE,CAAC;YACrE,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;gBACxD,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACzF,IAAI,CAAC;oBACJ,MAAM,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAC1C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,IAAI,CAAC;wBACJ,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;oBAC3B,CAAC;oBAAC,OAAO,YAAY,EAAE,CAAC;wBACvB,MAAM,IAAI,cAAc,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE,sCAAsC,CAAC,CAAC;oBACzF,CAAC;oBACD,MAAM,KAAK,CAAC;gBACb,CAAC;gBACD,MAAM,OAAO,GAAG,kBAAkB,CAAC;gBACnC,kBAAkB,GAAG,SAAS,CAAC;gBAC/B,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;gBACrC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YAAA,CACxB,CAAC,CAAC;YACH,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC;YAClD,OAAO,SAAS,CAAC;QAAA,CACjB,CAAC;QACF,MAAM,uBAAuB,GAAG,WAAW,CAAC;YAC3C,EAAE,EAAE,yBAAyB;YAC7B,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;gBACf,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE;oBAC3B,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,CACvC,IAAI,CAAC,OAAO,CACX,KAAK,EACL,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,EAClC,aAAa,CACb;oBACF,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;wBACvB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;wBACtB,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAAA,CAChB;iBACD,CAAC,CAAC;gBACH,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBACxC,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;gBAC5C,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACvC,MAAM,cAAc,GAAmB;oBACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,UAAU;iBACV,CAAC;gBACF,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;oBACpB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;wBACxG,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;oBAC7D,CAAC;oBACD,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC;oBAC/B,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;oBAC/B,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;oBAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;wBACb,IAAI,IAAI,CAAC,QAAQ,KAAK,cAAc;4BAAE,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;wBAChE,IAAI,IAAI,CAAC,cAAc,KAAK,QAAQ;4BAAE,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;wBACtE,IAAI,IAAI,CAAC,WAAW,KAAK,UAAU;4BAAE,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;oBAAA,CAClE,CAAC,CAAC;oBACH,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;oBAC9D,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;wBACnB,GAAG,CAAC,GAAG,CACN,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAClG,CAAC;wBACF,GAAG,CAAC,GAAG,CACN,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,CAClG,CAAC;oBACH,CAAC;gBAAA,CACD,CAAC,CAAC;YAAA,CACH;SACD,CAAC,CAAC;QACH,SAAS,GAAG,MAAM,eAAe,CAAC;YACjC,MAAM,EAAE;gBACP,+BAA+B,EAAE;gBACjC,uBAAuB;gBACvB,+BAA+B,CAAC,EAAE,yBAAyB,EAAE,CAAC;gBAC9D,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM;gBAC5B,GAAG,kBAAkB,CAAC,MAAM;aAC5B;YACD,cAAc,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC;SAC/C,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAAA,CAC5B;IAED,KAAK,CAAC,oBAAoB,CAAC,QAA+B,EAAiB;QAC1E,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9G,MAAM,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;QACnF,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;QAC7C,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAAA,CAChB;IAED,KAAK,CAAC,MAAM,GAAkB;QAC7B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,mBAAmB,CAAC;YAC/B,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,gBAAgB,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC;gBACJ,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACjC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;YACD,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC7B,CAAC;QACD,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CACxE,CAAC,UAAU,EAA8B,EAAE,CAAC,UAAU,KAAK,SAAS,CACpE,CAAC;QACF,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAChG,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACnG,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,2CAA2C,CAAC,CAAC;IAAA,CACrG;IAED,QAAQ,GAAS;QAChB,IAAI,CAAC,eAAe,CAAC,OAAO,CAC3B,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS;YACpE,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,IAAI,CAAC,iBAAiB,cAAc,IAAI,CAAC,UAAU,EAAE,CAAC,CACpF,CAAC;QACF,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxF,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAChE,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;YAChC,MAAM,QAAQ,GAAG,IAAI,SAAS,EAAE,CAAC;YACjC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrE,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;YAC/F,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;YAC/F,IAAI,aAAa,IAAI,CAAC;gBAAE,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;YACzE,IAAI,CAAC,WAAW,CAAC,QAAQ,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,IAAI,CAAC,WAAW,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;YACrE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;YACtC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;IAAA,CACtB;IAED,OAAO,CAAC,KAAa,EAAE,KAA4B,EAAE,aAAsB,EAA+B;QACzG,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACjG,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;YACvG,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC;YACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;QAAA,CAChB,CAAC,CAAC;IAAA,CACH;IAED,kBAAkB,CAAC,KAAyB,EAAQ;QACnD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO;QACpC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IAAA,CACnC;IAED,mBAAmB,GAAS;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,sBAAsB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC7D,IAAI,CAAC,UAAU,CAAC,uBAAuB,CACtC,IAAI,4BAA4B,CAC/B,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;YACrF,GAAG,CAAC,OAAO,CAAC,sBAAsB,KAAK,SAAS;gBAC/C,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACA,sBAAsB,EAAE,KAAK,EAAE,MAAc,EAAE,EAAE,CAAC;wBACjD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,sBAAuB,CAAC,MAAM,CAAC,CAAC;wBAC5D,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;oBAAA,CAC1C;iBACD,CAAC;SACJ,CAAC,CAAC,EACH,OAAO,CAAC,GAAG,EAAE,CACb,CACD,CAAC;QACF,IAAI,CAAC,cAAc,EAAE,CAAC;IAAA,CACtB;IAED,sBAAsB,GAA8B;QACnD,OAAO,IAAI,CAAC,cAAc,CAAC;IAAA,CAC3B;IAED,sBAAsB,CAAC,QAAgB,EAAE,KAA4B,EAAQ;QAC5E,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,iBAAiB,KAAK,QAAQ;YAAE,OAAO;QAChE,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBACzC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;gBAClB,IAAI,CAAC,OAAO,GAAG,wBAAsB,CAAC;gBACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjB,CAAC;YACD,OAAO;QACR,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,2BAAyB,CAAC,CAAC,CAAC,kCAAgC,CAAC;QAC5G,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;IAAA,CAChB;IAED,sBAAsB,CAAC,OAAuB,EAAE,KAA6B,EAAQ;QACpF,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,iBAAiB,KAAK,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO;QACzG,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YACxE,IAAI,CAAC,cAAc,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC/B,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS;oBAAE,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBACvE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;gBACnB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;gBAClB,IAAI,CAAC,QAAQ,EAAE,CAAC;YAAA,CAChB,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YACzE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,OAAO,GAAG,wBAAsB,CAAC;YACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjB,CAAC;IAAA,CACD;IAED,cAAc,CAAC,SAA8B,EAAQ;QACpD,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB;aACjD,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,MAAM,SAAS,EAAE,CAAC;QAAA,CACrC,CAAC;aACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC;YAC1B,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,OAAO,GAAG,oBAAoB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;QAAA,CAChB,CAAC,CAAC;IAAA,CACJ;IAED,KAAK,CAAC,SAAS,CAAC,OAAuB,EAAiB;QACvD,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,oBAAoB,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACvD,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,CAAC,yBAAyB,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC9D,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YACrE,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI;gBAAE,OAAO;YACpC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC3B,IAAI,CAAC,QAAQ,EAAE,CAAC;QAAA,CAChB,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjH,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC3D,CAAC;IAAA,CACD;IAED,KAAK,CAAC,UAAU,GAAkB;QACjC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;QAC1B,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,CAAC;QACvC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAAA,CAC9B;IAED,KAAK,CAAC,UAAU,CAAC,WAAmB,EAAiB;QACpD,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACvE,MAAM,IAAI,GAAG,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACxE,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC5C,OAAO;QACR,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,GAAG,UAAU,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjB,CAAC;IAAA,CACD;IAED,KAAK,CAAC,oBAAoB,CAAC,IAAY,EAAE,IAAY,EAAiB;QACrE,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,EAAE;YAC5C,EAAE,IAAI,EAAE;aACP,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,GAAG,2BAA2B,IAAI,EAAE,CAAC;YACjD,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO;QACR,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;YAC3D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1B,IAAI,SAAS,IAAI,MAAM;oBAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;;oBAC9C,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,GAAG,UAAU,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjB,CAAC;IAAA,CACD;IAED,KAAK,CAAC,aAAa,CAAC,MAAc,EAAiB;QAClD,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC9C,IAAI,UAAU,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjG,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,SAAS,CAAC;QAClD,MAAM,OAAO,GAAG,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,CAAC;QAC9D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,8BAA4B,CAAC,CAAC,CAAC,iBAAe,CAAC;QACxE,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,OAAO;YAAE,IAAI,CAAC,YAAY,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;;YACzG,IAAI,CAAC,gBAAgB,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAAA,CAC3G;IAED,KAAK,CAAC,cAAc,CAAC,IAAY,EAAiB;QACjD,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC9C,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO;QACrC,IAAI,CAAC;YACJ,IAAI,CAAC,OAAO,GAAG,uBAAqB,CAAC;YACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,IAAI,CAAC,YAAY,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;QACnG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,GAAG,UAAU,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjB,CAAC;IAAA,CACD;IAED,gBAAgB,CAAC,QAAgC,EAAQ;QACxD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,QAAQ;YAC/B,CAAC,CAAC,QAAQ,CAAC,KAAK,KAAK,IAAI;gBACxB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,qBAAqB,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE;YAChD,CAAC,CAAC,uBAAuB,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;IAAA,CAChB;IAED,YAAY,CAAC,QAA4B,EAAQ;QAChD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,qBAAqB,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACjH,IAAI,CAAC,QAAQ,EAAE,CAAC;IAAA,CAChB;IAED,UAAU,GAAS;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,SAAS,CAAC;QAClD,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC9C,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO;QACtF,IAAI,CAAC,OAAO,GAAG,YAAY,SAAS,CAAC,EAAE,KAAG,CAAC;QAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,KAAK,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC;YACxF,IAAI,CAAC,OAAO,GAAG,UAAU,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QAAA,CAChB,CAAC,CAAC;IAAA,CACH;IAED,mBAAmB,GAAgC;QAClD,OAAO,IAAI,CAAC,WAAW,CAAC;IAAA,CACxB;IAED,aAAa,GAAG;QACf,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;QACjE,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAAA,CAChD;IAED,OAAO,GAAW;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACtC,IAAI,CAAC,QAAQ;YAAE,OAAO,4CAAyC,CAAC;QAChE,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,IAAI,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,gBAAe,QAAQ,CAAC,aAAa,CAAC,aAAa,OAAM,QAAQ,CAAC,KAAK,CAAC,YAAY,yDAAqD,CAAC;IAAA,CACjO;CACD;AAED,KAAK,UAAU,oBAAoB,CAClC,OAAsB,EACtB,OAAmC,EACF;IACjC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvC,MAAM;QACN,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YAC5B,QAAQ,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,CAAC;YACpE,YAAY,GAAG,EAAC,CAAC;YACjB,OAAO,GAAG,EAAC,CAAC;SACZ,CAAC;KACF,CAAC,CAAC,CAAC;IACJ,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YACtD,MAAM;YACN,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC;YACzC,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,iBAAiB,CAAC;YAC3C,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,mBAAmB,CAAC;SAC1C,CAAC,CAAC,CAAC;QACJ,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;QACpF,IAAI,QAOQ,CAAC;QACb,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC5C,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE,CAAC;iBAC7C,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC;iBAC5D,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAClB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,OAAO;aACP,CAAC,CAAC,CACJ,CAAC;YACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,WAAW,OAAO,CAAC,SAAS,yCAAyC,CAAC,CAAC;YAC/G,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC5B,IAAI,OAAO,CAAC,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC7C,MAAM,IAAI,KAAK,CAAC,0CAA0C,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;gBAChF,CAAC;gBACD,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;gBAC9C,QAAQ,GAAG;oBACV,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,OAAO,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,kBAAkB,CAAC;iBACvF,CAAC;YACH,CAAC;QACF,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACjE,QAAQ,GAAG,QAAQ;iBACjB,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CACpB,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACjE,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,OAAO;aACP,CAAC,CAAC,CACH;iBACA,IAAI,CACJ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACf,KAAK,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS;gBAChD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAC3D,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAC9D,CAAC,CAAC,CAAC,CAAC;QACP,CAAC;QACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAC9C,QAAQ,GAAG;gBACV,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,OAAO,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,kBAAkB,CAAC;aAChE,CAAC;QACH,CAAC;QACD,MAAM,mBAAmB,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,cAAc,CAChE;YACC,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,SAAS;YACrC,YAAY,EAAE,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,IAAI;SACxF,EACD,kBAAkB,CAClB,CAAC;QACF,MAAM,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;QACjF,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;QAC3F,OAAO;YACN,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,mBAAmB;SACnB,CAAC;IACH,CAAC;YAAS,CAAC;QACV,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC9F,CAAC;AAAA,CACD;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAsB,EAAE,OAAO,GAAwB,EAAE,EAAiB;IAC5G,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,IAAI,qBAAqB,CAAC;QAChD,GAAG;QACH,QAAQ;QACR,eAAe;QACf,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,IAAI;QACd,iBAAiB,EAAE,IAAI;QACvB,cAAc,EAAE,IAAI;KACpB,CAAC,CAAC;IACH,MAAM,cAAc,CAAC,MAAM,EAAE,CAAC;IAC9B,mBAAmB,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,oBAAoB,CAAC;QAChC,OAAO,EAAE,YAAY;QACrB,kBAAkB,EAAE,eAAe,CAAC,qBAAqB,EAAE;QAC3D,YAAY,EAAE,QAAQ;KACtB,CAAC,CAAC;IACH,GAAG,CAAC,gBAAgB,CAAC,eAAe,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACzD,IAAI,SAA4C,CAAC;IACjD,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,MAAM,eAAe,GAAG,IAAI,0BAA0B,CAAC,GAAG,EAAE;QAC3D,kBAAkB,EAAE,GAAG,EAAE,CAAC,eAAe;QACzC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC;QACjD,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE;KAC1C,CAAC,CAAC;IACH,IAAI,CAAC;QACJ,IAAI,MAAmB,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/C,MAAM,GAAG,GAAG,EAAE,CAAC;gBACd,eAAe,CAAC,eAAe,EAAE,CAAC;gBAClC,IAAI,UAAU,EAAE,CAAC;oBAChB,GAAG,CAAC,IAAI,EAAE,CAAC;oBACX,UAAU,GAAG,KAAK,CAAC;gBACpB,CAAC;gBACD,OAAO,EAAE,CAAC;YAAA,CACV,CAAC;QAAA,CACF,CAAC,CAAC;QACH,SAAS,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC;YAC9C,OAAO;YACP,EAAE,EAAE,GAAG;YACP,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACzC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ;gBAC/B,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,KAAK,QAAQ;gBAC3C,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,OAAO,EAAE,MAAM,CAAC,OAAO;aACvB,CAAC,CAAC;YACH,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,aAAa,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE;YACxC,MAAM;SACN,CAAC,CAAC;QACH,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACxB,GAAG,CAAC,aAAa,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACxC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACxB,UAAU,GAAG,IAAI,CAAC;QAClB,GAAG,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,eAAe,CAAC,iBAAiB,EAAE,CAAC;QAC1C,MAAM,QAAQ,CAAC;IAChB,CAAC;YAAS,CAAC;QACV,eAAe,CAAC,OAAO,EAAE,CAAC;QAC1B,gBAAgB,EAAE,CAAC;QACnB,IAAI,UAAU;YAAE,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3B,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;AAAA,CACD;AAED,SAAS,mBAAmB,CAAI,QAAsB,EAAK;IAC1D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAC7F,OAAO,QAAQ,CAAC,CAAC,CAAE,CAAC;AAAA,CACpB;AAED,SAAS,OAAO,CAAC,KAAc,EAAU;IACxC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAAA,CAC9D","sourcesContent":["import { resolve } from \"node:path\";\nimport {\n\tcombineFacetLoaders,\n\tcreateFacetHost,\n\tdefineFacet,\n\ttype FacetHost,\n\ttype FacetLoader,\n\ttype JsonValue,\n\ttype LoadedFacets,\n} from \"@earendil-works/chord\";\nimport { BACKGROUND_CONTEXT } from \"@earendil-works/chord/context\";\nimport {\n\tCombinedAutocompleteProvider,\n\ttype Component,\n\tContainer,\n\ttype SelectItem,\n\tSelectList,\n\tsetKeybindings,\n\tText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport type { ClientCommand } from \"../cli/experimental/commands/client.ts\";\nimport { getAgentDir } from \"../config.ts\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport { DefaultResourceLoader } from \"../core/resource-loader.ts\";\nimport { SettingsManager } from \"../core/settings-manager.ts\";\nimport { createChatViewport } from \"../modes/interactive/chat-viewport.ts\";\nimport { CustomEditor } from \"../modes/interactive/components/custom-editor.ts\";\nimport { getEditorTheme, setRegisteredThemes, stopThemeWatcher, theme } from \"../modes/interactive/theme/theme.ts\";\nimport { InteractiveThemeController } from \"../modes/interactive/theme/theme-controller.ts\";\nimport { createInteractiveTui } from \"../modes/interactive/tui-renderer.ts\";\nimport { type OpenClientRuntimeOptions, openClientRuntime } from \"./client-runtime.ts\";\nimport { ExperimentalChatView } from \"./client-tui-chat.ts\";\nimport { createPresentationFacetLoaders } from \"./plugins/bundled.ts\";\nimport { AgentController, type AgentOperationResponse, type AgentQueueResponse } from \"./services/agent-controller.ts\";\nimport type {\n\tServerConnectionState,\n\tServerServiceSource,\n\tSessionAttachmentState,\n\tSessionServiceSource,\n} from \"./services/connection.ts\";\nimport { PresentationPlugins } from \"./services/plugins.ts\";\nimport { PresentationUI } from \"./services/presentation-ui.ts\";\nimport { SessionDirectory, SessionManagement, type SessionSummary } from \"./services/sessions.ts\";\nimport { SlashCommands } from \"./services/slash-commands.ts\";\nimport {\n\tcreateBuiltInSlashCommandsFacet,\n\tcreateSlashCommandsRuntimeFacet,\n} from \"./services/slash-commands-provider.ts\";\nimport { Transcript, type Transcript as TranscriptService } from \"./services/transcript.ts\";\n\nexport interface RunClientTuiOptions extends OpenClientRuntimeOptions {\n\treadonly facetLoader?: FacetLoader;\n}\n\nexport interface ClientTuiServer {\n\treadonly serverId: string;\n\treadonly radius: boolean;\n\treadonly server: ServerServiceSource;\n\treadonly session: SessionServiceSource;\n}\n\ninterface SessionFeature {\n\treadonly serverId: string;\n\treadonly session: SessionServiceSource;\n\treadonly transcript: TranscriptService;\n}\n\ninterface PreparedClientSession {\n\treadonly server: ClientTuiServer;\n\treadonly summary: SessionSummary;\n\treadonly presentationPlugins: JsonValue;\n}\n\ninterface PendingSelection {\n\treadonly title: string;\n\treadonly items: readonly SelectItem[];\n\treadonly selectedValue?: string;\n\tresolve(value: string | undefined): void;\n}\n\nconst selectTheme = {\n\tselectedPrefix: (text: string) => theme.fg(\"accent\", text),\n\tselectedText: (text: string) => theme.fg(\"accent\", text),\n\tdescription: (text: string) => theme.fg(\"muted\", text),\n\tscrollInfo: (text: string) => theme.fg(\"dim\", text),\n\tnoMatch: (text: string) => theme.fg(\"warning\", text),\n};\n\n/** Service-only presentation driven by a replicated main-lane snapshot. */\nexport class ExperimentalClientTui implements Component {\n\treadonly #ui: TUI;\n\treadonly #requestRender: () => void;\n\treadonly #finish: () => void;\n\treadonly #documentContainer = new Container();\n\treadonly #sessionHeading = new Text(\"\", 1, 0);\n\treadonly #pendingMessagesContainer = new Container();\n\treadonly #statusContainer = new Container();\n\treadonly #editorContainer = new Container();\n\treadonly #footerComponent = new Text(\"\", 1, 0);\n\treadonly #layoutRoot: Component;\n\treadonly #sharedFacets: LoadedFacets;\n\treadonly #keybindings = KeybindingsManager.create();\n\t#presentationFacets: LoadedFacets | undefined;\n\t#facetHost: FacetHost | undefined;\n\t#facetReloadTail = Promise.resolve();\n\t#session: SessionFeature | undefined;\n\t#slashCommands: SlashCommands | undefined;\n\t#controller: AgentController | undefined;\n\treadonly #chatInput: CustomEditor;\n\t#selectList: SelectList | undefined;\n\t#selection: PendingSelection | undefined;\n\t#screen: \"select\" | \"chat\" = \"chat\";\n\t#selectedServerId: string | undefined;\n\t#sessionId: string | undefined;\n\t#status = \"Starting Session…\";\n\t#busy = false;\n\t#closed = false;\n\t#closePromise: Promise<void> | undefined;\n\t#recoveryTransition: Promise<void> = Promise.resolve();\n\t#laneUnsubscribe: (() => void) | undefined;\n\t#chatView: ExperimentalChatView | undefined;\n\n\tprivate constructor(ui: TUI, requestRender: () => void, finish: () => void, loadedFacets: LoadedFacets) {\n\t\tthis.#ui = ui;\n\t\tthis.#requestRender = requestRender;\n\t\tthis.#finish = finish;\n\t\tthis.#sharedFacets = loadedFacets;\n\t\tsetKeybindings(this.#keybindings);\n\t\tthis.#chatInput = new CustomEditor(ui, getEditorTheme(), this.#keybindings, { paddingX: 1 });\n\t\tthis.#chatInput.onSubmit = (message) => void this.#runPrompt(message);\n\t\tthis.#chatInput.onEscape = () => this.#interrupt();\n\t\tthis.#chatInput.onCtrlD = finish;\n\t\tthis.#chatInput.onAction(\"app.clear\", finish);\n\t\tthis.#chatInput.onAction(\"app.model.select\", () => void this.#executeSlashCommand(\"model\", \"\"));\n\t\tthis.#chatInput.onAction(\"app.message.followUp\", () => {\n\t\t\tconst text = this.#chatInput.getText().trim();\n\t\t\tif (text.length === 0) return;\n\t\t\tthis.#chatInput.setText(\"\");\n\t\t\tvoid this.#queueFollowUp(text);\n\t\t});\n\t\tthis.#editorContainer.addChild(this.#chatInput);\n\t\tthis.#layoutRoot = createChatViewport({\n\t\t\tdocument: this.#documentContainer,\n\t\t\tpendingMessages: this.#pendingMessagesContainer,\n\t\t\tstatus: this.#statusContainer,\n\t\t\teditor: this.#editorContainer,\n\t\t\tfooter: this.#footerComponent,\n\t\t\tscrollbarTrackStyle: (text) => theme.fg(\"scrollbarTrack\", text),\n\t\t\tscrollbarThumbStyle: (text) => theme.fg(\"scrollbarThumb\", text),\n\t\t}).root;\n\t\tthis.#rebuild();\n\t}\n\n\tstatic async create(options: {\n\t\treadonly command: ClientCommand;\n\t\treadonly ui: TUI;\n\t\treadonly servers: readonly ClientTuiServer[];\n\t\treadonly facetLoader?: FacetLoader;\n\t\trequestRender(): void;\n\t\tfinish(): void;\n\t}): Promise<ExperimentalClientTui> {\n\t\tconst prepared = await prepareClientSession(options.command, options.servers);\n\t\tconst loadedFacets = await combineFacetLoaders(\n\t\t\toptions.facetLoader === undefined ? [] : [options.facetLoader],\n\t\t).load();\n\t\tconst component = new ExperimentalClientTui(options.ui, options.requestRender, options.finish, loadedFacets);\n\t\ttry {\n\t\t\tawait component.#start(prepared);\n\t\t\tawait component.#openPreparedSession(prepared);\n\t\t\treturn component;\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait component.close();\n\t\t\t} catch (cleanupError) {\n\t\t\t\tthrow new AggregateError([error, cleanupError], \"Experimental TUI startup and cleanup failed\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tget layoutRoot(): Component {\n\t\treturn this.#layoutRoot;\n\t}\n\n\trender(width: number): string[] {\n\t\treturn [\n\t\t\t...this.#documentContainer.render(width),\n\t\t\t...this.#pendingMessagesContainer.render(width),\n\t\t\t...this.#statusContainer.render(width),\n\t\t\t...this.#editorContainer.render(width),\n\t\t\t...this.#footerComponent.render(width),\n\t\t];\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.#busy) {\n\t\t\tif (\n\t\t\t\tthis.#keybindings.matches(data, \"app.clear\") ||\n\t\t\t\t(this.#chatInput.getText().length === 0 && this.#keybindings.matches(data, \"app.exit\"))\n\t\t\t) {\n\t\t\t\tthis.#finish();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (this.#screen === \"chat\") {\n\t\t\tthis.#chatInput.handleInput(data);\n\t\t\tthis.#requestRender();\n\t\t\treturn;\n\t\t}\n\t\tthis.#selectList?.handleInput(data);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.#layoutRoot.invalidate();\n\t}\n\n\tdispose(): void {\n\t\tvoid this.close().catch(() => {});\n\t}\n\n\trefreshTheme(): void {\n\t\tconst snapshot = this.#laneSnapshot();\n\t\tif (snapshot !== undefined) this.#chatView?.refreshTheme(snapshot);\n\t\tthis.#rebuild();\n\t}\n\n\tshowError(error: string): void {\n\t\tthis.#status = `Error: ${error}`;\n\t\tthis.#rebuild();\n\t}\n\n\tclose(): Promise<void> {\n\t\tthis.#closePromise ??= this.#close();\n\t\treturn this.#closePromise;\n\t}\n\n\tasync #start(prepared: PreparedClientSession): Promise<void> {\n\t\tconst server = prepared.server;\n\t\tlet presentationFacets = await combineFacetLoaders(\n\t\t\tcreatePresentationFacetLoaders(prepared.presentationPlugins),\n\t\t).load();\n\t\tthis.#presentationFacets = presentationFacets;\n\t\tlet facetHost!: FacetHost;\n\t\tconst reloadPresentationPlugins = (data: JsonValue): Promise<void> => {\n\t\t\tconst operation = this.#facetReloadTail.then(async () => {\n\t\t\t\tconst candidate = await combineFacetLoaders(createPresentationFacetLoaders(data)).load();\n\t\t\t\ttry {\n\t\t\t\t\tawait facetHost.reload(candidate.facets);\n\t\t\t\t} catch (error) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait candidate.dispose();\n\t\t\t\t\t} catch (cleanupError) {\n\t\t\t\t\t\tthrow new AggregateError([error, cleanupError], \"TUI plugin reload and cleanup failed\");\n\t\t\t\t\t}\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst retired = presentationFacets;\n\t\t\t\tpresentationFacets = candidate;\n\t\t\t\tthis.#presentationFacets = candidate;\n\t\t\t\tawait retired.dispose();\n\t\t\t});\n\t\t\tthis.#facetReloadTail = operation.catch(() => {});\n\t\t\treturn operation;\n\t\t};\n\t\tconst presentationBridgeFacet = defineFacet({\n\t\t\tid: \"@pi/presentation-bridge\",\n\t\t\tsetup: (env) => {\n\t\t\t\tenv.provide(PresentationUI, {\n\t\t\t\t\tselect: (title, items, selectedValue) =>\n\t\t\t\t\t\tthis.#select(\n\t\t\t\t\t\t\ttitle,\n\t\t\t\t\t\t\titems.map((item) => ({ ...item })),\n\t\t\t\t\t\t\tselectedValue,\n\t\t\t\t\t\t),\n\t\t\t\t\tshowStatus: (status) => {\n\t\t\t\t\t\tthis.#status = status;\n\t\t\t\t\t\tthis.#rebuild();\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tconst commands = env.use(SlashCommands);\n\t\t\t\tconst controller = env.use(AgentController);\n\t\t\t\tconst transcript = env.use(Transcript);\n\t\t\t\tconst sessionFeature: SessionFeature = {\n\t\t\t\t\tserverId: server.serverId,\n\t\t\t\t\tsession: server.session,\n\t\t\t\t\ttranscript,\n\t\t\t\t};\n\t\t\t\tenv.onActivate(() => {\n\t\t\t\t\tif (this.#session !== undefined || this.#slashCommands !== undefined || this.#controller !== undefined) {\n\t\t\t\t\t\tthrow new Error(\"Presentation services are already active\");\n\t\t\t\t\t}\n\t\t\t\t\tthis.#session = sessionFeature;\n\t\t\t\t\tthis.#slashCommands = commands;\n\t\t\t\t\tthis.#controller = controller;\n\t\t\t\t\tenv.own(() => {\n\t\t\t\t\t\tif (this.#session === sessionFeature) this.#session = undefined;\n\t\t\t\t\t\tif (this.#slashCommands === commands) this.#slashCommands = undefined;\n\t\t\t\t\t\tif (this.#controller === controller) this.#controller = undefined;\n\t\t\t\t\t});\n\t\t\t\t\tenv.own(commands.subscribe(() => this.#updateAutocomplete()));\n\t\t\t\t\tif (server.radius) {\n\t\t\t\t\t\tenv.own(\n\t\t\t\t\t\t\tserver.server.connection.subscribe((state) => this.#handleConnectionState(server.serverId, state)),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tenv.own(\n\t\t\t\t\t\t\tserver.session.attachment.subscribe((state) => this.#handleAttachmentState(sessionFeature, state)),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t\tfacetHost = await createFacetHost({\n\t\t\tfacets: [\n\t\t\t\tcreateSlashCommandsRuntimeFacet(),\n\t\t\t\tpresentationBridgeFacet,\n\t\t\t\tcreateBuiltInSlashCommandsFacet({ reloadPresentationPlugins }),\n\t\t\t\t...this.#sharedFacets.facets,\n\t\t\t\t...presentationFacets.facets,\n\t\t\t],\n\t\t\tserviceSources: [server.server, server.session],\n\t\t});\n\t\tthis.#facetHost = facetHost;\n\t}\n\n\tasync #openPreparedSession(prepared: PreparedClientSession): Promise<void> {\n\t\tconst feature = this.#session;\n\t\tif (feature === undefined) throw new Error(`No Session service is available for ${prepared.server.serverId}`);\n\t\tawait feature.session.whenAttached(prepared.summary.sessionId, BACKGROUND_CONTEXT);\n\t\tthis.#selectedServerId = feature.serverId;\n\t\tthis.#sessionId = prepared.summary.sessionId;\n\t\tthis.#updateAutocomplete();\n\t\tawait this.#openLane(feature);\n\t\tthis.#screen = \"chat\";\n\t\tthis.#status = \"\";\n\t\tthis.#rebuild();\n\t}\n\n\tasync #close(): Promise<void> {\n\t\tthis.#closed = true;\n\t\tthis.#completeSelection(undefined);\n\t\tconst errors: unknown[] = [];\n\t\ttry {\n\t\t\tawait this.#recoveryTransition;\n\t\t\tawait this.#closeLane();\n\t\t\tawait this.#facetReloadTail;\n\t\t} catch (error) {\n\t\t\terrors.push(error);\n\t\t}\n\t\tif (this.#facetHost !== undefined) {\n\t\t\ttry {\n\t\t\t\tawait this.#facetHost.dispose();\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(error);\n\t\t\t}\n\t\t\tthis.#facetHost = undefined;\n\t\t}\n\t\tconst generations = [this.#presentationFacets, this.#sharedFacets].filter(\n\t\t\t(generation): generation is LoadedFacets => generation !== undefined,\n\t\t);\n\t\tthis.#presentationFacets = undefined;\n\t\tconst results = await Promise.allSettled(generations.map((generation) => generation.dispose()));\n\t\terrors.push(...results.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : [])));\n\t\tif (errors.length === 1) throw errors[0];\n\t\tif (errors.length > 1) throw new AggregateError(errors, \"Failed to dispose experimental TUI facets\");\n\t}\n\n\t#rebuild(): void {\n\t\tthis.#sessionHeading.setText(\n\t\t\tthis.#sessionId === undefined || this.#selectedServerId === undefined\n\t\t\t\t? \"\"\n\t\t\t\t: theme.fg(\"dim\", `Server: ${this.#selectedServerId}\\nSession: ${this.#sessionId}`),\n\t\t);\n\t\tthis.#statusContainer.clear();\n\t\tif (this.#status.length > 0) {\n\t\t\tthis.#statusContainer.addChild(new Text(theme.fg(\"dim\", this.#status), 1, 0));\n\t\t}\n\t\tif (this.#chatView !== undefined) this.#statusContainer.addChild(this.#chatView.status);\n\t\tthis.#footerComponent.setText(theme.fg(\"dim\", this.#footer()));\n\t\tthis.#editorContainer.clear();\n\t\tif (this.#screen === \"select\" && this.#selection !== undefined) {\n\t\t\tthis.#chatInput.focused = false;\n\t\t\tconst selector = new Container();\n\t\t\tselector.addChild(new Text(theme.bold(this.#selection.title), 1, 1));\n\t\t\tconst items = [...this.#selection.items];\n\t\t\tthis.#selectList = new SelectList(items, Math.min(Math.max(items.length, 1), 12), selectTheme);\n\t\t\tconst selectedIndex = items.findIndex((item) => item.value === this.#selection?.selectedValue);\n\t\t\tif (selectedIndex >= 0) this.#selectList.setSelectedIndex(selectedIndex);\n\t\t\tthis.#selectList.onSelect = (item) => this.#completeSelection(item.value);\n\t\t\tthis.#selectList.onCancel = () => this.#completeSelection(undefined);\n\t\t\tselector.addChild(this.#selectList);\n\t\t\tthis.#editorContainer.addChild(selector);\n\t\t} else {\n\t\t\tthis.#selectList = undefined;\n\t\t\tthis.#chatInput.focused = !this.#busy;\n\t\t\tthis.#editorContainer.addChild(this.#chatInput);\n\t\t}\n\t\tthis.#layoutRoot.invalidate();\n\t\tthis.#requestRender();\n\t}\n\n\t#select(title: string, items: readonly SelectItem[], selectedValue?: string): Promise<string | undefined> {\n\t\tif (this.#selection !== undefined) throw new Error(\"A slash command selector is already active\");\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.#selection = { title, items, ...(selectedValue === undefined ? {} : { selectedValue }), resolve };\n\t\t\tthis.#screen = \"select\";\n\t\t\tthis.#rebuild();\n\t\t});\n\t}\n\n\t#completeSelection(value: string | undefined): void {\n\t\tconst selection = this.#selection;\n\t\tif (selection === undefined) return;\n\t\tthis.#selection = undefined;\n\t\tthis.#screen = \"chat\";\n\t\tselection.resolve(value);\n\t\tif (!this.#closed) this.#rebuild();\n\t}\n\n\t#updateAutocomplete(): void {\n\t\tconst commands = this.#selectedSlashCommands()?.list() ?? [];\n\t\tthis.#chatInput.setAutocompleteProvider(\n\t\t\tnew CombinedAutocompleteProvider(\n\t\t\t\tcommands.map((command) => ({\n\t\t\t\t\tname: command.name,\n\t\t\t\t\tdescription: command.description,\n\t\t\t\t\t...(command.argumentHint === undefined ? {} : { argumentHint: command.argumentHint }),\n\t\t\t\t\t...(command.getArgumentCompletions === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tgetArgumentCompletions: async (prefix: string) => {\n\t\t\t\t\t\t\t\t\tconst items = await command.getArgumentCompletions!(prefix);\n\t\t\t\t\t\t\t\t\treturn items === null ? null : [...items];\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t})),\n\t\t\t\tprocess.cwd(),\n\t\t\t),\n\t\t);\n\t\tthis.#requestRender();\n\t}\n\n\t#selectedSlashCommands(): SlashCommands | undefined {\n\t\treturn this.#slashCommands;\n\t}\n\n\t#handleConnectionState(serverId: string, state: ServerConnectionState): void {\n\t\tif (this.#closed || this.#selectedServerId !== serverId) return;\n\t\tif (state.status === \"connected\") {\n\t\t\tif (this.#laneUnsubscribe === undefined) {\n\t\t\t\tthis.#busy = true;\n\t\t\t\tthis.#status = \"Reattaching Session…\";\n\t\t\t\tthis.#rebuild();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis.#busy = true;\n\t\tthis.#status = state.status === \"connecting\" ? \"Reconnecting to Radius…\" : \"Radius disconnected; retrying…\";\n\t\tthis.#queueRecovery(() => this.#closeLane());\n\t\tthis.#rebuild();\n\t}\n\n\t#handleAttachmentState(feature: SessionFeature, state: SessionAttachmentState): void {\n\t\tif (this.#closed || this.#selectedServerId !== feature.serverId || this.#sessionId === undefined) return;\n\t\tif (state.status === \"attached\" && state.sessionId === this.#sessionId) {\n\t\t\tthis.#queueRecovery(async () => {\n\t\t\t\tif (this.#laneUnsubscribe === undefined) await this.#openLane(feature);\n\t\t\t\tthis.#busy = false;\n\t\t\t\tthis.#status = \"\";\n\t\t\t\tthis.#rebuild();\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (state.status === \"attaching\" && state.sessionId === this.#sessionId) {\n\t\t\tthis.#busy = true;\n\t\t\tthis.#status = \"Reattaching Session…\";\n\t\t\tthis.#rebuild();\n\t\t}\n\t}\n\n\t#queueRecovery(operation: () => Promise<void>): void {\n\t\tthis.#recoveryTransition = this.#recoveryTransition\n\t\t\t.then(async () => {\n\t\t\t\tif (!this.#closed) await operation();\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (this.#closed) return;\n\t\t\t\tthis.#busy = true;\n\t\t\t\tthis.#status = `Reconnect error: ${message(error)}`;\n\t\t\t\tthis.#rebuild();\n\t\t\t});\n\t}\n\n\tasync #openLane(feature: SessionFeature): Promise<void> {\n\t\tawait this.#closeLane();\n\t\tconst view = new ExperimentalChatView(this.#ui, process.cwd());\n\t\tthis.#chatView = view;\n\t\tthis.#documentContainer.addChild(this.#sessionHeading);\n\t\tthis.#documentContainer.addChild(view.transcript);\n\t\tthis.#pendingMessagesContainer.addChild(view.pendingMessages);\n\t\tthis.#laneUnsubscribe = feature.transcript.state.subscribe((value) => {\n\t\t\tif (value.snapshot === null) return;\n\t\t\tview.apply(value.snapshot);\n\t\t\tthis.#rebuild();\n\t\t});\n\t\tif (feature.transcript.state.value?.snapshot === null || feature.transcript.state.value?.snapshot === undefined) {\n\t\t\tawait this.#closeLane();\n\t\t\tthrow new Error(\"Transcript has no initialized snapshot\");\n\t\t}\n\t}\n\n\tasync #closeLane(): Promise<void> {\n\t\tthis.#laneUnsubscribe?.();\n\t\tthis.#laneUnsubscribe = undefined;\n\t\tthis.#chatView?.dispose();\n\t\tthis.#chatView = undefined;\n\t\tthis.#documentContainer.clear();\n\t\tthis.#pendingMessagesContainer.clear();\n\t\tthis.#statusContainer.clear();\n\t}\n\n\tasync #runPrompt(messageText: string): Promise<void> {\n\t\tconst prompt = messageText.trim();\n\t\tif (prompt.length === 0) return;\n\t\tif (prompt.startsWith(\"/\")) {\n\t\t\tconst separator = prompt.indexOf(\" \");\n\t\t\tconst name = prompt.slice(1, separator === -1 ? undefined : separator);\n\t\t\tconst args = separator === -1 ? \"\" : prompt.slice(separator + 1).trim();\n\t\t\tawait this.#executeSlashCommand(name, args);\n\t\t\treturn;\n\t\t}\n\t\tthis.#chatInput.setText(\"\");\n\t\ttry {\n\t\t\tawait this.#submitPrompt(prompt);\n\t\t} catch (error) {\n\t\t\tthis.#status = `Error: ${message(error)}`;\n\t\t\tthis.#rebuild();\n\t\t}\n\t}\n\n\tasync #executeSlashCommand(name: string, args: string): Promise<void> {\n\t\tconst command = this.#selectedSlashCommands()\n\t\t\t?.list()\n\t\t\t.find((candidate) => candidate.name === name);\n\t\tthis.#chatInput.setText(\"\");\n\t\tif (command === undefined) {\n\t\t\tthis.#status = `Unknown slash command: /${name}`;\n\t\t\tthis.#rebuild();\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst result = await command.run(args, BACKGROUND_CONTEXT);\n\t\t\tif (result !== undefined) {\n\t\t\t\tif (\"entryId\" in result) this.#reportQueue(result);\n\t\t\t\telse this.#reportOperation(result);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.#status = `Error: ${message(error)}`;\n\t\t\tthis.#rebuild();\n\t\t}\n\t}\n\n\tasync #submitPrompt(prompt: string): Promise<void> {\n\t\tconst controller = this.#selectedController();\n\t\tif (controller === undefined) throw new Error(\"No Session AgentController service is available\");\n\t\tconst operation = this.#laneSnapshot()?.operation;\n\t\tconst running = operation !== null && operation !== undefined;\n\t\tthis.#status = running ? \"Queueing steering message…\" : \"Running turn…\";\n\t\tthis.#rebuild();\n\t\tif (running) this.#reportQueue(await controller.steer({ message: prompt, images: null }, BACKGROUND_CONTEXT));\n\t\telse this.#reportOperation(await controller.prompt({ message: prompt, images: null }, BACKGROUND_CONTEXT));\n\t}\n\n\tasync #queueFollowUp(text: string): Promise<void> {\n\t\tconst controller = this.#selectedController();\n\t\tif (controller === undefined) return;\n\t\ttry {\n\t\t\tthis.#status = \"Queueing follow-up…\";\n\t\t\tthis.#rebuild();\n\t\t\tthis.#reportQueue(await controller.followUp({ message: text, images: null }, BACKGROUND_CONTEXT));\n\t\t} catch (error) {\n\t\t\tthis.#status = `Error: ${message(error)}`;\n\t\t\tthis.#rebuild();\n\t\t}\n\t}\n\n\t#reportOperation(response: AgentOperationResponse): void {\n\t\tthis.#status = response.accepted\n\t\t\t? response.error === null\n\t\t\t\t? \"\"\n\t\t\t\t: `Operation failed: ${response.error.message}`\n\t\t\t: `Operation rejected: ${response.error.message}`;\n\t\tthis.#rebuild();\n\t}\n\n\t#reportQueue(response: AgentQueueResponse): void {\n\t\tthis.#status = response.accepted ? `Queued ${response.entryId}.` : `Message rejected: ${response.error.message}`;\n\t\tthis.#rebuild();\n\t}\n\n\t#interrupt(): void {\n\t\tconst operation = this.#laneSnapshot()?.operation;\n\t\tconst controller = this.#selectedController();\n\t\tif (operation === null || operation === undefined || controller === undefined) return;\n\t\tthis.#status = `Aborting ${operation.id}…`;\n\t\tthis.#rebuild();\n\t\tvoid controller.requestAbort(operation.id, BACKGROUND_CONTEXT).catch((error: unknown) => {\n\t\t\tthis.#status = `Error: ${message(error)}`;\n\t\t\tthis.#rebuild();\n\t\t});\n\t}\n\n\t#selectedController(): AgentController | undefined {\n\t\treturn this.#controller;\n\t}\n\n\t#laneSnapshot() {\n\t\tconst snapshot = this.#session?.transcript.state.value?.snapshot;\n\t\treturn snapshot === null ? undefined : snapshot;\n\t}\n\n\t#footer(): string {\n\t\tconst snapshot = this.#laneSnapshot();\n\t\tif (!snapshot) return \"/model · /thinking · /compact · /reload\";\n\t\treturn `${snapshot.configuration.model.provider}/${snapshot.configuration.model.modelId} · thinking:${snapshot.configuration.thinkingLevel} · ${snapshot.stats.messageCount} messages · /model · /thinking · /compact · /reload`;\n\t}\n}\n\nasync function prepareClientSession(\n\tcommand: ClientCommand,\n\tservers: readonly ClientTuiServer[],\n): Promise<PreparedClientSession> {\n\tconst opened = servers.map((server) => ({\n\t\tserver,\n\t\tservices: server.server.open({\n\t\t\tservices: [SessionDirectory, SessionManagement, PresentationPlugins],\n\t\t\tassertAccess() {},\n\t\t\tonError() {},\n\t\t}),\n\t}));\n\ttry {\n\t\tconst features = opened.map(({ server, services }) => ({\n\t\t\tserver,\n\t\t\tdirectory: services.use(SessionDirectory),\n\t\t\tmanagement: services.use(SessionManagement),\n\t\t\tplugins: services.use(PresentationPlugins),\n\t\t}));\n\t\tawait Promise.all(opened.map(({ services }) => services.ready(BACKGROUND_CONTEXT)));\n\t\tlet selected:\n\t\t\t| {\n\t\t\t\t\treadonly server: ClientTuiServer;\n\t\t\t\t\treadonly management: SessionManagement;\n\t\t\t\t\treadonly plugins: PresentationPlugins;\n\t\t\t\t\treadonly summary: SessionSummary;\n\t\t\t }\n\t\t\t| undefined;\n\t\tif (command.sessionId !== undefined) {\n\t\t\tconst matches = features.flatMap((feature) =>\n\t\t\t\t(feature.directory.state.value?.sessions ?? [])\n\t\t\t\t\t.filter((session) => session.sessionId === command.sessionId)\n\t\t\t\t\t.map((summary) => ({\n\t\t\t\t\t\tserver: feature.server,\n\t\t\t\t\t\tmanagement: feature.management,\n\t\t\t\t\t\tplugins: feature.plugins,\n\t\t\t\t\t\tsummary,\n\t\t\t\t\t})),\n\t\t\t);\n\t\t\tif (matches.length > 1) throw new Error(`Session ${command.sessionId} is available from more than one server`);\n\t\t\tselected = matches[0];\n\t\t\tif (selected === undefined) {\n\t\t\t\tif (command.connect?.transport === \"radius\") {\n\t\t\t\t\tthrow new Error(`Remote server does not contain Session ${command.sessionId}`);\n\t\t\t\t}\n\t\t\t\tconst feature = requireSingleServer(features);\n\t\t\t\tselected = {\n\t\t\t\t\tserver: feature.server,\n\t\t\t\t\tmanagement: feature.management,\n\t\t\t\t\tplugins: feature.plugins,\n\t\t\t\t\tsummary: await feature.management.create({ id: command.sessionId }, BACKGROUND_CONTEXT),\n\t\t\t\t};\n\t\t\t}\n\t\t} else if (command.continue === true || command.resume === true) {\n\t\t\tselected = features\n\t\t\t\t.flatMap((feature) =>\n\t\t\t\t\t(feature.directory.state.value?.sessions ?? []).map((summary) => ({\n\t\t\t\t\t\tserver: feature.server,\n\t\t\t\t\t\tmanagement: feature.management,\n\t\t\t\t\t\tplugins: feature.plugins,\n\t\t\t\t\t\tsummary,\n\t\t\t\t\t})),\n\t\t\t\t)\n\t\t\t\t.sort(\n\t\t\t\t\t(left, right) =>\n\t\t\t\t\t\tright.summary.createdAt - left.summary.createdAt ||\n\t\t\t\t\t\tleft.summary.serverId.localeCompare(right.summary.serverId) ||\n\t\t\t\t\t\tleft.summary.sessionId.localeCompare(right.summary.sessionId),\n\t\t\t\t)[0];\n\t\t}\n\t\tif (selected === undefined) {\n\t\t\tconst feature = requireSingleServer(features);\n\t\t\tselected = {\n\t\t\t\tserver: feature.server,\n\t\t\t\tmanagement: feature.management,\n\t\t\t\tplugins: feature.plugins,\n\t\t\t\tsummary: await feature.management.create({}, BACKGROUND_CONTEXT),\n\t\t\t};\n\t\t}\n\t\tconst presentationPlugins = await selected.plugins.prepareSession(\n\t\t\t{\n\t\t\t\tsessionId: selected.summary.sessionId,\n\t\t\t\tpackagePaths: command.pluginPackages?.map((packagePath) => resolve(packagePath)) ?? null,\n\t\t\t},\n\t\t\tBACKGROUND_CONTEXT,\n\t\t);\n\t\tawait selected.management.attach(selected.summary.sessionId, BACKGROUND_CONTEXT);\n\t\tawait selected.server.session.whenAttached(selected.summary.sessionId, BACKGROUND_CONTEXT);\n\t\treturn {\n\t\t\tserver: selected.server,\n\t\t\tsummary: selected.summary,\n\t\t\tpresentationPlugins,\n\t\t};\n\t} finally {\n\t\tawait Promise.allSettled(opened.map(({ services }) => services.dispose(BACKGROUND_CONTEXT)));\n\t}\n}\n\nexport async function runClientTui(command: ClientCommand, options: RunClientTuiOptions = {}): Promise<void> {\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst settingsManager = SettingsManager.create(cwd, agentDir);\n\tconst resourceLoader = new DefaultResourceLoader({\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t\tnoExtensions: true,\n\t\tnoSkills: true,\n\t\tnoPromptTemplates: true,\n\t\tnoContextFiles: true,\n\t});\n\tawait resourceLoader.reload();\n\tsetRegisteredThemes(resourceLoader.getThemes().themes);\n\tconst runtime = await openClientRuntime(command, options);\n\tconst tui = createInteractiveTui({\n\t\ttuiMode: \"fullscreen\",\n\t\tshowHardwareCursor: settingsManager.getShowHardwareCursor(),\n\t\tlogDirectory: agentDir,\n\t});\n\ttui.setClearOnShrink(settingsManager.getClearOnShrink());\n\tlet component: ExperimentalClientTui | undefined;\n\tlet tuiStarted = false;\n\tconst themeController = new InteractiveThemeController(tui, {\n\t\tgetSettingsManager: () => settingsManager,\n\t\tshowError: (error) => component?.showError(error),\n\t\tonChanged: () => component?.refreshTheme(),\n\t});\n\ttry {\n\t\tlet finish!: () => void;\n\t\tconst finished = new Promise<void>((resolve) => {\n\t\t\tfinish = () => {\n\t\t\t\tthemeController.disableAutoSync();\n\t\t\t\tif (tuiStarted) {\n\t\t\t\t\ttui.stop();\n\t\t\t\t\ttuiStarted = false;\n\t\t\t\t}\n\t\t\t\tresolve();\n\t\t\t};\n\t\t});\n\t\tcomponent = await ExperimentalClientTui.create({\n\t\t\tcommand,\n\t\t\tui: tui,\n\t\t\tservers: runtime.servers.map((server) => ({\n\t\t\t\tserverId: server.route.serverId,\n\t\t\t\tradius: server.route.transport === \"radius\",\n\t\t\t\tserver: server.server,\n\t\t\t\tsession: server.session,\n\t\t\t})),\n\t\t\tfacetLoader: options.facetLoader,\n\t\t\trequestRender: () => tui.requestRender(),\n\t\t\tfinish,\n\t\t});\n\t\ttui.addChild(component);\n\t\ttui.setLayoutRoot(component.layoutRoot);\n\t\ttui.setFocus(component);\n\t\ttuiStarted = true;\n\t\ttui.start();\n\t\tawait themeController.applyFromSettings();\n\t\tawait finished;\n\t} finally {\n\t\tthemeController.dispose();\n\t\tstopThemeWatcher();\n\t\tif (tuiStarted) tui.stop();\n\t\tawait component?.close();\n\t\tawait runtime.dispose();\n\t}\n}\n\nfunction requireSingleServer<T>(features: readonly T[]): T {\n\tif (features.length !== 1) throw new Error(\"Starting a Session requires exactly one server\");\n\treturn features[0]!;\n}\n\nfunction message(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type LaneWatchEvent } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { ClientCommand } from "../cli/experimental/commands/client.ts";
|
|
3
|
+
import type { SessionAddress } from "./services/sessions.ts";
|
|
4
|
+
export type ClientResult = {
|
|
5
|
+
readonly kind: "list";
|
|
6
|
+
readonly sessions: readonly SessionAddress[];
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: "attached";
|
|
9
|
+
readonly serverId: string;
|
|
10
|
+
readonly sessionId: string;
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: "prompted";
|
|
13
|
+
readonly serverId: string;
|
|
14
|
+
readonly sessionId: string;
|
|
15
|
+
readonly text: string;
|
|
16
|
+
};
|
|
17
|
+
export interface RunClientOptions {
|
|
18
|
+
/** Directory searched when --connect is omitted. Defaults to PI_SERVER_DIR or ~/.pi/server. */
|
|
19
|
+
readonly directory?: string;
|
|
20
|
+
/** Receives snapshot-ordered main-lane events while a prompt is active. */
|
|
21
|
+
readonly onEvent?: (event: LaneWatchEvent) => void | Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
/** Discover servers, then list Sessions, attach to one, or create one for a prompt. */
|
|
24
|
+
export declare function runClient(command: ClientCommand, options?: RunClientOptions): Promise<ClientResult>;
|
|
25
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/experimental/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAExF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAG5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,MAAM,YAAY,GACrB;IACA,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;CAC5C,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACpF;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/G,MAAM,WAAW,gBAAgB;IAChC,+FAA+F;IAC/F,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AAED,uFAAuF;AACvF,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,YAAY,CAAC,CA4F7G","sourcesContent":["import { resolve } from \"node:path\";\nimport { BACKGROUND_CONTEXT, type LaneWatchEvent } from \"@earendil-works/pi-agent-core\";\nimport type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport type { ClientCommand } from \"../cli/experimental/commands/client.ts\";\nimport { activateBuiltinClientServices, openClientRuntime } from \"./client-runtime.ts\";\nimport type { AgentOperationResponse } from \"./services/agent-controller.ts\";\nimport type { SessionAddress } from \"./services/sessions.ts\";\n\nexport type ClientResult =\n\t| {\n\t\t\treadonly kind: \"list\";\n\t\t\treadonly sessions: readonly SessionAddress[];\n\t }\n\t| { readonly kind: \"attached\"; readonly serverId: string; readonly sessionId: string }\n\t| { readonly kind: \"prompted\"; readonly serverId: string; readonly sessionId: string; readonly text: string };\n\nexport interface RunClientOptions {\n\t/** Directory searched when --connect is omitted. Defaults to PI_SERVER_DIR or ~/.pi/server. */\n\treadonly directory?: string;\n\t/** Receives snapshot-ordered main-lane events while a prompt is active. */\n\treadonly onEvent?: (event: LaneWatchEvent) => void | Promise<void>;\n}\n\n/** Discover servers, then list Sessions, attach to one, or create one for a prompt. */\nexport async function runClient(command: ClientCommand, options: RunClientOptions = {}): Promise<ClientResult> {\n\tconst runtime = await openClientRuntime(command, { directory: options.directory });\n\ttry {\n\t\tconst discovered = await Promise.all(runtime.servers.map(activateBuiltinClientServices));\n\t\tlet sessionId = command.sessionId;\n\t\tif (sessionId === undefined && command.prompt === undefined) {\n\t\t\treturn {\n\t\t\t\tkind: \"list\",\n\t\t\t\tsessions: discovered\n\t\t\t\t\t.flatMap(({ route, directory }) =>\n\t\t\t\t\t\tdirectory.state.value!.sessions.map(({ sessionId }) => ({ serverId: route.serverId, sessionId })),\n\t\t\t\t\t)\n\t\t\t\t\t.sort(\n\t\t\t\t\t\t(left, right) =>\n\t\t\t\t\t\t\tleft.serverId.localeCompare(right.serverId) || left.sessionId.localeCompare(right.sessionId),\n\t\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\tlet match: (typeof discovered)[number];\n\t\tif (sessionId === undefined) {\n\t\t\tif (discovered.length !== 1) {\n\t\t\t\tthrow new Error(\"Client prompt requires exactly one discovered server to create a Session\");\n\t\t\t}\n\t\t\tmatch = discovered[0]!;\n\t\t\tsessionId = (await match.management.create({}, BACKGROUND_CONTEXT)).sessionId;\n\t\t} else {\n\t\t\tconst selectedSessionId = sessionId;\n\t\t\tconst matches = discovered.filter((candidate) =>\n\t\t\t\tcandidate.directory.state.value!.sessions.some(({ sessionId }) => sessionId === selectedSessionId),\n\t\t\t);\n\t\t\tif (matches.length > 1) {\n\t\t\t\tthrow new Error(`Session ${selectedSessionId} is available from more than one server`);\n\t\t\t}\n\t\t\tconst existing = matches[0];\n\t\t\tif (existing) {\n\t\t\t\tmatch = existing;\n\t\t\t} else {\n\t\t\t\tif (command.connect?.transport === \"radius\" || command.prompt === undefined || discovered.length !== 1) {\n\t\t\t\t\tthrow new Error(`No discovered server contains session ${selectedSessionId}`);\n\t\t\t\t}\n\t\t\t\tmatch = discovered[0]!;\n\t\t\t\tawait match.management.create({ id: selectedSessionId }, BACKGROUND_CONTEXT);\n\t\t\t}\n\t\t}\n\t\tawait match.plugins.prepareSession(\n\t\t\t{\n\t\t\t\tsessionId,\n\t\t\t\tpackagePaths: command.pluginPackages?.map((packagePath) => resolve(packagePath)) ?? null,\n\t\t\t},\n\t\t\tBACKGROUND_CONTEXT,\n\t\t);\n\t\tawait match.management.attach(sessionId, BACKGROUND_CONTEXT);\n\t\tif (command.prompt === undefined) {\n\t\t\treturn { kind: \"attached\", serverId: match.route.serverId, sessionId };\n\t\t}\n\n\t\tconst agent = match.agent;\n\t\tconst completedText = new Map<string, string>();\n\t\tlet deliveryTail = Promise.resolve();\n\t\tconst unsubscribe = match.transcript.state.subscribe((value, _context, delivery) => {\n\t\t\tif (delivery.kind !== \"update\" || value.event === null) return;\n\t\t\tconst event = value.event;\n\t\t\tdeliveryTail = deliveryTail.then(async () => {\n\t\t\t\tif (event.type === \"message_end\" && event.runId !== undefined && event.message.role === \"assistant\") {\n\t\t\t\t\tcompletedText.set(event.runId, messageText(event.message));\n\t\t\t\t}\n\t\t\t\tawait options.onEvent?.(event);\n\t\t\t});\n\t\t});\n\t\tif (match.transcript.state.value?.snapshot === null || match.transcript.state.value?.snapshot === undefined) {\n\t\t\tunsubscribe();\n\t\t\tthrow new Error(\"Transcript has no initialized snapshot\");\n\t\t}\n\t\tlet response: AgentOperationResponse;\n\t\ttry {\n\t\t\tresponse = await agent.prompt({ message: command.prompt, images: null }, BACKGROUND_CONTEXT);\n\t\t} finally {\n\t\t\tunsubscribe();\n\t\t\tawait deliveryTail;\n\t\t}\n\t\tif (!response.accepted) throw new Error(response.error.message);\n\t\tif (response.error !== null) throw new Error(response.error.message);\n\t\treturn {\n\t\t\tkind: \"prompted\",\n\t\t\tserverId: match.route.serverId,\n\t\t\tsessionId,\n\t\t\ttext: completedText.get(response.operationId) ?? \"\",\n\t\t};\n\t} finally {\n\t\tawait runtime.dispose();\n\t}\n}\n\nfunction messageText(message: AssistantMessage): string {\n\treturn message.content\n\t\t.filter((content) => content.type === \"text\")\n\t\t.map((content) => content.text)\n\t\t.join(\"\");\n}\n"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { BACKGROUND_CONTEXT } from "@earendil-works/pi-agent-core";
|
|
3
|
+
import { activateBuiltinClientServices, openClientRuntime } from "./client-runtime.js";
|
|
4
|
+
/** Discover servers, then list Sessions, attach to one, or create one for a prompt. */
|
|
5
|
+
export async function runClient(command, options = {}) {
|
|
6
|
+
const runtime = await openClientRuntime(command, { directory: options.directory });
|
|
7
|
+
try {
|
|
8
|
+
const discovered = await Promise.all(runtime.servers.map(activateBuiltinClientServices));
|
|
9
|
+
let sessionId = command.sessionId;
|
|
10
|
+
if (sessionId === undefined && command.prompt === undefined) {
|
|
11
|
+
return {
|
|
12
|
+
kind: "list",
|
|
13
|
+
sessions: discovered
|
|
14
|
+
.flatMap(({ route, directory }) => directory.state.value.sessions.map(({ sessionId }) => ({ serverId: route.serverId, sessionId })))
|
|
15
|
+
.sort((left, right) => left.serverId.localeCompare(right.serverId) || left.sessionId.localeCompare(right.sessionId)),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
let match;
|
|
19
|
+
if (sessionId === undefined) {
|
|
20
|
+
if (discovered.length !== 1) {
|
|
21
|
+
throw new Error("Client prompt requires exactly one discovered server to create a Session");
|
|
22
|
+
}
|
|
23
|
+
match = discovered[0];
|
|
24
|
+
sessionId = (await match.management.create({}, BACKGROUND_CONTEXT)).sessionId;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const selectedSessionId = sessionId;
|
|
28
|
+
const matches = discovered.filter((candidate) => candidate.directory.state.value.sessions.some(({ sessionId }) => sessionId === selectedSessionId));
|
|
29
|
+
if (matches.length > 1) {
|
|
30
|
+
throw new Error(`Session ${selectedSessionId} is available from more than one server`);
|
|
31
|
+
}
|
|
32
|
+
const existing = matches[0];
|
|
33
|
+
if (existing) {
|
|
34
|
+
match = existing;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
if (command.connect?.transport === "radius" || command.prompt === undefined || discovered.length !== 1) {
|
|
38
|
+
throw new Error(`No discovered server contains session ${selectedSessionId}`);
|
|
39
|
+
}
|
|
40
|
+
match = discovered[0];
|
|
41
|
+
await match.management.create({ id: selectedSessionId }, BACKGROUND_CONTEXT);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
await match.plugins.prepareSession({
|
|
45
|
+
sessionId,
|
|
46
|
+
packagePaths: command.pluginPackages?.map((packagePath) => resolve(packagePath)) ?? null,
|
|
47
|
+
}, BACKGROUND_CONTEXT);
|
|
48
|
+
await match.management.attach(sessionId, BACKGROUND_CONTEXT);
|
|
49
|
+
if (command.prompt === undefined) {
|
|
50
|
+
return { kind: "attached", serverId: match.route.serverId, sessionId };
|
|
51
|
+
}
|
|
52
|
+
const agent = match.agent;
|
|
53
|
+
const completedText = new Map();
|
|
54
|
+
let deliveryTail = Promise.resolve();
|
|
55
|
+
const unsubscribe = match.transcript.state.subscribe((value, _context, delivery) => {
|
|
56
|
+
if (delivery.kind !== "update" || value.event === null)
|
|
57
|
+
return;
|
|
58
|
+
const event = value.event;
|
|
59
|
+
deliveryTail = deliveryTail.then(async () => {
|
|
60
|
+
if (event.type === "message_end" && event.runId !== undefined && event.message.role === "assistant") {
|
|
61
|
+
completedText.set(event.runId, messageText(event.message));
|
|
62
|
+
}
|
|
63
|
+
await options.onEvent?.(event);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
if (match.transcript.state.value?.snapshot === null || match.transcript.state.value?.snapshot === undefined) {
|
|
67
|
+
unsubscribe();
|
|
68
|
+
throw new Error("Transcript has no initialized snapshot");
|
|
69
|
+
}
|
|
70
|
+
let response;
|
|
71
|
+
try {
|
|
72
|
+
response = await agent.prompt({ message: command.prompt, images: null }, BACKGROUND_CONTEXT);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
unsubscribe();
|
|
76
|
+
await deliveryTail;
|
|
77
|
+
}
|
|
78
|
+
if (!response.accepted)
|
|
79
|
+
throw new Error(response.error.message);
|
|
80
|
+
if (response.error !== null)
|
|
81
|
+
throw new Error(response.error.message);
|
|
82
|
+
return {
|
|
83
|
+
kind: "prompted",
|
|
84
|
+
serverId: match.route.serverId,
|
|
85
|
+
sessionId,
|
|
86
|
+
text: completedText.get(response.operationId) ?? "",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
await runtime.dispose();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function messageText(message) {
|
|
94
|
+
return message.content
|
|
95
|
+
.filter((content) => content.type === "text")
|
|
96
|
+
.map((content) => content.text)
|
|
97
|
+
.join("");
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/experimental/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from \"node:path\";\nimport { BACKGROUND_CONTEXT, type LaneWatchEvent } from \"@earendil-works/pi-agent-core\";\nimport type { AssistantMessage } from \"@earendil-works/pi-ai\";\nimport type { ClientCommand } from \"../cli/experimental/commands/client.ts\";\nimport { activateBuiltinClientServices, openClientRuntime } from \"./client-runtime.ts\";\nimport type { AgentOperationResponse } from \"./services/agent-controller.ts\";\nimport type { SessionAddress } from \"./services/sessions.ts\";\n\nexport type ClientResult =\n\t| {\n\t\t\treadonly kind: \"list\";\n\t\t\treadonly sessions: readonly SessionAddress[];\n\t }\n\t| { readonly kind: \"attached\"; readonly serverId: string; readonly sessionId: string }\n\t| { readonly kind: \"prompted\"; readonly serverId: string; readonly sessionId: string; readonly text: string };\n\nexport interface RunClientOptions {\n\t/** Directory searched when --connect is omitted. Defaults to PI_SERVER_DIR or ~/.pi/server. */\n\treadonly directory?: string;\n\t/** Receives snapshot-ordered main-lane events while a prompt is active. */\n\treadonly onEvent?: (event: LaneWatchEvent) => void | Promise<void>;\n}\n\n/** Discover servers, then list Sessions, attach to one, or create one for a prompt. */\nexport async function runClient(command: ClientCommand, options: RunClientOptions = {}): Promise<ClientResult> {\n\tconst runtime = await openClientRuntime(command, { directory: options.directory });\n\ttry {\n\t\tconst discovered = await Promise.all(runtime.servers.map(activateBuiltinClientServices));\n\t\tlet sessionId = command.sessionId;\n\t\tif (sessionId === undefined && command.prompt === undefined) {\n\t\t\treturn {\n\t\t\t\tkind: \"list\",\n\t\t\t\tsessions: discovered\n\t\t\t\t\t.flatMap(({ route, directory }) =>\n\t\t\t\t\t\tdirectory.state.value!.sessions.map(({ sessionId }) => ({ serverId: route.serverId, sessionId })),\n\t\t\t\t\t)\n\t\t\t\t\t.sort(\n\t\t\t\t\t\t(left, right) =>\n\t\t\t\t\t\t\tleft.serverId.localeCompare(right.serverId) || left.sessionId.localeCompare(right.sessionId),\n\t\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\tlet match: (typeof discovered)[number];\n\t\tif (sessionId === undefined) {\n\t\t\tif (discovered.length !== 1) {\n\t\t\t\tthrow new Error(\"Client prompt requires exactly one discovered server to create a Session\");\n\t\t\t}\n\t\t\tmatch = discovered[0]!;\n\t\t\tsessionId = (await match.management.create({}, BACKGROUND_CONTEXT)).sessionId;\n\t\t} else {\n\t\t\tconst selectedSessionId = sessionId;\n\t\t\tconst matches = discovered.filter((candidate) =>\n\t\t\t\tcandidate.directory.state.value!.sessions.some(({ sessionId }) => sessionId === selectedSessionId),\n\t\t\t);\n\t\t\tif (matches.length > 1) {\n\t\t\t\tthrow new Error(`Session ${selectedSessionId} is available from more than one server`);\n\t\t\t}\n\t\t\tconst existing = matches[0];\n\t\t\tif (existing) {\n\t\t\t\tmatch = existing;\n\t\t\t} else {\n\t\t\t\tif (command.connect?.transport === \"radius\" || command.prompt === undefined || discovered.length !== 1) {\n\t\t\t\t\tthrow new Error(`No discovered server contains session ${selectedSessionId}`);\n\t\t\t\t}\n\t\t\t\tmatch = discovered[0]!;\n\t\t\t\tawait match.management.create({ id: selectedSessionId }, BACKGROUND_CONTEXT);\n\t\t\t}\n\t\t}\n\t\tawait match.plugins.prepareSession(\n\t\t\t{\n\t\t\t\tsessionId,\n\t\t\t\tpackagePaths: command.pluginPackages?.map((packagePath) => resolve(packagePath)) ?? null,\n\t\t\t},\n\t\t\tBACKGROUND_CONTEXT,\n\t\t);\n\t\tawait match.management.attach(sessionId, BACKGROUND_CONTEXT);\n\t\tif (command.prompt === undefined) {\n\t\t\treturn { kind: \"attached\", serverId: match.route.serverId, sessionId };\n\t\t}\n\n\t\tconst agent = match.agent;\n\t\tconst completedText = new Map<string, string>();\n\t\tlet deliveryTail = Promise.resolve();\n\t\tconst unsubscribe = match.transcript.state.subscribe((value, _context, delivery) => {\n\t\t\tif (delivery.kind !== \"update\" || value.event === null) return;\n\t\t\tconst event = value.event;\n\t\t\tdeliveryTail = deliveryTail.then(async () => {\n\t\t\t\tif (event.type === \"message_end\" && event.runId !== undefined && event.message.role === \"assistant\") {\n\t\t\t\t\tcompletedText.set(event.runId, messageText(event.message));\n\t\t\t\t}\n\t\t\t\tawait options.onEvent?.(event);\n\t\t\t});\n\t\t});\n\t\tif (match.transcript.state.value?.snapshot === null || match.transcript.state.value?.snapshot === undefined) {\n\t\t\tunsubscribe();\n\t\t\tthrow new Error(\"Transcript has no initialized snapshot\");\n\t\t}\n\t\tlet response: AgentOperationResponse;\n\t\ttry {\n\t\t\tresponse = await agent.prompt({ message: command.prompt, images: null }, BACKGROUND_CONTEXT);\n\t\t} finally {\n\t\t\tunsubscribe();\n\t\t\tawait deliveryTail;\n\t\t}\n\t\tif (!response.accepted) throw new Error(response.error.message);\n\t\tif (response.error !== null) throw new Error(response.error.message);\n\t\treturn {\n\t\t\tkind: \"prompted\",\n\t\t\tserverId: match.route.serverId,\n\t\t\tsessionId,\n\t\t\ttext: completedText.get(response.operationId) ?? \"\",\n\t\t};\n\t} finally {\n\t\tawait runtime.dispose();\n\t}\n}\n\nfunction messageText(message: AssistantMessage): string {\n\treturn message.content\n\t\t.filter((content) => content.type === \"text\")\n\t\t.map((content) => content.text)\n\t\t.join(\"\");\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator-entry.d.ts","sourceRoot":"","sources":["../../src/experimental/coordinator-entry.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { runCoordinatorProcess } from \"./coordinator.ts\";\nimport { consumeInternalProcessRole } from \"./process.ts\";\n\nconst role = consumeInternalProcessRole();\nif (role !== \"coordinator\") throw new Error(\"Coordinator entrypoint requires an internal coordinator invocation\");\nvoid runCoordinatorProcess(process.argv.slice(2)).catch((error: unknown) => {\n\tconsole.error(error);\n\tprocess.exit(1);\n});\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCoordinatorProcess } from "./coordinator.js";
|
|
3
|
+
import { consumeInternalProcessRole } from "./process.js";
|
|
4
|
+
const role = consumeInternalProcessRole();
|
|
5
|
+
if (role !== "coordinator")
|
|
6
|
+
throw new Error("Coordinator entrypoint requires an internal coordinator invocation");
|
|
7
|
+
void runCoordinatorProcess(process.argv.slice(2)).catch((error) => {
|
|
8
|
+
console.error(error);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=coordinator-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator-entry.js","sourceRoot":"","sources":["../../src/experimental/coordinator-entry.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,IAAI,GAAG,0BAA0B,EAAE,CAAC;AAC1C,IAAI,IAAI,KAAK,aAAa;IAAE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;AAClH,KAAK,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC;IAC3E,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAAA,CAChB,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { runCoordinatorProcess } from \"./coordinator.ts\";\nimport { consumeInternalProcessRole } from \"./process.ts\";\n\nconst role = consumeInternalProcessRole();\nif (role !== \"coordinator\") throw new Error(\"Coordinator entrypoint requires an internal coordinator invocation\");\nvoid runCoordinatorProcess(process.argv.slice(2)).catch((error: unknown) => {\n\tconsole.error(error);\n\tprocess.exit(1);\n});\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const COORDINATOR_PROTOCOL_VERSION = 3;
|
|
2
|
+
export type CoordinatorConnectionEvent = {
|
|
3
|
+
readonly type: "peer_connected";
|
|
4
|
+
readonly peerId: string;
|
|
5
|
+
} | {
|
|
6
|
+
readonly type: "peer_disconnected";
|
|
7
|
+
readonly peerId: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly type: "message";
|
|
10
|
+
readonly from: string;
|
|
11
|
+
readonly payload: unknown;
|
|
12
|
+
};
|
|
13
|
+
export interface CoordinatorConnectionOptions {
|
|
14
|
+
readonly controlPath: string;
|
|
15
|
+
readonly endpoint: string;
|
|
16
|
+
readonly serverConnectionId?: string;
|
|
17
|
+
}
|
|
18
|
+
/** The server-side endpoint of the coordinator's intentionally opaque message router. */
|
|
19
|
+
export declare class CoordinatorConnection {
|
|
20
|
+
#private;
|
|
21
|
+
readonly serverConnectionId: string;
|
|
22
|
+
readonly replaced: Promise<void>;
|
|
23
|
+
readonly peerIds: Set<string>;
|
|
24
|
+
constructor(options: CoordinatorConnectionOptions);
|
|
25
|
+
get controlPath(): string;
|
|
26
|
+
get wasReplaced(): boolean;
|
|
27
|
+
onEvent(listener: (event: CoordinatorConnectionEvent) => void): () => void;
|
|
28
|
+
connect(): Promise<void>;
|
|
29
|
+
send(peerId: string, payload: unknown): Promise<void>;
|
|
30
|
+
broadcast(payload: unknown): Promise<void>;
|
|
31
|
+
close(): void;
|
|
32
|
+
}
|
|
33
|
+
export interface CoordinatorStartupLease {
|
|
34
|
+
close(): void;
|
|
35
|
+
}
|
|
36
|
+
export declare function ensureCoordinator(publicPath: string, controlPath: string): Promise<CoordinatorStartupLease>;
|
|
37
|
+
export declare function runCoordinatorProcess(args: readonly string[]): Promise<void>;
|
|
38
|
+
//# sourceMappingURL=coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../../src/experimental/coordinator.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAiB9C,MAAM,MAAM,0BAA0B,GACnC;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAElF,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,yFAAyF;AACzF,qBAAa,qBAAqB;;IACjC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,QAAQ,CAAC,OAAO,cAAqB;IAYrC,YAAY,OAAO,EAAE,4BAA4B,EAOhD;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,GAAG,MAAM,IAAI,CAGzE;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB7B;IAED,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpD;IAED,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzC;IAED,KAAK,IAAI,IAAI,CASZ;CAgED;AAED,MAAM,WAAW,uBAAuB;IACvC,KAAK,IAAI,IAAI,CAAC;CACd;AAED,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAYjH;AAsGD,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAYlF","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"]}
|