@hansjm10/volt-coding-agent 0.0.0-bootstrap.0 → 0.1.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/BINARY-CAPABILITIES.md +28 -0
- package/CHANGELOG.md +4845 -0
- package/LICENSE +1 -1
- package/README.md +716 -3
- package/THIRD-PARTY-NOTICES.md +55 -0
- package/dist/LICENSES/clipboard-image-MIT.txt +9 -0
- package/dist/LICENSES/highlight.js-10.7.3-BSD-3-Clause.txt +29 -0
- package/dist/LICENSES/highlight.js-11.9.0-BSD-3-Clause.txt +29 -0
- package/dist/LICENSES/marked-18.0.5-LICENSE.txt +44 -0
- package/dist/LICENSES/run-jxa-MIT.txt +9 -0
- package/dist/cli/args.d.ts +60 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +414 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/config-selector.d.ts +14 -0
- package/dist/cli/config-selector.d.ts.map +1 -0
- package/dist/cli/config-selector.js +31 -0
- package/dist/cli/config-selector.js.map +1 -0
- package/dist/cli/file-processor.d.ts +15 -0
- package/dist/cli/file-processor.d.ts.map +1 -0
- package/dist/cli/file-processor.js +85 -0
- package/dist/cli/file-processor.js.map +1 -0
- package/dist/cli/initial-message.d.ts +18 -0
- package/dist/cli/initial-message.d.ts.map +1 -0
- package/dist/cli/initial-message.js +22 -0
- package/dist/cli/initial-message.js.map +1 -0
- package/dist/cli/list-models.d.ts +9 -0
- package/dist/cli/list-models.d.ts.map +1 -0
- package/dist/cli/list-models.js +98 -0
- package/dist/cli/list-models.js.map +1 -0
- package/dist/cli/project-trust.d.ts +10 -0
- package/dist/cli/project-trust.d.ts.map +1 -0
- package/dist/cli/project-trust.js +48 -0
- package/dist/cli/project-trust.js.map +1 -0
- package/dist/cli/session-picker.d.ts +9 -0
- package/dist/cli/session-picker.d.ts.map +1 -0
- package/dist/cli/session-picker.js +35 -0
- package/dist/cli/session-picker.js.map +1 -0
- package/dist/cli/startup-ui.d.ts +17 -0
- package/dist/cli/startup-ui.d.ts.map +1 -0
- package/dist/cli/startup-ui.js +133 -0
- package/dist/cli/startup-ui.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +18 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +85 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +487 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts +160 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -0
- package/dist/core/agent-session-runtime.js +397 -0
- package/dist/core/agent-session-runtime.js.map +1 -0
- package/dist/core/agent-session-services.d.ts +98 -0
- package/dist/core/agent-session-services.d.ts.map +1 -0
- package/dist/core/agent-session-services.js +125 -0
- package/dist/core/agent-session-services.js.map +1 -0
- package/dist/core/agent-session.d.ts +739 -0
- package/dist/core/agent-session.d.ts.map +1 -0
- package/dist/core/agent-session.js +3158 -0
- package/dist/core/agent-session.js.map +1 -0
- package/dist/core/auth-guidance.d.ts +5 -0
- package/dist/core/auth-guidance.d.ts.map +1 -0
- package/dist/core/auth-guidance.js +21 -0
- package/dist/core/auth-guidance.js.map +1 -0
- package/dist/core/auth-storage.d.ts +159 -0
- package/dist/core/auth-storage.d.ts.map +1 -0
- package/dist/core/auth-storage.js +509 -0
- package/dist/core/auth-storage.js.map +1 -0
- package/dist/core/bash-executor.d.ts +32 -0
- package/dist/core/bash-executor.d.ts.map +1 -0
- package/dist/core/bash-executor.js +111 -0
- package/dist/core/bash-executor.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts +92 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/core/compaction/branch-summarization.js +257 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +121 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -0
- package/dist/core/compaction/compaction.js +658 -0
- package/dist/core/compaction/compaction.js.map +1 -0
- package/dist/core/compaction/index.d.ts +7 -0
- package/dist/core/compaction/index.d.ts.map +1 -0
- package/dist/core/compaction/index.js +7 -0
- package/dist/core/compaction/index.js.map +1 -0
- package/dist/core/compaction/utils.d.ts +56 -0
- package/dist/core/compaction/utils.d.ts.map +1 -0
- package/dist/core/compaction/utils.js +271 -0
- package/dist/core/compaction/utils.js.map +1 -0
- package/dist/core/defaults.d.ts +3 -0
- package/dist/core/defaults.d.ts.map +1 -0
- package/dist/core/defaults.js +2 -0
- package/dist/core/defaults.js.map +1 -0
- package/dist/core/diagnostics.d.ts +15 -0
- package/dist/core/diagnostics.d.ts.map +1 -0
- package/dist/core/diagnostics.js +2 -0
- package/dist/core/diagnostics.js.map +1 -0
- package/dist/core/event-bus.d.ts +9 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +25 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/exec.d.ts +29 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +75 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/experimental.d.ts +2 -0
- package/dist/core/experimental.d.ts.map +1 -0
- package/dist/core/experimental.js +4 -0
- package/dist/core/experimental.js.map +1 -0
- package/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/core/export-html/ansi-to-html.js +249 -0
- package/dist/core/export-html/ansi-to-html.js.map +1 -0
- package/dist/core/export-html/index.d.ts +37 -0
- package/dist/core/export-html/index.d.ts.map +1 -0
- package/dist/core/export-html/index.js +234 -0
- package/dist/core/export-html/index.js.map +1 -0
- package/dist/core/export-html/template.css +1066 -0
- package/dist/core/export-html/template.html +55 -0
- package/dist/core/export-html/template.js +1864 -0
- package/dist/core/export-html/tool-renderer.d.ts +34 -0
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/core/export-html/tool-renderer.js +108 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +78 -0
- package/dist/core/extensions/index.d.ts +12 -0
- package/dist/core/extensions/index.d.ts.map +1 -0
- package/dist/core/extensions/index.js +9 -0
- package/dist/core/extensions/index.js.map +1 -0
- package/dist/core/extensions/loader.d.ts +25 -0
- package/dist/core/extensions/loader.d.ts.map +1 -0
- package/dist/core/extensions/loader.js +516 -0
- package/dist/core/extensions/loader.js.map +1 -0
- package/dist/core/extensions/runner.d.ts +180 -0
- package/dist/core/extensions/runner.d.ts.map +1 -0
- package/dist/core/extensions/runner.js +938 -0
- package/dist/core/extensions/runner.js.map +1 -0
- package/dist/core/extensions/types.d.ts +1215 -0
- package/dist/core/extensions/types.d.ts.map +1 -0
- package/dist/core/extensions/types.js +48 -0
- package/dist/core/extensions/types.js.map +1 -0
- package/dist/core/extensions/wrapper.d.ts +20 -0
- package/dist/core/extensions/wrapper.d.ts.map +1 -0
- package/dist/core/extensions/wrapper.js +22 -0
- package/dist/core/extensions/wrapper.js.map +1 -0
- package/dist/core/footer-data-provider.d.ts +54 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -0
- package/dist/core/footer-data-provider.js +338 -0
- package/dist/core/footer-data-provider.js.map +1 -0
- package/dist/core/host-actions.d.ts +107 -0
- package/dist/core/host-actions.d.ts.map +1 -0
- package/dist/core/host-actions.js +632 -0
- package/dist/core/host-actions.js.map +1 -0
- package/dist/core/host-interaction.d.ts +35 -0
- package/dist/core/host-interaction.d.ts.map +1 -0
- package/dist/core/host-interaction.js +2 -0
- package/dist/core/host-interaction.js.map +1 -0
- package/dist/core/http-dispatcher.d.ts +22 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -0
- package/dist/core/http-dispatcher.js +64 -0
- package/dist/core/http-dispatcher.js.map +1 -0
- package/dist/core/index.d.ts +18 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +17 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/keybindings.d.ts +373 -0
- package/dist/core/keybindings.d.ts.map +1 -0
- package/dist/core/keybindings.js +303 -0
- package/dist/core/keybindings.js.map +1 -0
- package/dist/core/lsp/client.d.ts +119 -0
- package/dist/core/lsp/client.d.ts.map +1 -0
- package/dist/core/lsp/client.js +711 -0
- package/dist/core/lsp/client.js.map +1 -0
- package/dist/core/lsp/config.d.ts +96 -0
- package/dist/core/lsp/config.d.ts.map +1 -0
- package/dist/core/lsp/config.js +206 -0
- package/dist/core/lsp/config.js.map +1 -0
- package/dist/core/lsp/index.d.ts +6 -0
- package/dist/core/lsp/index.d.ts.map +1 -0
- package/dist/core/lsp/index.js +6 -0
- package/dist/core/lsp/index.js.map +1 -0
- package/dist/core/lsp/manager.d.ts +122 -0
- package/dist/core/lsp/manager.d.ts.map +1 -0
- package/dist/core/lsp/manager.js +1136 -0
- package/dist/core/lsp/manager.js.map +1 -0
- package/dist/core/lsp/trace.d.ts +26 -0
- package/dist/core/lsp/trace.d.ts.map +1 -0
- package/dist/core/lsp/trace.js +98 -0
- package/dist/core/lsp/trace.js.map +1 -0
- package/dist/core/lsp/workspace-edit.d.ts +60 -0
- package/dist/core/lsp/workspace-edit.d.ts.map +1 -0
- package/dist/core/lsp/workspace-edit.js +71 -0
- package/dist/core/lsp/workspace-edit.js.map +1 -0
- package/dist/core/mcp/audit.d.ts +39 -0
- package/dist/core/mcp/audit.d.ts.map +1 -0
- package/dist/core/mcp/audit.js +35 -0
- package/dist/core/mcp/audit.js.map +1 -0
- package/dist/core/mcp/auth.d.ts +7 -0
- package/dist/core/mcp/auth.d.ts.map +1 -0
- package/dist/core/mcp/auth.js +56 -0
- package/dist/core/mcp/auth.js.map +1 -0
- package/dist/core/mcp/client-factory.d.ts +20 -0
- package/dist/core/mcp/client-factory.d.ts.map +1 -0
- package/dist/core/mcp/client-factory.js +200 -0
- package/dist/core/mcp/client-factory.js.map +1 -0
- package/dist/core/mcp/config-loader.d.ts +9 -0
- package/dist/core/mcp/config-loader.d.ts.map +1 -0
- package/dist/core/mcp/config-loader.js +104 -0
- package/dist/core/mcp/config-loader.js.map +1 -0
- package/dist/core/mcp/config-writer.d.ts +21 -0
- package/dist/core/mcp/config-writer.d.ts.map +1 -0
- package/dist/core/mcp/config-writer.js +124 -0
- package/dist/core/mcp/config-writer.js.map +1 -0
- package/dist/core/mcp/config.d.ts +32 -0
- package/dist/core/mcp/config.d.ts.map +1 -0
- package/dist/core/mcp/config.js +385 -0
- package/dist/core/mcp/config.js.map +1 -0
- package/dist/core/mcp/direct-tools.d.ts +11 -0
- package/dist/core/mcp/direct-tools.d.ts.map +1 -0
- package/dist/core/mcp/direct-tools.js +47 -0
- package/dist/core/mcp/direct-tools.js.map +1 -0
- package/dist/core/mcp/gateway-tool.d.ts +29 -0
- package/dist/core/mcp/gateway-tool.d.ts.map +1 -0
- package/dist/core/mcp/gateway-tool.js +108 -0
- package/dist/core/mcp/gateway-tool.js.map +1 -0
- package/dist/core/mcp/index.d.ts +19 -0
- package/dist/core/mcp/index.d.ts.map +1 -0
- package/dist/core/mcp/index.js +18 -0
- package/dist/core/mcp/index.js.map +1 -0
- package/dist/core/mcp/manager.d.ts +117 -0
- package/dist/core/mcp/manager.d.ts.map +1 -0
- package/dist/core/mcp/manager.js +819 -0
- package/dist/core/mcp/manager.js.map +1 -0
- package/dist/core/mcp/metadata-cache.d.ts +27 -0
- package/dist/core/mcp/metadata-cache.d.ts.map +1 -0
- package/dist/core/mcp/metadata-cache.js +152 -0
- package/dist/core/mcp/metadata-cache.js.map +1 -0
- package/dist/core/mcp/oauth-flow.d.ts +94 -0
- package/dist/core/mcp/oauth-flow.d.ts.map +1 -0
- package/dist/core/mcp/oauth-flow.js +473 -0
- package/dist/core/mcp/oauth-flow.js.map +1 -0
- package/dist/core/mcp/oauth-provider.d.ts +39 -0
- package/dist/core/mcp/oauth-provider.d.ts.map +1 -0
- package/dist/core/mcp/oauth-provider.js +149 -0
- package/dist/core/mcp/oauth-provider.js.map +1 -0
- package/dist/core/mcp/oauth-store.d.ts +27 -0
- package/dist/core/mcp/oauth-store.d.ts.map +1 -0
- package/dist/core/mcp/oauth-store.js +111 -0
- package/dist/core/mcp/oauth-store.js.map +1 -0
- package/dist/core/mcp/output-store.d.ts +55 -0
- package/dist/core/mcp/output-store.d.ts.map +1 -0
- package/dist/core/mcp/output-store.js +206 -0
- package/dist/core/mcp/output-store.js.map +1 -0
- package/dist/core/mcp/rpc.d.ts +13 -0
- package/dist/core/mcp/rpc.d.ts.map +1 -0
- package/dist/core/mcp/rpc.js +29 -0
- package/dist/core/mcp/rpc.js.map +1 -0
- package/dist/core/mcp/safety.d.ts +6 -0
- package/dist/core/mcp/safety.d.ts.map +1 -0
- package/dist/core/mcp/safety.js +65 -0
- package/dist/core/mcp/safety.js.map +1 -0
- package/dist/core/mcp/search.d.ts +8 -0
- package/dist/core/mcp/search.d.ts.map +1 -0
- package/dist/core/mcp/search.js +85 -0
- package/dist/core/mcp/search.js.map +1 -0
- package/dist/core/mcp/server-supervisor.d.ts +59 -0
- package/dist/core/mcp/server-supervisor.d.ts.map +1 -0
- package/dist/core/mcp/server-supervisor.js +331 -0
- package/dist/core/mcp/server-supervisor.js.map +1 -0
- package/dist/core/mcp/types.d.ts +321 -0
- package/dist/core/mcp/types.d.ts.map +1 -0
- package/dist/core/mcp/types.js +2 -0
- package/dist/core/mcp/types.js.map +1 -0
- package/dist/core/messages.d.ts +78 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +138 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/model-catalog-watcher.d.ts +36 -0
- package/dist/core/model-catalog-watcher.d.ts.map +1 -0
- package/dist/core/model-catalog-watcher.js +101 -0
- package/dist/core/model-catalog-watcher.js.map +1 -0
- package/dist/core/model-registry.d.ts +160 -0
- package/dist/core/model-registry.d.ts.map +1 -0
- package/dist/core/model-registry.js +754 -0
- package/dist/core/model-registry.js.map +1 -0
- package/dist/core/model-resolver.d.ts +111 -0
- package/dist/core/model-resolver.d.ts.map +1 -0
- package/dist/core/model-resolver.js +534 -0
- package/dist/core/model-resolver.js.map +1 -0
- package/dist/core/output-guard.d.ts +7 -0
- package/dist/core/output-guard.d.ts.map +1 -0
- package/dist/core/output-guard.js +89 -0
- package/dist/core/output-guard.js.map +1 -0
- package/dist/core/package-manager.d.ts +220 -0
- package/dist/core/package-manager.d.ts.map +1 -0
- package/dist/core/package-manager.js +2217 -0
- package/dist/core/package-manager.js.map +1 -0
- package/dist/core/project-trust.d.ts +15 -0
- package/dist/core/project-trust.d.ts.map +1 -0
- package/dist/core/project-trust.js +58 -0
- package/dist/core/project-trust.js.map +1 -0
- package/dist/core/prompt-templates.d.ts +53 -0
- package/dist/core/prompt-templates.d.ts.map +1 -0
- package/dist/core/prompt-templates.js +236 -0
- package/dist/core/prompt-templates.js.map +1 -0
- package/dist/core/provider-attribution.d.ts +4 -0
- package/dist/core/provider-attribution.d.ts.map +1 -0
- package/dist/core/provider-attribution.js +81 -0
- package/dist/core/provider-attribution.js.map +1 -0
- package/dist/core/provider-display-names.d.ts +2 -0
- package/dist/core/provider-display-names.d.ts.map +1 -0
- package/dist/core/provider-display-names.js +36 -0
- package/dist/core/provider-display-names.js.map +1 -0
- package/dist/core/remote/iroh/access-grant.d.ts +40 -0
- package/dist/core/remote/iroh/access-grant.d.ts.map +1 -0
- package/dist/core/remote/iroh/access-grant.js +199 -0
- package/dist/core/remote/iroh/access-grant.js.map +1 -0
- package/dist/core/remote/iroh/active-stream-registry.d.ts +39 -0
- package/dist/core/remote/iroh/active-stream-registry.d.ts.map +1 -0
- package/dist/core/remote/iroh/active-stream-registry.js +109 -0
- package/dist/core/remote/iroh/active-stream-registry.js.map +1 -0
- package/dist/core/remote/iroh/audit.d.ts +67 -0
- package/dist/core/remote/iroh/audit.d.ts.map +1 -0
- package/dist/core/remote/iroh/audit.js +274 -0
- package/dist/core/remote/iroh/audit.js.map +1 -0
- package/dist/core/remote/iroh/authorization.d.ts +46 -0
- package/dist/core/remote/iroh/authorization.d.ts.map +1 -0
- package/dist/core/remote/iroh/authorization.js +327 -0
- package/dist/core/remote/iroh/authorization.js.map +1 -0
- package/dist/core/remote/iroh/control.d.ts +64 -0
- package/dist/core/remote/iroh/control.d.ts.map +1 -0
- package/dist/core/remote/iroh/control.js +326 -0
- package/dist/core/remote/iroh/control.js.map +1 -0
- package/dist/core/remote/iroh/device-log-rpc.d.ts +22 -0
- package/dist/core/remote/iroh/device-log-rpc.d.ts.map +1 -0
- package/dist/core/remote/iroh/device-log-rpc.js +152 -0
- package/dist/core/remote/iroh/device-log-rpc.js.map +1 -0
- package/dist/core/remote/iroh/engine.d.ts +148 -0
- package/dist/core/remote/iroh/engine.d.ts.map +1 -0
- package/dist/core/remote/iroh/engine.js +499 -0
- package/dist/core/remote/iroh/engine.js.map +1 -0
- package/dist/core/remote/iroh/handshake-reader.d.ts +19 -0
- package/dist/core/remote/iroh/handshake-reader.d.ts.map +1 -0
- package/dist/core/remote/iroh/handshake-reader.js +91 -0
- package/dist/core/remote/iroh/handshake-reader.js.map +1 -0
- package/dist/core/remote/iroh/handshake.d.ts +119 -0
- package/dist/core/remote/iroh/handshake.d.ts.map +1 -0
- package/dist/core/remote/iroh/handshake.js +621 -0
- package/dist/core/remote/iroh/handshake.js.map +1 -0
- package/dist/core/remote/iroh/host-policy.d.ts +13 -0
- package/dist/core/remote/iroh/host-policy.d.ts.map +1 -0
- package/dist/core/remote/iroh/host-policy.js +15 -0
- package/dist/core/remote/iroh/host-policy.js.map +1 -0
- package/dist/core/remote/iroh/index.d.ts +25 -0
- package/dist/core/remote/iroh/index.d.ts.map +1 -0
- package/dist/core/remote/iroh/index.js +25 -0
- package/dist/core/remote/iroh/index.js.map +1 -0
- package/dist/core/remote/iroh/metadata.d.ts +28 -0
- package/dist/core/remote/iroh/metadata.d.ts.map +1 -0
- package/dist/core/remote/iroh/metadata.js +16 -0
- package/dist/core/remote/iroh/metadata.js.map +1 -0
- package/dist/core/remote/iroh/outbound-filter.d.ts +29 -0
- package/dist/core/remote/iroh/outbound-filter.d.ts.map +1 -0
- package/dist/core/remote/iroh/outbound-filter.js +692 -0
- package/dist/core/remote/iroh/outbound-filter.js.map +1 -0
- package/dist/core/remote/iroh/protocol.d.ts +60 -0
- package/dist/core/remote/iroh/protocol.d.ts.map +1 -0
- package/dist/core/remote/iroh/protocol.js +204 -0
- package/dist/core/remote/iroh/protocol.js.map +1 -0
- package/dist/core/remote/iroh/push.d.ts +179 -0
- package/dist/core/remote/iroh/push.d.ts.map +1 -0
- package/dist/core/remote/iroh/push.js +662 -0
- package/dist/core/remote/iroh/push.js.map +1 -0
- package/dist/core/remote/iroh/qr.d.ts +12 -0
- package/dist/core/remote/iroh/qr.d.ts.map +1 -0
- package/dist/core/remote/iroh/qr.js +27 -0
- package/dist/core/remote/iroh/qr.js.map +1 -0
- package/dist/core/remote/iroh/rpc-command-filter.d.ts +47 -0
- package/dist/core/remote/iroh/rpc-command-filter.d.ts.map +1 -0
- package/dist/core/remote/iroh/rpc-command-filter.js +188 -0
- package/dist/core/remote/iroh/rpc-command-filter.js.map +1 -0
- package/dist/core/remote/iroh/rpc-transport.d.ts +21 -0
- package/dist/core/remote/iroh/rpc-transport.d.ts.map +1 -0
- package/dist/core/remote/iroh/rpc-transport.js +106 -0
- package/dist/core/remote/iroh/rpc-transport.js.map +1 -0
- package/dist/core/remote/iroh/state-manager.d.ts +141 -0
- package/dist/core/remote/iroh/state-manager.d.ts.map +1 -0
- package/dist/core/remote/iroh/state-manager.js +744 -0
- package/dist/core/remote/iroh/state-manager.js.map +1 -0
- package/dist/core/remote/iroh/state.d.ts +141 -0
- package/dist/core/remote/iroh/state.d.ts.map +1 -0
- package/dist/core/remote/iroh/state.js +433 -0
- package/dist/core/remote/iroh/state.js.map +1 -0
- package/dist/core/remote/iroh/ticket.d.ts +46 -0
- package/dist/core/remote/iroh/ticket.d.ts.map +1 -0
- package/dist/core/remote/iroh/ticket.js +267 -0
- package/dist/core/remote/iroh/ticket.js.map +1 -0
- package/dist/core/remote/iroh/transcript-text.d.ts +8 -0
- package/dist/core/remote/iroh/transcript-text.d.ts.map +1 -0
- package/dist/core/remote/iroh/transcript-text.js +26 -0
- package/dist/core/remote/iroh/transcript-text.js.map +1 -0
- package/dist/core/remote/iroh/workspace-rpc.d.ts +31 -0
- package/dist/core/remote/iroh/workspace-rpc.d.ts.map +1 -0
- package/dist/core/remote/iroh/workspace-rpc.js +73 -0
- package/dist/core/remote/iroh/workspace-rpc.js.map +1 -0
- package/dist/core/remote/iroh/workspace.d.ts +16 -0
- package/dist/core/remote/iroh/workspace.d.ts.map +1 -0
- package/dist/core/remote/iroh/workspace.js +104 -0
- package/dist/core/remote/iroh/workspace.js.map +1 -0
- package/dist/core/remote/iroh/worktree-rpc.d.ts +83 -0
- package/dist/core/remote/iroh/worktree-rpc.d.ts.map +1 -0
- package/dist/core/remote/iroh/worktree-rpc.js +148 -0
- package/dist/core/remote/iroh/worktree-rpc.js.map +1 -0
- package/dist/core/resolve-config-value.d.ts +30 -0
- package/dist/core/resolve-config-value.d.ts.map +1 -0
- package/dist/core/resolve-config-value.js +245 -0
- package/dist/core/resolve-config-value.js.map +1 -0
- package/dist/core/resource-loader.d.ts +214 -0
- package/dist/core/resource-loader.d.ts.map +1 -0
- package/dist/core/resource-loader.js +824 -0
- package/dist/core/resource-loader.js.map +1 -0
- package/dist/core/review.d.ts +318 -0
- package/dist/core/review.d.ts.map +1 -0
- package/dist/core/review.js +1271 -0
- package/dist/core/review.js.map +1 -0
- package/dist/core/rpc/duplex-write-gate.d.ts +29 -0
- package/dist/core/rpc/duplex-write-gate.d.ts.map +1 -0
- package/dist/core/rpc/duplex-write-gate.js +124 -0
- package/dist/core/rpc/duplex-write-gate.js.map +1 -0
- package/dist/core/rpc/index.d.ts +6 -0
- package/dist/core/rpc/index.d.ts.map +1 -0
- package/dist/core/rpc/index.js +5 -0
- package/dist/core/rpc/index.js.map +1 -0
- package/dist/core/rpc/iroh-transport.d.ts +58 -0
- package/dist/core/rpc/iroh-transport.d.ts.map +1 -0
- package/dist/core/rpc/iroh-transport.js +278 -0
- package/dist/core/rpc/iroh-transport.js.map +1 -0
- package/dist/core/rpc/jsonl.d.ts +17 -0
- package/dist/core/rpc/jsonl.d.ts.map +1 -0
- package/dist/core/rpc/jsonl.js +49 -0
- package/dist/core/rpc/jsonl.js.map +1 -0
- package/dist/core/rpc/loopback-transport.d.ts +14 -0
- package/dist/core/rpc/loopback-transport.d.ts.map +1 -0
- package/dist/core/rpc/loopback-transport.js +120 -0
- package/dist/core/rpc/loopback-transport.js.map +1 -0
- package/dist/core/rpc/transcript.d.ts +37 -0
- package/dist/core/rpc/transcript.d.ts.map +1 -0
- package/dist/core/rpc/transcript.js +624 -0
- package/dist/core/rpc/transcript.js.map +1 -0
- package/dist/core/rpc/transport.d.ts +41 -0
- package/dist/core/rpc/transport.d.ts.map +1 -0
- package/dist/core/rpc/transport.js +155 -0
- package/dist/core/rpc/transport.js.map +1 -0
- package/dist/core/rpc/types.d.ts +1254 -0
- package/dist/core/rpc/types.d.ts.map +1 -0
- package/dist/core/rpc/types.js +8 -0
- package/dist/core/rpc/types.js.map +1 -0
- package/dist/core/rpc/ui-action-args.d.ts +3 -0
- package/dist/core/rpc/ui-action-args.d.ts.map +1 -0
- package/dist/core/rpc/ui-action-args.js +66 -0
- package/dist/core/rpc/ui-action-args.js.map +1 -0
- package/dist/core/rpc/ui-actions.d.ts +43 -0
- package/dist/core/rpc/ui-actions.d.ts.map +1 -0
- package/dist/core/rpc/ui-actions.js +362 -0
- package/dist/core/rpc/ui-actions.js.map +1 -0
- package/dist/core/sdk.d.ts +138 -0
- package/dist/core/sdk.d.ts.map +1 -0
- package/dist/core/sdk.js +324 -0
- package/dist/core/sdk.js.map +1 -0
- package/dist/core/session-cwd.d.ts +19 -0
- package/dist/core/session-cwd.d.ts.map +1 -0
- package/dist/core/session-cwd.js +38 -0
- package/dist/core/session-cwd.js.map +1 -0
- package/dist/core/session-manager.d.ts +346 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +1280 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/core/settings-manager.d.ts +359 -0
- package/dist/core/settings-manager.d.ts.map +1 -0
- package/dist/core/settings-manager.js +1277 -0
- package/dist/core/settings-manager.js.map +1 -0
- package/dist/core/skills.d.ts +60 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +387 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/slash-commands.d.ts +14 -0
- package/dist/core/slash-commands.d.ts.map +1 -0
- package/dist/core/slash-commands.js +51 -0
- package/dist/core/slash-commands.js.map +1 -0
- package/dist/core/source-info.d.ts +18 -0
- package/dist/core/source-info.d.ts.map +1 -0
- package/dist/core/source-info.js +19 -0
- package/dist/core/source-info.js.map +1 -0
- package/dist/core/subagents/delegation-scope.d.ts +47 -0
- package/dist/core/subagents/delegation-scope.d.ts.map +1 -0
- package/dist/core/subagents/delegation-scope.js +134 -0
- package/dist/core/subagents/delegation-scope.js.map +1 -0
- package/dist/core/subagents/index.d.ts +46 -0
- package/dist/core/subagents/index.d.ts.map +1 -0
- package/dist/core/subagents/index.js +369 -0
- package/dist/core/subagents/index.js.map +1 -0
- package/dist/core/subagents/manager.d.ts +183 -0
- package/dist/core/subagents/manager.d.ts.map +1 -0
- package/dist/core/subagents/manager.js +820 -0
- package/dist/core/subagents/manager.js.map +1 -0
- package/dist/core/system-prompt.d.ts +28 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +180 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/telemetry.d.ts +3 -0
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/core/telemetry.js +9 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/core/theme/dark.json +86 -0
- package/dist/core/theme/discovery.d.ts +48 -0
- package/dist/core/theme/discovery.d.ts.map +1 -0
- package/dist/core/theme/discovery.js +239 -0
- package/dist/core/theme/discovery.js.map +1 -0
- package/dist/core/theme/index.d.ts +6 -0
- package/dist/core/theme/index.d.ts.map +1 -0
- package/dist/core/theme/index.js +5 -0
- package/dist/core/theme/index.js.map +1 -0
- package/dist/core/theme/light.json +85 -0
- package/dist/core/theme/runtime.d.ts +55 -0
- package/dist/core/theme/runtime.d.ts.map +1 -0
- package/dist/core/theme/runtime.js +555 -0
- package/dist/core/theme/runtime.js.map +1 -0
- package/dist/core/theme/theme-schema.json +335 -0
- package/dist/core/theme/theme-service.d.ts +37 -0
- package/dist/core/theme/theme-service.d.ts.map +1 -0
- package/dist/core/theme/theme-service.js +222 -0
- package/dist/core/theme/theme-service.js.map +1 -0
- package/dist/core/theme/theme.d.ts +100 -0
- package/dist/core/theme/theme.d.ts.map +1 -0
- package/dist/core/theme/theme.js +243 -0
- package/dist/core/theme/theme.js.map +1 -0
- package/dist/core/theme/tokens.d.ts +20 -0
- package/dist/core/theme/tokens.d.ts.map +1 -0
- package/dist/core/theme/tokens.js +178 -0
- package/dist/core/theme/tokens.js.map +1 -0
- package/dist/core/theme/types.d.ts +21 -0
- package/dist/core/theme/types.d.ts.map +1 -0
- package/dist/core/theme/types.js +2 -0
- package/dist/core/theme/types.js.map +1 -0
- package/dist/core/timings.d.ts +8 -0
- package/dist/core/timings.d.ts.map +1 -0
- package/dist/core/timings.js +31 -0
- package/dist/core/timings.js.map +1 -0
- package/dist/core/tools/bash.d.ts +68 -0
- package/dist/core/tools/bash.d.ts.map +1 -0
- package/dist/core/tools/bash.js +345 -0
- package/dist/core/tools/bash.js.map +1 -0
- package/dist/core/tools/diagnostics-provider.d.ts +12 -0
- package/dist/core/tools/diagnostics-provider.d.ts.map +1 -0
- package/dist/core/tools/diagnostics-provider.js +2 -0
- package/dist/core/tools/diagnostics-provider.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +77 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -0
- package/dist/core/tools/edit-diff.js +506 -0
- package/dist/core/tools/edit-diff.js.map +1 -0
- package/dist/core/tools/edit.d.ts +56 -0
- package/dist/core/tools/edit.d.ts.map +1 -0
- package/dist/core/tools/edit.js +300 -0
- package/dist/core/tools/edit.js.map +1 -0
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-queue.js +52 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -0
- package/dist/core/tools/find.d.ts +35 -0
- package/dist/core/tools/find.d.ts.map +1 -0
- package/dist/core/tools/find.js +337 -0
- package/dist/core/tools/find.js.map +1 -0
- package/dist/core/tools/grep.d.ts +37 -0
- package/dist/core/tools/grep.d.ts.map +1 -0
- package/dist/core/tools/grep.js +305 -0
- package/dist/core/tools/grep.js.map +1 -0
- package/dist/core/tools/index.d.ts +56 -0
- package/dist/core/tools/index.d.ts.map +1 -0
- package/dist/core/tools/index.js +174 -0
- package/dist/core/tools/index.js.map +1 -0
- package/dist/core/tools/ls.d.ts +37 -0
- package/dist/core/tools/ls.d.ts.map +1 -0
- package/dist/core/tools/ls.js +167 -0
- package/dist/core/tools/ls.js.map +1 -0
- package/dist/core/tools/lsp.d.ts +59 -0
- package/dist/core/tools/lsp.d.ts.map +1 -0
- package/dist/core/tools/lsp.js +157 -0
- package/dist/core/tools/lsp.js.map +1 -0
- package/dist/core/tools/output-accumulator.d.ts +52 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -0
- package/dist/core/tools/output-accumulator.js +184 -0
- package/dist/core/tools/output-accumulator.js.map +1 -0
- package/dist/core/tools/path-utils.d.ts +10 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -0
- package/dist/core/tools/path-utils.js +99 -0
- package/dist/core/tools/path-utils.js.map +1 -0
- package/dist/core/tools/read.d.ts +35 -0
- package/dist/core/tools/read.d.ts.map +1 -0
- package/dist/core/tools/read.js +292 -0
- package/dist/core/tools/read.js.map +1 -0
- package/dist/core/tools/render-utils.d.ts +26 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -0
- package/dist/core/tools/render-utils.js +69 -0
- package/dist/core/tools/render-utils.js.map +1 -0
- package/dist/core/tools/subagent.d.ts +219 -0
- package/dist/core/tools/subagent.d.ts.map +1 -0
- package/dist/core/tools/subagent.js +1445 -0
- package/dist/core/tools/subagent.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.js +34 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
- package/dist/core/tools/truncate.d.ts +70 -0
- package/dist/core/tools/truncate.d.ts.map +1 -0
- package/dist/core/tools/truncate.js +215 -0
- package/dist/core/tools/truncate.js.map +1 -0
- package/dist/core/tools/web-search.d.ts +69 -0
- package/dist/core/tools/web-search.d.ts.map +1 -0
- package/dist/core/tools/web-search.js +634 -0
- package/dist/core/tools/web-search.js.map +1 -0
- package/dist/core/tools/write.d.ts +33 -0
- package/dist/core/tools/write.d.ts.map +1 -0
- package/dist/core/tools/write.js +210 -0
- package/dist/core/tools/write.js.map +1 -0
- package/dist/core/trust-manager.d.ts +36 -0
- package/dist/core/trust-manager.d.ts.map +1 -0
- package/dist/core/trust-manager.js +220 -0
- package/dist/core/trust-manager.js.map +1 -0
- package/dist/daemon/cli.d.ts +8 -0
- package/dist/daemon/cli.d.ts.map +1 -0
- package/dist/daemon/cli.js +468 -0
- package/dist/daemon/cli.js.map +1 -0
- package/dist/daemon/control-client.d.ts +60 -0
- package/dist/daemon/control-client.d.ts.map +1 -0
- package/dist/daemon/control-client.js +411 -0
- package/dist/daemon/control-client.js.map +1 -0
- package/dist/daemon/control-protocol.d.ts +507 -0
- package/dist/daemon/control-protocol.d.ts.map +1 -0
- package/dist/daemon/control-protocol.js +395 -0
- package/dist/daemon/control-protocol.js.map +1 -0
- package/dist/daemon/control-server.d.ts +77 -0
- package/dist/daemon/control-server.d.ts.map +1 -0
- package/dist/daemon/control-server.js +327 -0
- package/dist/daemon/control-server.js.map +1 -0
- package/dist/daemon/conversation-commands.d.ts +176 -0
- package/dist/daemon/conversation-commands.d.ts.map +1 -0
- package/dist/daemon/conversation-commands.js +1268 -0
- package/dist/daemon/conversation-commands.js.map +1 -0
- package/dist/daemon/daemon-lock.d.ts +27 -0
- package/dist/daemon/daemon-lock.d.ts.map +1 -0
- package/dist/daemon/daemon-lock.js +238 -0
- package/dist/daemon/daemon-lock.js.map +1 -0
- package/dist/daemon/handshake-responses.d.ts +47 -0
- package/dist/daemon/handshake-responses.d.ts.map +1 -0
- package/dist/daemon/handshake-responses.js +113 -0
- package/dist/daemon/handshake-responses.js.map +1 -0
- package/dist/daemon/integrated-runtimes.d.ts +137 -0
- package/dist/daemon/integrated-runtimes.d.ts.map +1 -0
- package/dist/daemon/integrated-runtimes.js +763 -0
- package/dist/daemon/integrated-runtimes.js.map +1 -0
- package/dist/daemon/iroh-native.d.ts +76 -0
- package/dist/daemon/iroh-native.d.ts.map +1 -0
- package/dist/daemon/iroh-native.js +18 -0
- package/dist/daemon/iroh-native.js.map +1 -0
- package/dist/daemon/iroh-resource-guard.d.ts +57 -0
- package/dist/daemon/iroh-resource-guard.d.ts.map +1 -0
- package/dist/daemon/iroh-resource-guard.js +134 -0
- package/dist/daemon/iroh-resource-guard.js.map +1 -0
- package/dist/daemon/iroh-service.d.ts +51 -0
- package/dist/daemon/iroh-service.d.ts.map +1 -0
- package/dist/daemon/iroh-service.js +2604 -0
- package/dist/daemon/iroh-service.js.map +1 -0
- package/dist/daemon/keep-awake.d.ts +62 -0
- package/dist/daemon/keep-awake.d.ts.map +1 -0
- package/dist/daemon/keep-awake.js +190 -0
- package/dist/daemon/keep-awake.js.map +1 -0
- package/dist/daemon/lease-broker.d.ts +139 -0
- package/dist/daemon/lease-broker.d.ts.map +1 -0
- package/dist/daemon/lease-broker.js +504 -0
- package/dist/daemon/lease-broker.js.map +1 -0
- package/dist/daemon/log.d.ts +16 -0
- package/dist/daemon/log.d.ts.map +1 -0
- package/dist/daemon/log.js +40 -0
- package/dist/daemon/log.js.map +1 -0
- package/dist/daemon/main.d.ts +70 -0
- package/dist/daemon/main.d.ts.map +1 -0
- package/dist/daemon/main.js +781 -0
- package/dist/daemon/main.js.map +1 -0
- package/dist/daemon/paths.d.ts +32 -0
- package/dist/daemon/paths.d.ts.map +1 -0
- package/dist/daemon/paths.js +208 -0
- package/dist/daemon/paths.js.map +1 -0
- package/dist/daemon/process-identity.d.ts +58 -0
- package/dist/daemon/process-identity.d.ts.map +1 -0
- package/dist/daemon/process-identity.js +185 -0
- package/dist/daemon/process-identity.js.map +1 -0
- package/dist/daemon/relay-stream.d.ts +89 -0
- package/dist/daemon/relay-stream.d.ts.map +1 -0
- package/dist/daemon/relay-stream.js +202 -0
- package/dist/daemon/relay-stream.js.map +1 -0
- package/dist/daemon/remote-cli.d.ts +7 -0
- package/dist/daemon/remote-cli.d.ts.map +1 -0
- package/dist/daemon/remote-cli.js +774 -0
- package/dist/daemon/remote-cli.js.map +1 -0
- package/dist/daemon/service-install.d.ts +43 -0
- package/dist/daemon/service-install.d.ts.map +1 -0
- package/dist/daemon/service-install.js +198 -0
- package/dist/daemon/service-install.js.map +1 -0
- package/dist/daemon/session-target.d.ts +62 -0
- package/dist/daemon/session-target.d.ts.map +1 -0
- package/dist/daemon/session-target.js +66 -0
- package/dist/daemon/session-target.js.map +1 -0
- package/dist/daemon/spawn.d.ts +53 -0
- package/dist/daemon/spawn.d.ts.map +1 -0
- package/dist/daemon/spawn.js +205 -0
- package/dist/daemon/spawn.js.map +1 -0
- package/dist/daemon/state.d.ts +145 -0
- package/dist/daemon/state.d.ts.map +1 -0
- package/dist/daemon/state.js +454 -0
- package/dist/daemon/state.js.map +1 -0
- package/dist/daemon/theme-push.d.ts +23 -0
- package/dist/daemon/theme-push.d.ts.map +1 -0
- package/dist/daemon/theme-push.js +30 -0
- package/dist/daemon/theme-push.js.map +1 -0
- package/dist/daemon/viewer-feed.d.ts +42 -0
- package/dist/daemon/viewer-feed.d.ts.map +1 -0
- package/dist/daemon/viewer-feed.js +138 -0
- package/dist/daemon/viewer-feed.js.map +1 -0
- package/dist/daemon/workspace-directory.d.ts +35 -0
- package/dist/daemon/workspace-directory.d.ts.map +1 -0
- package/dist/daemon/workspace-directory.js +105 -0
- package/dist/daemon/workspace-directory.js.map +1 -0
- package/dist/daemon/workspace-streams.d.ts +70 -0
- package/dist/daemon/workspace-streams.d.ts.map +1 -0
- package/dist/daemon/workspace-streams.js +289 -0
- package/dist/daemon/workspace-streams.js.map +1 -0
- package/dist/daemon/worktree-manager.d.ts +219 -0
- package/dist/daemon/worktree-manager.d.ts.map +1 -0
- package/dist/daemon/worktree-manager.js +1204 -0
- package/dist/daemon/worktree-manager.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +12 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +773 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp-cli.d.ts +6 -0
- package/dist/mcp-cli.d.ts.map +1 -0
- package/dist/mcp-cli.js +347 -0
- package/dist/mcp-cli.js.map +1 -0
- package/dist/migrations.d.ts +33 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +281 -0
- package/dist/migrations.js.map +1 -0
- package/dist/modes/index.d.ts +13 -0
- package/dist/modes/index.d.ts.map +1 -0
- package/dist/modes/index.js +12 -0
- package/dist/modes/index.js.map +1 -0
- package/dist/modes/interactive/components/armin.d.ts +34 -0
- package/dist/modes/interactive/components/armin.d.ts.map +1 -0
- package/dist/modes/interactive/components/armin.js +333 -0
- package/dist/modes/interactive/components/armin.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +22 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/assistant-message.js +129 -0
- package/dist/modes/interactive/components/assistant-message.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +39 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/bash-execution.js +212 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts +17 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.js +57 -0
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.js +44 -0
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/config-selector.d.ts +71 -0
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/config-selector.js +510 -0
- package/dist/modes/interactive/components/config-selector.js.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.js +33 -0
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-editor.js +70 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts +20 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-message.js +76 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -0
- package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
- package/dist/modes/interactive/components/daxnuts.js +140 -0
- package/dist/modes/interactive/components/daxnuts.js.map +1 -0
- package/dist/modes/interactive/components/diff.d.ts +12 -0
- package/dist/modes/interactive/components/diff.d.ts.map +1 -0
- package/dist/modes/interactive/components/diff.js +133 -0
- package/dist/modes/interactive/components/diff.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.js +21 -0
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +20 -0
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-editor.js +116 -0
- package/dist/modes/interactive/components/extension-editor.js.map +1 -0
- package/dist/modes/interactive/components/extension-input.d.ts +23 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-input.js +61 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -0
- package/dist/modes/interactive/components/extension-selector.d.ts +27 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-selector.js +98 -0
- package/dist/modes/interactive/components/extension-selector.js.map +1 -0
- package/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
- package/dist/modes/interactive/components/first-time-setup.js +103 -0
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +27 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -0
- package/dist/modes/interactive/components/footer.js +180 -0
- package/dist/modes/interactive/components/footer.js.map +1 -0
- package/dist/modes/interactive/components/hotkeys.d.ts +24 -0
- package/dist/modes/interactive/components/hotkeys.d.ts.map +1 -0
- package/dist/modes/interactive/components/hotkeys.js +97 -0
- package/dist/modes/interactive/components/hotkeys.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +35 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -0
- package/dist/modes/interactive/components/index.js +36 -0
- package/dist/modes/interactive/components/index.js.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +19 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.js +48 -0
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts +52 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
- package/dist/modes/interactive/components/login-dialog.js +179 -0
- package/dist/modes/interactive/components/login-dialog.js.map +1 -0
- package/dist/modes/interactive/components/logo.d.ts +25 -0
- package/dist/modes/interactive/components/logo.d.ts.map +1 -0
- package/dist/modes/interactive/components/logo.js +89 -0
- package/dist/modes/interactive/components/logo.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +47 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/model-selector.js +278 -0
- package/dist/modes/interactive/components/model-selector.js.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts +31 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.js +165 -0
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
- package/dist/modes/interactive/components/remote-control-center.d.ts +110 -0
- package/dist/modes/interactive/components/remote-control-center.d.ts.map +1 -0
- package/dist/modes/interactive/components/remote-control-center.js +1217 -0
- package/dist/modes/interactive/components/remote-control-center.js.map +1 -0
- package/dist/modes/interactive/components/review-tools-selector.d.ts +24 -0
- package/dist/modes/interactive/components/review-tools-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/review-tools-selector.js +93 -0
- package/dist/modes/interactive/components/review-tools-selector.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +290 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.js +155 -0
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +95 -0
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector.js +856 -0
- package/dist/modes/interactive/components/session-selector.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +77 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-selector.js +484 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.js +39 -0
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
- package/dist/modes/interactive/components/streaming-render-coalescer.d.ts +29 -0
- package/dist/modes/interactive/components/streaming-render-coalescer.d.ts.map +1 -0
- package/dist/modes/interactive/components/streaming-render-coalescer.js +98 -0
- package/dist/modes/interactive/components/streaming-render-coalescer.js.map +1 -0
- package/dist/modes/interactive/components/subagent-inspector.d.ts +32 -0
- package/dist/modes/interactive/components/subagent-inspector.d.ts.map +1 -0
- package/dist/modes/interactive/components/subagent-inspector.js +439 -0
- package/dist/modes/interactive/components/subagent-inspector.js.map +1 -0
- package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/theme-selector.js +50 -0
- package/dist/modes/interactive/components/theme-selector.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.js +52 -0
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +83 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-execution.js +421 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +89 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/tree-selector.js +1208 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -0
- package/dist/modes/interactive/components/trust-selector.d.ts +23 -0
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/trust-selector.js +91 -0
- package/dist/modes/interactive/components/trust-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.js +114 -0
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +9 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message.js +42 -0
- package/dist/modes/interactive/components/user-message.js.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.js +33 -0
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
- package/dist/modes/interactive/components/volt-announcement.d.ts +5 -0
- package/dist/modes/interactive/components/volt-announcement.d.ts.map +1 -0
- package/dist/modes/interactive/components/volt-announcement.js +15 -0
- package/dist/modes/interactive/components/volt-announcement.js.map +1 -0
- package/dist/modes/interactive/daemon-attach.d.ts +154 -0
- package/dist/modes/interactive/daemon-attach.d.ts.map +1 -0
- package/dist/modes/interactive/daemon-attach.js +552 -0
- package/dist/modes/interactive/daemon-attach.js.map +1 -0
- package/dist/modes/interactive/drain-viewer.d.ts +31 -0
- package/dist/modes/interactive/drain-viewer.d.ts.map +1 -0
- package/dist/modes/interactive/drain-viewer.js +166 -0
- package/dist/modes/interactive/drain-viewer.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +502 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-mode.js +7007 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -0
- package/dist/modes/interactive/prompt-image-attachments.d.ts +34 -0
- package/dist/modes/interactive/prompt-image-attachments.d.ts.map +1 -0
- package/dist/modes/interactive/prompt-image-attachments.js +120 -0
- package/dist/modes/interactive/prompt-image-attachments.js.map +1 -0
- package/dist/modes/interactive/relay-stream-adapter.d.ts +19 -0
- package/dist/modes/interactive/relay-stream-adapter.d.ts.map +1 -0
- package/dist/modes/interactive/relay-stream-adapter.js +107 -0
- package/dist/modes/interactive/relay-stream-adapter.js.map +1 -0
- package/dist/modes/print-mode.d.ts +28 -0
- package/dist/modes/print-mode.d.ts.map +1 -0
- package/dist/modes/print-mode.js +132 -0
- package/dist/modes/print-mode.js.map +1 -0
- package/dist/modes/rpc/in-process-rpc-client.d.ts +31 -0
- package/dist/modes/rpc/in-process-rpc-client.d.ts.map +1 -0
- package/dist/modes/rpc/in-process-rpc-client.js +63 -0
- package/dist/modes/rpc/in-process-rpc-client.js.map +1 -0
- package/dist/modes/rpc/iroh-remote-agent-runtime.d.ts +61 -0
- package/dist/modes/rpc/iroh-remote-agent-runtime.d.ts.map +1 -0
- package/dist/modes/rpc/iroh-remote-agent-runtime.js +155 -0
- package/dist/modes/rpc/iroh-remote-agent-runtime.js.map +1 -0
- package/dist/modes/rpc/iroh-remote-rpc-mode.d.ts +69 -0
- package/dist/modes/rpc/iroh-remote-rpc-mode.d.ts.map +1 -0
- package/dist/modes/rpc/iroh-remote-rpc-mode.js +1223 -0
- package/dist/modes/rpc/iroh-remote-rpc-mode.js.map +1 -0
- package/dist/modes/rpc/jsonl.d.ts +2 -0
- package/dist/modes/rpc/jsonl.d.ts.map +1 -0
- package/dist/modes/rpc/jsonl.js +2 -0
- package/dist/modes/rpc/jsonl.js.map +1 -0
- package/dist/modes/rpc/rpc-client-base.d.ts +209 -0
- package/dist/modes/rpc/rpc-client-base.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-client-base.js +530 -0
- package/dist/modes/rpc/rpc-client-base.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +50 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-client.js +190 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -0
- package/dist/modes/rpc/rpc-command-dispatcher.d.ts +43 -0
- package/dist/modes/rpc/rpc-command-dispatcher.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-command-dispatcher.js +613 -0
- package/dist/modes/rpc/rpc-command-dispatcher.js.map +1 -0
- package/dist/modes/rpc/rpc-command-validation.d.ts +2 -0
- package/dist/modes/rpc/rpc-command-validation.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-command-validation.js +207 -0
- package/dist/modes/rpc/rpc-command-validation.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts +48 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-mode.js +1089 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -0
- package/dist/modes/rpc/rpc-transport-client.d.ts +26 -0
- package/dist/modes/rpc/rpc-transport-client.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-transport-client.js +76 -0
- package/dist/modes/rpc/rpc-transport-client.js.map +1 -0
- package/dist/modes/rpc/rpc-types.d.ts +2 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-types.js +2 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -0
- package/dist/package-manager-cli.d.ts +28 -0
- package/dist/package-manager-cli.d.ts.map +1 -0
- package/dist/package-manager-cli.js +667 -0
- package/dist/package-manager-cli.js.map +1 -0
- package/dist/remote/integrated-runtime-retention.d.ts +17 -0
- package/dist/remote/integrated-runtime-retention.d.ts.map +1 -0
- package/dist/remote/integrated-runtime-retention.js +62 -0
- package/dist/remote/integrated-runtime-retention.js.map +1 -0
- package/dist/remote/iroh-native-adapter.cjs +19 -0
- package/dist/sea/cli.d.ts +4 -0
- package/dist/sea/cli.d.ts.map +1 -0
- package/dist/sea/cli.js +4 -0
- package/dist/sea/cli.js.map +1 -0
- package/dist/sea/register-bedrock.d.ts +2 -0
- package/dist/sea/register-bedrock.d.ts.map +1 -0
- package/dist/sea/register-bedrock.js +4 -0
- package/dist/sea/register-bedrock.js.map +1 -0
- package/dist/store/catalog.d.ts +57 -0
- package/dist/store/catalog.d.ts.map +1 -0
- package/dist/store/catalog.js +331 -0
- package/dist/store/catalog.js.map +1 -0
- package/dist/store/inspector.d.ts +36 -0
- package/dist/store/inspector.d.ts.map +1 -0
- package/dist/store/inspector.js +578 -0
- package/dist/store/inspector.js.map +1 -0
- package/dist/store/install-plan.d.ts +26 -0
- package/dist/store/install-plan.d.ts.map +1 -0
- package/dist/store/install-plan.js +80 -0
- package/dist/store/install-plan.js.map +1 -0
- package/dist/store/render.d.ts +11 -0
- package/dist/store/render.d.ts.map +1 -0
- package/dist/store/render.js +153 -0
- package/dist/store/render.js.map +1 -0
- package/dist/store/resolver.d.ts +22 -0
- package/dist/store/resolver.d.ts.map +1 -0
- package/dist/store/resolver.js +207 -0
- package/dist/store/resolver.js.map +1 -0
- package/dist/store/store-cli.d.ts +7 -0
- package/dist/store/store-cli.d.ts.map +1 -0
- package/dist/store/store-cli.js +636 -0
- package/dist/store/store-cli.js.map +1 -0
- package/dist/store/targets.d.ts +21 -0
- package/dist/store/targets.d.ts.map +1 -0
- package/dist/store/targets.js +55 -0
- package/dist/store/targets.js.map +1 -0
- package/dist/utils/ansi.d.ts +2 -0
- package/dist/utils/ansi.d.ts.map +1 -0
- package/dist/utils/ansi.js +52 -0
- package/dist/utils/ansi.js.map +1 -0
- package/dist/utils/changelog.d.ts +22 -0
- package/dist/utils/changelog.d.ts.map +1 -0
- package/dist/utils/changelog.js +165 -0
- package/dist/utils/changelog.js.map +1 -0
- package/dist/utils/child-process.d.ts +18 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +106 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts +11 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -0
- package/dist/utils/clipboard-image.js +245 -0
- package/dist/utils/clipboard-image.js.map +1 -0
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +94 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/deprecation.d.ts +4 -0
- package/dist/utils/deprecation.d.ts.map +1 -0
- package/dist/utils/deprecation.js +13 -0
- package/dist/utils/deprecation.js.map +1 -0
- package/dist/utils/durable-atomic-write.d.ts +46 -0
- package/dist/utils/durable-atomic-write.d.ts.map +1 -0
- package/dist/utils/durable-atomic-write.js +104 -0
- package/dist/utils/durable-atomic-write.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +8 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +26 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/fs-watch.d.ts +5 -0
- package/dist/utils/fs-watch.d.ts.map +1 -0
- package/dist/utils/fs-watch.js +25 -0
- package/dist/utils/fs-watch.js.map +1 -0
- package/dist/utils/git.d.ts +26 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +195 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/html.d.ts +7 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +40 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/ignore-files.d.ts +5 -0
- package/dist/utils/ignore-files.d.ts.map +1 -0
- package/dist/utils/ignore-files.js +58 -0
- package/dist/utils/ignore-files.js.map +1 -0
- package/dist/utils/image-codec.d.ts +22 -0
- package/dist/utils/image-codec.d.ts.map +1 -0
- package/dist/utils/image-codec.js +35 -0
- package/dist/utils/image-codec.js.map +1 -0
- package/dist/utils/image-convert.d.ts +9 -0
- package/dist/utils/image-convert.d.ts.map +1 -0
- package/dist/utils/image-convert.js +26 -0
- package/dist/utils/image-convert.js.map +1 -0
- package/dist/utils/image-resize-core.d.ts +31 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -0
- package/dist/utils/image-resize-core.js +181 -0
- package/dist/utils/image-resize-core.js.map +1 -0
- package/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/utils/image-resize-worker.d.ts.map +1 -0
- package/dist/utils/image-resize-worker.js +31 -0
- package/dist/utils/image-resize-worker.js.map +1 -0
- package/dist/utils/image-resize.d.ts +15 -0
- package/dist/utils/image-resize.d.ts.map +1 -0
- package/dist/utils/image-resize.js +92 -0
- package/dist/utils/image-resize.js.map +1 -0
- package/dist/utils/json.d.ts +3 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +7 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/mime.d.ts +3 -0
- package/dist/utils/mime.d.ts.map +1 -0
- package/dist/utils/mime.js +69 -0
- package/dist/utils/mime.js.map +1 -0
- package/dist/utils/npm-spec.d.ts +9 -0
- package/dist/utils/npm-spec.d.ts.map +1 -0
- package/dist/utils/npm-spec.js +15 -0
- package/dist/utils/npm-spec.js.map +1 -0
- package/dist/utils/open-browser.d.ts +9 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +22 -0
- package/dist/utils/open-browser.js.map +1 -0
- package/dist/utils/paths.d.ts +31 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +92 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/private-files.d.ts +21 -0
- package/dist/utils/private-files.d.ts.map +1 -0
- package/dist/utils/private-files.js +103 -0
- package/dist/utils/private-files.js.map +1 -0
- package/dist/utils/process-env.d.ts +2 -0
- package/dist/utils/process-env.d.ts.map +1 -0
- package/dist/utils/process-env.js +31 -0
- package/dist/utils/process-env.js.map +1 -0
- package/dist/utils/shell.d.ts +30 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +195 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/sleep.d.ts +5 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +17 -0
- package/dist/utils/sleep.js.map +1 -0
- package/dist/utils/syntax-highlight.d.ts +18 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -0
- package/dist/utils/syntax-highlight.js +139 -0
- package/dist/utils/syntax-highlight.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +3 -0
- package/dist/utils/tools-manager.d.ts.map +1 -0
- package/dist/utils/tools-manager.js +328 -0
- package/dist/utils/tools-manager.js.map +1 -0
- package/dist/utils/version-check.d.ts +15 -0
- package/dist/utils/version-check.d.ts.map +1 -0
- package/dist/utils/version-check.js +61 -0
- package/dist/utils/version-check.js.map +1 -0
- package/dist/utils/volt-user-agent.d.ts +2 -0
- package/dist/utils/volt-user-agent.d.ts.map +1 -0
- package/dist/utils/volt-user-agent.js +5 -0
- package/dist/utils/volt-user-agent.js.map +1 -0
- package/dist/utils/windows-self-update.d.ts +3 -0
- package/dist/utils/windows-self-update.d.ts.map +1 -0
- package/dist/utils/windows-self-update.js +77 -0
- package/dist/utils/windows-self-update.js.map +1 -0
- package/docs/compaction.md +394 -0
- package/docs/containerization.md +111 -0
- package/docs/custom-provider.md +737 -0
- package/docs/daemon.md +190 -0
- package/docs/development.md +70 -0
- package/docs/docs.json +176 -0
- package/docs/extensions.md +2692 -0
- package/docs/images/exy.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/index.md +82 -0
- package/docs/iroh-remote-access-design.md +340 -0
- package/docs/iroh-remote-protocol.md +431 -0
- package/docs/json.md +87 -0
- package/docs/keybindings.md +200 -0
- package/docs/live-shared-session-daemon-design.md +1090 -0
- package/docs/lsp.md +143 -0
- package/docs/mcp.md +1044 -0
- package/docs/models.md +495 -0
- package/docs/packages.md +230 -0
- package/docs/prompt-templates.md +108 -0
- package/docs/providers.md +274 -0
- package/docs/quickstart.md +165 -0
- package/docs/rpc.md +2050 -0
- package/docs/sdk.md +1267 -0
- package/docs/security.md +139 -0
- package/docs/session-format.md +412 -0
- package/docs/sessions.md +145 -0
- package/docs/settings.md +371 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +243 -0
- package/docs/subagents-design.md +419 -0
- package/docs/terminal-setup.md +148 -0
- package/docs/termux.md +127 -0
- package/docs/themes.md +295 -0
- package/docs/tla/ClientAuth.cfg +16 -0
- package/docs/tla/ClientAuth.tla +205 -0
- package/docs/tla/ClientConn.cfg +16 -0
- package/docs/tla/ClientConn.tla +265 -0
- package/docs/tla/LeaseBroker.cfg +43 -0
- package/docs/tla/LeaseBroker.tla +563 -0
- package/docs/tla/PLAN.md +240 -0
- package/docs/tla/PushOrdering.cfg +17 -0
- package/docs/tla/PushOrdering.tla +183 -0
- package/docs/tla/README.md +205 -0
- package/docs/tla/RelayViewer.cfg +26 -0
- package/docs/tla/RelayViewer.tla +299 -0
- package/docs/tla/SessionTarget.cfg +18 -0
- package/docs/tla/SessionTarget.tla +192 -0
- package/docs/tla/check.sh +34 -0
- package/docs/tmux.md +63 -0
- package/docs/tui.md +949 -0
- package/docs/usage.md +482 -0
- package/docs/windows.md +17 -0
- package/docs/worktrees-design.md +605 -0
- package/examples/README.md +28 -0
- package/examples/extensions/README.md +211 -0
- package/examples/extensions/auto-commit-on-exit.ts +49 -0
- package/examples/extensions/bash-spawn-hook.ts +30 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/border-status-editor.ts +150 -0
- package/examples/extensions/built-in-tool-renderer.ts +249 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/commands.ts +72 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +127 -0
- package/examples/extensions/custom-footer.ts +64 -0
- package/examples/extensions/custom-header.ts +72 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +400 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
- package/examples/extensions/dirty-repo-guard.ts +56 -0
- package/examples/extensions/dynamic-resources/SKILL.md +8 -0
- package/examples/extensions/dynamic-resources/dynamic.json +79 -0
- package/examples/extensions/dynamic-resources/dynamic.md +5 -0
- package/examples/extensions/dynamic-resources/index.ts +15 -0
- package/examples/extensions/dynamic-tools.ts +74 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/git-merge-and-resolve.ts +115 -0
- package/examples/extensions/github-issue-autocomplete.ts +185 -0
- package/examples/extensions/gondolin/index.ts +531 -0
- package/examples/extensions/gondolin/package-lock.json +185 -0
- package/examples/extensions/gondolin/package.json +19 -0
- package/examples/extensions/handoff.ts +191 -0
- package/examples/extensions/hello.ts +26 -0
- package/examples/extensions/hidden-thinking-label.ts +53 -0
- package/examples/extensions/inline-bash.ts +94 -0
- package/examples/extensions/input-transform-streaming.ts +39 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +196 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +59 -0
- package/examples/extensions/minimal-mode.ts +426 -0
- package/examples/extensions/modal-editor.ts +85 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +55 -0
- package/examples/extensions/overlay-qa-tests.ts +1450 -0
- package/examples/extensions/overlay-test.ts +153 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +65 -0
- package/examples/extensions/plan-mode/index.ts +340 -0
- package/examples/extensions/plan-mode/utils.ts +168 -0
- package/examples/extensions/preset.ts +436 -0
- package/examples/extensions/project-trust.ts +64 -0
- package/examples/extensions/prompt-customizer.ts +97 -0
- package/examples/extensions/protected-paths.ts +30 -0
- package/examples/extensions/provider-payload.ts +18 -0
- package/examples/extensions/qna.ts +122 -0
- package/examples/extensions/question.ts +277 -0
- package/examples/extensions/questionnaire.ts +440 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/rpc-demo.ts +118 -0
- package/examples/extensions/sandbox/index.ts +321 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +343 -0
- package/examples/extensions/space-invaders.ts +560 -0
- package/examples/extensions/ssh.ts +220 -0
- package/examples/extensions/status-line.ts +32 -0
- package/examples/extensions/structured-output.ts +65 -0
- package/examples/extensions/subagent/README.md +175 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +126 -0
- package/examples/extensions/subagent/index.ts +1009 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +206 -0
- package/examples/extensions/system-prompt-header.ts +17 -0
- package/examples/extensions/tic-tac-toe.ts +1008 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/titlebar-spinner.ts +58 -0
- package/examples/extensions/todo.ts +297 -0
- package/examples/extensions/tool-override.ts +144 -0
- package/examples/extensions/tools.ts +146 -0
- package/examples/extensions/trigger-compact.ts +50 -0
- package/examples/extensions/truncated-tool.ts +195 -0
- package/examples/extensions/widget-placement.ts +9 -0
- package/examples/extensions/with-deps/index.ts +32 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/extensions/working-indicator.ts +123 -0
- package/examples/extensions/working-message-test.ts +25 -0
- package/examples/remote/firebase-push-relay/README.md +79 -0
- package/examples/remote/firebase-push-relay/firebase.json +12 -0
- package/examples/remote/firebase-push-relay/firestore.indexes.json +11 -0
- package/examples/remote/firebase-push-relay/firestore.rules +9 -0
- package/examples/remote/firebase-push-relay/functions/core.js +511 -0
- package/examples/remote/firebase-push-relay/functions/core.test.js +273 -0
- package/examples/remote/firebase-push-relay/functions/index.js +413 -0
- package/examples/remote/firebase-push-relay/functions/package-lock.json +2974 -0
- package/examples/remote/firebase-push-relay/functions/package.json +18 -0
- package/examples/remote/iroh-sidecar/README.md +211 -0
- package/examples/remote/iroh-sidecar/client.mjs +554 -0
- package/examples/remote/iroh-sidecar/common.mjs +195 -0
- package/examples/remote/iroh-sidecar/host.mjs +4 -0
- package/examples/remote/iroh-sidecar/package-lock.json +213 -0
- package/examples/remote/iroh-sidecar/package.json +13 -0
- package/examples/remote/iroh-sidecar/source-aware-run.mjs +41 -0
- package/examples/rpc-extension-ui.ts +632 -0
- package/examples/sdk/01-minimal.ts +26 -0
- package/examples/sdk/02-custom-model.ts +53 -0
- package/examples/sdk/03-custom-prompt.ts +70 -0
- package/examples/sdk/04-skills.ts +55 -0
- package/examples/sdk/05-tools.ts +48 -0
- package/examples/sdk/06-extensions.ts +94 -0
- package/examples/sdk/07-context-files.ts +42 -0
- package/examples/sdk/08-prompt-templates.ts +51 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +52 -0
- package/examples/sdk/10-settings.ts +53 -0
- package/examples/sdk/11-sessions.ts +52 -0
- package/examples/sdk/12-full-control.ts +78 -0
- package/examples/sdk/13-session-runtime.ts +67 -0
- package/examples/sdk/README.md +147 -0
- package/npm-shrinkwrap.json +3442 -0
- package/package.json +125 -19
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
export const DEFAULT_START_TIME_TOLERANCE_MS = 15_000;
|
|
3
|
+
/**
|
|
4
|
+
* Command-line markers that identify a voltd process. Linux rewrites argv to the
|
|
5
|
+
* process title ("voltd"); macOS and Windows report the original invocation
|
|
6
|
+
* (`... daemon run --foreground`).
|
|
7
|
+
*
|
|
8
|
+
* The bare "voltd" marker is matched as a whole path/argv token, not a bare
|
|
9
|
+
* substring: an unrelated but same-user process whose command line merely
|
|
10
|
+
* contains the string (e.g. `tail -f /var/log/voltd.log`, `vim voltd.ts`,
|
|
11
|
+
* `node .../voltd-cli/x.js`) must not satisfy the identity check and be signalled.
|
|
12
|
+
*/
|
|
13
|
+
const VOLTD_COMMAND_MARKERS = [/(?:^|[\s/\\])voltd(?=$|[\s/\\])/, "daemon run --foreground"];
|
|
14
|
+
const defaultRunner = (command, args) => new Promise((resolve) => {
|
|
15
|
+
const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
16
|
+
let output = "";
|
|
17
|
+
child.stdout?.on("data", (chunk) => {
|
|
18
|
+
output += chunk.toString("utf8");
|
|
19
|
+
});
|
|
20
|
+
child.on("error", (error) => resolve({ code: 127, output: error.message }));
|
|
21
|
+
child.on("close", (code) => resolve({ code: code ?? 1, output }));
|
|
22
|
+
});
|
|
23
|
+
function defaultIsProcessAlive(pid) {
|
|
24
|
+
try {
|
|
25
|
+
process.kill(pid, 0);
|
|
26
|
+
return "alive";
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
// EPERM: the pid exists but belongs to another user — alive (and almost
|
|
30
|
+
// certainly not our daemon; the identity check will refuse it).
|
|
31
|
+
return error instanceof Error && "code" in error && error.code === "EPERM"
|
|
32
|
+
? "alive"
|
|
33
|
+
: "gone";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Parse ps etime ("[[dd-]hh:]mm:ss") into elapsed milliseconds. */
|
|
37
|
+
export function parseElapsedTime(value) {
|
|
38
|
+
const match = /^(?:(\d+)-)?(?:(\d+):)?(\d{1,2}):(\d{2})$/.exec(value.trim());
|
|
39
|
+
if (!match) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
const [, days, hours, minutes, seconds] = match;
|
|
43
|
+
return (Number(days ?? 0) * 86_400 + Number(hours ?? 0) * 3_600 + Number(minutes) * 60 + Number(seconds)) * 1_000;
|
|
44
|
+
}
|
|
45
|
+
async function queryPosixProcess(pid, runner, now) {
|
|
46
|
+
// etime (not the Linux-only etimes) is in the POSIX ps keyword set and has a
|
|
47
|
+
// fixed, locale-independent format.
|
|
48
|
+
const result = await runner("ps", ["-p", String(pid), "-o", "etime=,args="]);
|
|
49
|
+
if (result.code !== 0) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
const line = result.output.split("\n").find((candidate) => candidate.trim().length > 0);
|
|
53
|
+
if (!line) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
const trimmed = line.trim();
|
|
57
|
+
const separatorIndex = trimmed.search(/\s/);
|
|
58
|
+
const etime = separatorIndex === -1 ? trimmed : trimmed.slice(0, separatorIndex);
|
|
59
|
+
const commandLine = separatorIndex === -1 ? "" : trimmed.slice(separatorIndex + 1).trim();
|
|
60
|
+
const elapsedMs = parseElapsedTime(etime);
|
|
61
|
+
return {
|
|
62
|
+
...(elapsedMs === undefined ? {} : { startTimeMs: now() - elapsedMs }),
|
|
63
|
+
commandLine,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
async function queryWindowsProcess(pid, runner) {
|
|
67
|
+
// CIM gives both an absolute creation time and the original command line.
|
|
68
|
+
const script = `$p = Get-CimInstance Win32_Process -Filter 'ProcessId=${pid}'; ` +
|
|
69
|
+
`if ($p) { ConvertTo-Json -Compress @{ startMs = [DateTimeOffset]::new($p.CreationDate).ToUnixTimeMilliseconds(); commandLine = [string]$p.CommandLine } }`;
|
|
70
|
+
const result = await runner("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", script]);
|
|
71
|
+
if (result.code !== 0) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const jsonLine = result.output.split("\n").find((candidate) => candidate.trim().startsWith("{"));
|
|
75
|
+
if (!jsonLine) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const parsed = JSON.parse(jsonLine.trim());
|
|
80
|
+
return {
|
|
81
|
+
...(typeof parsed.startMs === "number" && Number.isFinite(parsed.startMs)
|
|
82
|
+
? { startTimeMs: parsed.startMs }
|
|
83
|
+
: {}),
|
|
84
|
+
commandLine: typeof parsed.commandLine === "string" ? parsed.commandLine : "",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function commandLineLooksLikeVoltd(commandLine) {
|
|
92
|
+
return VOLTD_COMMAND_MARKERS.some((marker) => typeof marker === "string" ? commandLine.includes(marker) : marker.test(commandLine));
|
|
93
|
+
}
|
|
94
|
+
async function lookupProcessIdentity(pid, options) {
|
|
95
|
+
const runner = options.runner ?? defaultRunner;
|
|
96
|
+
const platform = options.platform ?? process.platform;
|
|
97
|
+
const now = () => options.now ?? Date.now();
|
|
98
|
+
const isProcessAlive = options.isProcessAlive ?? defaultIsProcessAlive;
|
|
99
|
+
if (isProcessAlive(pid) === "gone") {
|
|
100
|
+
return { kind: "gone" };
|
|
101
|
+
}
|
|
102
|
+
const identity = platform === "win32" ? await queryWindowsProcess(pid, runner) : await queryPosixProcess(pid, runner, now);
|
|
103
|
+
if (identity) {
|
|
104
|
+
return { kind: "found", identity };
|
|
105
|
+
}
|
|
106
|
+
// The process may have exited between the liveness probe and the query.
|
|
107
|
+
// Otherwise its identity is unavailable and callers must fail closed.
|
|
108
|
+
return isProcessAlive(pid) === "gone" ? { kind: "gone" } : { kind: "unknown" };
|
|
109
|
+
}
|
|
110
|
+
function processStartTimeMatches(startedAtMs, identity, toleranceMs) {
|
|
111
|
+
return (identity.startTimeMs !== undefined &&
|
|
112
|
+
startedAtMs > 0 &&
|
|
113
|
+
Math.abs(identity.startTimeMs - startedAtMs) <= toleranceMs);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Verify only process creation identity. Unlike pidfile verification, this
|
|
117
|
+
* distinguishes a verifiable recycled PID from an unavailable OS query so
|
|
118
|
+
* startup-lock recovery can reap the former while failing closed on the latter.
|
|
119
|
+
*/
|
|
120
|
+
export async function verifyProcessCreationTime(record, options = {}) {
|
|
121
|
+
if (!Number.isInteger(record.pid) || record.pid <= 0) {
|
|
122
|
+
return "mismatch";
|
|
123
|
+
}
|
|
124
|
+
const lookup = await lookupProcessIdentity(record.pid, options);
|
|
125
|
+
if (lookup.kind !== "found") {
|
|
126
|
+
return lookup.kind;
|
|
127
|
+
}
|
|
128
|
+
if (record.startedAtMs <= 0 || lookup.identity.startTimeMs === undefined) {
|
|
129
|
+
return "unknown";
|
|
130
|
+
}
|
|
131
|
+
const toleranceMs = options.toleranceMs ?? DEFAULT_START_TIME_TOLERANCE_MS;
|
|
132
|
+
return processStartTimeMatches(record.startedAtMs, lookup.identity, toleranceMs) ? "match" : "mismatch";
|
|
133
|
+
}
|
|
134
|
+
/** Verify both process creation identity and the voltd command marker. */
|
|
135
|
+
export async function verifyVoltdProcessIdentity(record, options = {}) {
|
|
136
|
+
if (!Number.isInteger(record.pid) || record.pid <= 0) {
|
|
137
|
+
return "mismatch";
|
|
138
|
+
}
|
|
139
|
+
const lookup = await lookupProcessIdentity(record.pid, options);
|
|
140
|
+
if (lookup.kind !== "found") {
|
|
141
|
+
return lookup.kind;
|
|
142
|
+
}
|
|
143
|
+
if (record.startedAtMs <= 0 || lookup.identity.startTimeMs === undefined) {
|
|
144
|
+
return "unknown";
|
|
145
|
+
}
|
|
146
|
+
const toleranceMs = options.toleranceMs ?? DEFAULT_START_TIME_TOLERANCE_MS;
|
|
147
|
+
if (!processStartTimeMatches(record.startedAtMs, lookup.identity, toleranceMs)) {
|
|
148
|
+
return "mismatch";
|
|
149
|
+
}
|
|
150
|
+
// Matching creation evidence is conclusive enough to fail closed, but some
|
|
151
|
+
// supported hosts (notably direct runVoltDaemon() calls on Windows) do not
|
|
152
|
+
// expose a voltd marker in the immutable process command line.
|
|
153
|
+
return commandLineLooksLikeVoltd(lookup.identity.commandLine) ? "match" : "unknown";
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Verify that pidfile.pid still refers to the daemon that wrote the pidfile.
|
|
157
|
+
*
|
|
158
|
+
* - "gone": no such process (or it exited mid-check) — safe to treat as stopped.
|
|
159
|
+
* - "match": alive, start time within tolerance of startedAtMs, and a
|
|
160
|
+
* voltd-looking command line — safe to signal.
|
|
161
|
+
* - "mismatch": alive but unverifiable or verifiably different (recycled pid,
|
|
162
|
+
* another user's process, ps/powershell unavailable) — do NOT signal.
|
|
163
|
+
*/
|
|
164
|
+
export async function verifyPidfileProcess(pidfile, options = {}) {
|
|
165
|
+
if (!Number.isInteger(pidfile.pid) || pidfile.pid <= 0) {
|
|
166
|
+
return "mismatch";
|
|
167
|
+
}
|
|
168
|
+
const lookup = await lookupProcessIdentity(pidfile.pid, options);
|
|
169
|
+
if (lookup.kind === "gone") {
|
|
170
|
+
return "gone";
|
|
171
|
+
}
|
|
172
|
+
if (lookup.kind === "unknown") {
|
|
173
|
+
return "mismatch";
|
|
174
|
+
}
|
|
175
|
+
// A match REQUIRES verifying the process start time against the pidfile, not
|
|
176
|
+
// just a voltd-looking command line. Without that check (a legacy pidfile
|
|
177
|
+
// missing startedAtMs, or the OS not reporting a start time) a recycled pid
|
|
178
|
+
// whose command line merely contains a voltd marker must not be signalled.
|
|
179
|
+
const toleranceMs = options.toleranceMs ?? DEFAULT_START_TIME_TOLERANCE_MS;
|
|
180
|
+
if (!processStartTimeMatches(pidfile.startedAtMs, lookup.identity, toleranceMs)) {
|
|
181
|
+
return "mismatch";
|
|
182
|
+
}
|
|
183
|
+
return commandLineLooksLikeVoltd(lookup.identity.commandLine) ? "match" : "mismatch";
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=process-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-identity.js","sourceRoot":"","sources":["../../src/daemon/process-identity.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport type { PidfileContents } from \"./main.ts\";\n\n/**\n * Process-identity verification for the pidfile SIGTERM fallbacks: a pidfile\n * outlives its daemon, and the recorded pid can be recycled by an unrelated\n * process. Before killing, verify the live process (a) started when the\n * pidfile says the daemon started and (b) has a voltd-looking command line.\n *\n * Platform-aware by design (Windows daemon support is planned): POSIX queries\n * `ps -o etime=,args=`; Windows queries Win32_Process via PowerShell CIM.\n */\n\nexport type ProcessQueryRunner = (command: string, args: string[]) => Promise<{ code: number; output: string }>;\n\nexport interface ProcessIdentity {\n\t/** Absolute process start time; undefined when the platform query lacks it. */\n\tstartTimeMs?: number;\n\tcommandLine: string;\n}\n\nexport type PidfileVerification = \"match\" | \"mismatch\" | \"gone\";\nexport type ProcessCreationVerification = \"match\" | \"mismatch\" | \"gone\" | \"unknown\";\n\nexport interface VerifyPidfileOptions {\n\trunner?: ProcessQueryRunner;\n\tplatform?: NodeJS.Platform;\n\tnow?: number;\n\t/** Allowed |actual start - pidfile.startedAtMs| skew (spawn-to-record delay, etime rounding). */\n\ttoleranceMs?: number;\n\t/** Injectable liveness probe (kill(pid, 0)). */\n\tisProcessAlive?: (pid: number) => \"alive\" | \"gone\";\n}\n\nexport const DEFAULT_START_TIME_TOLERANCE_MS = 15_000;\n\n/**\n * Command-line markers that identify a voltd process. Linux rewrites argv to the\n * process title (\"voltd\"); macOS and Windows report the original invocation\n * (`... daemon run --foreground`).\n *\n * The bare \"voltd\" marker is matched as a whole path/argv token, not a bare\n * substring: an unrelated but same-user process whose command line merely\n * contains the string (e.g. `tail -f /var/log/voltd.log`, `vim voltd.ts`,\n * `node .../voltd-cli/x.js`) must not satisfy the identity check and be signalled.\n */\nconst VOLTD_COMMAND_MARKERS = [/(?:^|[\\s/\\\\])voltd(?=$|[\\s/\\\\])/, \"daemon run --foreground\"] as const;\n\nconst defaultRunner: ProcessQueryRunner = (command, args) =>\n\tnew Promise((resolve) => {\n\t\tconst child = spawn(command, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\tlet output = \"\";\n\t\tchild.stdout?.on(\"data\", (chunk: Buffer) => {\n\t\t\toutput += chunk.toString(\"utf8\");\n\t\t});\n\t\tchild.on(\"error\", (error) => resolve({ code: 127, output: error.message }));\n\t\tchild.on(\"close\", (code) => resolve({ code: code ?? 1, output }));\n\t});\n\nfunction defaultIsProcessAlive(pid: number): \"alive\" | \"gone\" {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t\treturn \"alive\";\n\t} catch (error) {\n\t\t// EPERM: the pid exists but belongs to another user — alive (and almost\n\t\t// certainly not our daemon; the identity check will refuse it).\n\t\treturn error instanceof Error && \"code\" in error && (error as NodeJS.ErrnoException).code === \"EPERM\"\n\t\t\t? \"alive\"\n\t\t\t: \"gone\";\n\t}\n}\n\n/** Parse ps etime (\"[[dd-]hh:]mm:ss\") into elapsed milliseconds. */\nexport function parseElapsedTime(value: string): number | undefined {\n\tconst match = /^(?:(\\d+)-)?(?:(\\d+):)?(\\d{1,2}):(\\d{2})$/.exec(value.trim());\n\tif (!match) {\n\t\treturn undefined;\n\t}\n\tconst [, days, hours, minutes, seconds] = match;\n\treturn (Number(days ?? 0) * 86_400 + Number(hours ?? 0) * 3_600 + Number(minutes) * 60 + Number(seconds)) * 1_000;\n}\n\nasync function queryPosixProcess(\n\tpid: number,\n\trunner: ProcessQueryRunner,\n\tnow: () => number,\n): Promise<ProcessIdentity | undefined> {\n\t// etime (not the Linux-only etimes) is in the POSIX ps keyword set and has a\n\t// fixed, locale-independent format.\n\tconst result = await runner(\"ps\", [\"-p\", String(pid), \"-o\", \"etime=,args=\"]);\n\tif (result.code !== 0) {\n\t\treturn undefined;\n\t}\n\tconst line = result.output.split(\"\\n\").find((candidate) => candidate.trim().length > 0);\n\tif (!line) {\n\t\treturn undefined;\n\t}\n\tconst trimmed = line.trim();\n\tconst separatorIndex = trimmed.search(/\\s/);\n\tconst etime = separatorIndex === -1 ? trimmed : trimmed.slice(0, separatorIndex);\n\tconst commandLine = separatorIndex === -1 ? \"\" : trimmed.slice(separatorIndex + 1).trim();\n\tconst elapsedMs = parseElapsedTime(etime);\n\treturn {\n\t\t...(elapsedMs === undefined ? {} : { startTimeMs: now() - elapsedMs }),\n\t\tcommandLine,\n\t};\n}\n\nasync function queryWindowsProcess(pid: number, runner: ProcessQueryRunner): Promise<ProcessIdentity | undefined> {\n\t// CIM gives both an absolute creation time and the original command line.\n\tconst script =\n\t\t`$p = Get-CimInstance Win32_Process -Filter 'ProcessId=${pid}'; ` +\n\t\t`if ($p) { ConvertTo-Json -Compress @{ startMs = [DateTimeOffset]::new($p.CreationDate).ToUnixTimeMilliseconds(); commandLine = [string]$p.CommandLine } }`;\n\tconst result = await runner(\"powershell.exe\", [\"-NoProfile\", \"-NonInteractive\", \"-Command\", script]);\n\tif (result.code !== 0) {\n\t\treturn undefined;\n\t}\n\tconst jsonLine = result.output.split(\"\\n\").find((candidate) => candidate.trim().startsWith(\"{\"));\n\tif (!jsonLine) {\n\t\treturn undefined;\n\t}\n\ttry {\n\t\tconst parsed = JSON.parse(jsonLine.trim()) as { startMs?: unknown; commandLine?: unknown };\n\t\treturn {\n\t\t\t...(typeof parsed.startMs === \"number\" && Number.isFinite(parsed.startMs)\n\t\t\t\t? { startTimeMs: parsed.startMs }\n\t\t\t\t: {}),\n\t\t\tcommandLine: typeof parsed.commandLine === \"string\" ? parsed.commandLine : \"\",\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction commandLineLooksLikeVoltd(commandLine: string): boolean {\n\treturn VOLTD_COMMAND_MARKERS.some((marker) =>\n\t\ttypeof marker === \"string\" ? commandLine.includes(marker) : marker.test(commandLine),\n\t);\n}\n\ntype ProcessIdentityLookup = { kind: \"found\"; identity: ProcessIdentity } | { kind: \"gone\" } | { kind: \"unknown\" };\n\nasync function lookupProcessIdentity(pid: number, options: VerifyPidfileOptions): Promise<ProcessIdentityLookup> {\n\tconst runner = options.runner ?? defaultRunner;\n\tconst platform = options.platform ?? process.platform;\n\tconst now = () => options.now ?? Date.now();\n\tconst isProcessAlive = options.isProcessAlive ?? defaultIsProcessAlive;\n\tif (isProcessAlive(pid) === \"gone\") {\n\t\treturn { kind: \"gone\" };\n\t}\n\tconst identity =\n\t\tplatform === \"win32\" ? await queryWindowsProcess(pid, runner) : await queryPosixProcess(pid, runner, now);\n\tif (identity) {\n\t\treturn { kind: \"found\", identity };\n\t}\n\t// The process may have exited between the liveness probe and the query.\n\t// Otherwise its identity is unavailable and callers must fail closed.\n\treturn isProcessAlive(pid) === \"gone\" ? { kind: \"gone\" } : { kind: \"unknown\" };\n}\n\nfunction processStartTimeMatches(startedAtMs: number, identity: ProcessIdentity, toleranceMs: number): boolean {\n\treturn (\n\t\tidentity.startTimeMs !== undefined &&\n\t\tstartedAtMs > 0 &&\n\t\tMath.abs(identity.startTimeMs - startedAtMs) <= toleranceMs\n\t);\n}\n\n/**\n * Verify only process creation identity. Unlike pidfile verification, this\n * distinguishes a verifiable recycled PID from an unavailable OS query so\n * startup-lock recovery can reap the former while failing closed on the latter.\n */\nexport async function verifyProcessCreationTime(\n\trecord: { pid: number; startedAtMs: number },\n\toptions: VerifyPidfileOptions = {},\n): Promise<ProcessCreationVerification> {\n\tif (!Number.isInteger(record.pid) || record.pid <= 0) {\n\t\treturn \"mismatch\";\n\t}\n\tconst lookup = await lookupProcessIdentity(record.pid, options);\n\tif (lookup.kind !== \"found\") {\n\t\treturn lookup.kind;\n\t}\n\tif (record.startedAtMs <= 0 || lookup.identity.startTimeMs === undefined) {\n\t\treturn \"unknown\";\n\t}\n\tconst toleranceMs = options.toleranceMs ?? DEFAULT_START_TIME_TOLERANCE_MS;\n\treturn processStartTimeMatches(record.startedAtMs, lookup.identity, toleranceMs) ? \"match\" : \"mismatch\";\n}\n\n/** Verify both process creation identity and the voltd command marker. */\nexport async function verifyVoltdProcessIdentity(\n\trecord: { pid: number; startedAtMs: number },\n\toptions: VerifyPidfileOptions = {},\n): Promise<ProcessCreationVerification> {\n\tif (!Number.isInteger(record.pid) || record.pid <= 0) {\n\t\treturn \"mismatch\";\n\t}\n\tconst lookup = await lookupProcessIdentity(record.pid, options);\n\tif (lookup.kind !== \"found\") {\n\t\treturn lookup.kind;\n\t}\n\tif (record.startedAtMs <= 0 || lookup.identity.startTimeMs === undefined) {\n\t\treturn \"unknown\";\n\t}\n\tconst toleranceMs = options.toleranceMs ?? DEFAULT_START_TIME_TOLERANCE_MS;\n\tif (!processStartTimeMatches(record.startedAtMs, lookup.identity, toleranceMs)) {\n\t\treturn \"mismatch\";\n\t}\n\t// Matching creation evidence is conclusive enough to fail closed, but some\n\t// supported hosts (notably direct runVoltDaemon() calls on Windows) do not\n\t// expose a voltd marker in the immutable process command line.\n\treturn commandLineLooksLikeVoltd(lookup.identity.commandLine) ? \"match\" : \"unknown\";\n}\n\n/**\n * Verify that pidfile.pid still refers to the daemon that wrote the pidfile.\n *\n * - \"gone\": no such process (or it exited mid-check) — safe to treat as stopped.\n * - \"match\": alive, start time within tolerance of startedAtMs, and a\n * voltd-looking command line — safe to signal.\n * - \"mismatch\": alive but unverifiable or verifiably different (recycled pid,\n * another user's process, ps/powershell unavailable) — do NOT signal.\n */\nexport async function verifyPidfileProcess(\n\tpidfile: Pick<PidfileContents, \"pid\" | \"startedAtMs\">,\n\toptions: VerifyPidfileOptions = {},\n): Promise<PidfileVerification> {\n\tif (!Number.isInteger(pidfile.pid) || pidfile.pid <= 0) {\n\t\treturn \"mismatch\";\n\t}\n\tconst lookup = await lookupProcessIdentity(pidfile.pid, options);\n\tif (lookup.kind === \"gone\") {\n\t\treturn \"gone\";\n\t}\n\tif (lookup.kind === \"unknown\") {\n\t\treturn \"mismatch\";\n\t}\n\t// A match REQUIRES verifying the process start time against the pidfile, not\n\t// just a voltd-looking command line. Without that check (a legacy pidfile\n\t// missing startedAtMs, or the OS not reporting a start time) a recycled pid\n\t// whose command line merely contains a voltd marker must not be signalled.\n\tconst toleranceMs = options.toleranceMs ?? DEFAULT_START_TIME_TOLERANCE_MS;\n\tif (!processStartTimeMatches(pidfile.startedAtMs, lookup.identity, toleranceMs)) {\n\t\treturn \"mismatch\";\n\t}\n\treturn commandLineLooksLikeVoltd(lookup.identity.commandLine) ? \"match\" : \"mismatch\";\n}\n"]}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import type { Socket } from "node:net";
|
|
3
|
+
import type { IrohBiStreamLike } from "../core/rpc/iroh-transport.ts";
|
|
4
|
+
import { type RelayCloseReason, type RelayPreamble } from "./control-protocol.ts";
|
|
5
|
+
export declare const RELAY_TOKEN_TTL_MS = 10000;
|
|
6
|
+
export interface PendingRelay {
|
|
7
|
+
relayId: string;
|
|
8
|
+
relayToken: string;
|
|
9
|
+
workspaceName: string;
|
|
10
|
+
sessionId: string;
|
|
11
|
+
clientNodeId: string;
|
|
12
|
+
connectionId: string;
|
|
13
|
+
ownerControlConnectionId: string;
|
|
14
|
+
streamId: string;
|
|
15
|
+
/** The phone's Iroh stream, paused until the TUI redeems the token. */
|
|
16
|
+
stream: IrohBiStreamLike;
|
|
17
|
+
preamble: RelayPreamble;
|
|
18
|
+
expiresAt: number;
|
|
19
|
+
used: boolean;
|
|
20
|
+
/** Resolves when the relay finishes (either side closed). */
|
|
21
|
+
settle(outcome: RelayOutcome): void;
|
|
22
|
+
}
|
|
23
|
+
export interface RelayOutcome {
|
|
24
|
+
reason: RelayCloseReason;
|
|
25
|
+
bytesUp: number;
|
|
26
|
+
bytesDown: number;
|
|
27
|
+
durationMs: number;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ActiveRelay {
|
|
31
|
+
relayId: string;
|
|
32
|
+
workspaceName: string;
|
|
33
|
+
sessionId: string;
|
|
34
|
+
clientNodeId: string;
|
|
35
|
+
connectionId: string;
|
|
36
|
+
ownerControlConnectionId: string;
|
|
37
|
+
streamId: string;
|
|
38
|
+
close(reason: RelayCloseReason): void;
|
|
39
|
+
}
|
|
40
|
+
export type RelayRpcAuthorizationResult = {
|
|
41
|
+
ok: true;
|
|
42
|
+
relay: ActiveRelay;
|
|
43
|
+
} | {
|
|
44
|
+
ok: false;
|
|
45
|
+
code: "not_found" | "not_held" | "session_mismatch";
|
|
46
|
+
message: string;
|
|
47
|
+
};
|
|
48
|
+
export interface MintRelayOptions {
|
|
49
|
+
workspaceName: string;
|
|
50
|
+
sessionId: string;
|
|
51
|
+
clientNodeId: string;
|
|
52
|
+
connectionId: string;
|
|
53
|
+
ownerControlConnectionId: string;
|
|
54
|
+
streamId: string;
|
|
55
|
+
stream: IrohBiStreamLike;
|
|
56
|
+
preamble: Omit<RelayPreamble, "type" | "relayId">;
|
|
57
|
+
now?: number;
|
|
58
|
+
settle(outcome: RelayOutcome): void;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Daemon-side relay lifecycle: token mint/expiry (10s, single-use), preamble
|
|
62
|
+
* write, and the bidirectional raw byte pump between the phone's Iroh stream
|
|
63
|
+
* and the TUI's relay unix connection. No inspection, no reframing.
|
|
64
|
+
*/
|
|
65
|
+
export declare class RelayRegistry {
|
|
66
|
+
private readonly pending;
|
|
67
|
+
private readonly active;
|
|
68
|
+
mint(options: MintRelayOptions): PendingRelay;
|
|
69
|
+
/** Invalidate an unredeemed offer (rekey, duplicate replacement, expiry). */
|
|
70
|
+
invalidatePending(relayId: string): PendingRelay | undefined;
|
|
71
|
+
pendingForConversation(clientNodeId: string, workspaceName: string, sessionId: string): PendingRelay[];
|
|
72
|
+
activeForConversation(clientNodeId: string, workspaceName: string, sessionId: string): ActiveRelay[];
|
|
73
|
+
activeRelays(): ActiveRelay[];
|
|
74
|
+
pendingRelays(): PendingRelay[];
|
|
75
|
+
activeCount(): number;
|
|
76
|
+
authorizeRpc(relayId: string, ownerControlConnectionId: string, scope: {
|
|
77
|
+
clientNodeId: string;
|
|
78
|
+
workspaceName: string;
|
|
79
|
+
sessionId: string;
|
|
80
|
+
}): RelayRpcAuthorizationResult;
|
|
81
|
+
closeActive(relayId: string, reason: RelayCloseReason): void;
|
|
82
|
+
/**
|
|
83
|
+
* Redeem a relay token from a TUI relay hello. On success, acks the socket,
|
|
84
|
+
* writes the preamble line, and starts the byte pump. Returns false when the
|
|
85
|
+
* token is invalid/expired/used (caller sends bad_relay_token).
|
|
86
|
+
*/
|
|
87
|
+
admit(relayId: string, relayToken: string, socket: Socket, bufferedRemainder: Buffer, now?: number): boolean;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=relay-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-stream.d.ts","sourceRoot":"","sources":["../../src/daemon/relay-stream.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport { randomBytes, randomUUID } from \"node:crypto\";\nimport type { Socket } from \"node:net\";\nimport { DuplexWriteGate, StreamClosedError } from \"../core/rpc/duplex-write-gate.ts\";\nimport type { IrohBiStreamLike } from \"../core/rpc/iroh-transport.ts\";\nimport { encodeControlLine, type RelayCloseReason, type RelayPreamble } from \"./control-protocol.ts\";\n\nexport const RELAY_TOKEN_TTL_MS = 10_000;\n\nconst RELAY_READ_LIMIT = 64 * 1024;\n\nexport interface PendingRelay {\n\trelayId: string;\n\trelayToken: string;\n\tworkspaceName: string;\n\tsessionId: string;\n\tclientNodeId: string;\n\tconnectionId: string;\n\townerControlConnectionId: string;\n\tstreamId: string;\n\t/** The phone's Iroh stream, paused until the TUI redeems the token. */\n\tstream: IrohBiStreamLike;\n\tpreamble: RelayPreamble;\n\texpiresAt: number;\n\tused: boolean;\n\t/** Resolves when the relay finishes (either side closed). */\n\tsettle(outcome: RelayOutcome): void;\n}\n\nexport interface RelayOutcome {\n\treason: RelayCloseReason;\n\tbytesUp: number;\n\tbytesDown: number;\n\tdurationMs: number;\n\terror?: string;\n}\n\nexport interface ActiveRelay {\n\trelayId: string;\n\tworkspaceName: string;\n\tsessionId: string;\n\tclientNodeId: string;\n\tconnectionId: string;\n\townerControlConnectionId: string;\n\tstreamId: string;\n\tclose(reason: RelayCloseReason): void;\n}\n\nexport type RelayRpcAuthorizationResult =\n\t| { ok: true; relay: ActiveRelay }\n\t| { ok: false; code: \"not_found\" | \"not_held\" | \"session_mismatch\"; message: string };\n\nexport interface MintRelayOptions {\n\tworkspaceName: string;\n\tsessionId: string;\n\tclientNodeId: string;\n\tconnectionId: string;\n\townerControlConnectionId: string;\n\tstreamId: string;\n\tstream: IrohBiStreamLike;\n\tpreamble: Omit<RelayPreamble, \"type\" | \"relayId\">;\n\tnow?: number;\n\tsettle(outcome: RelayOutcome): void;\n}\n\n/**\n * Daemon-side relay lifecycle: token mint/expiry (10s, single-use), preamble\n * write, and the bidirectional raw byte pump between the phone's Iroh stream\n * and the TUI's relay unix connection. No inspection, no reframing.\n */\nexport class RelayRegistry {\n\tprivate readonly pending = new Map<string, PendingRelay>();\n\tprivate readonly active = new Map<string, ActiveRelay>();\n\n\tmint(options: MintRelayOptions): PendingRelay {\n\t\tconst relayId = `rl-${randomUUID()}`;\n\t\tconst relay: PendingRelay = {\n\t\t\trelayId,\n\t\t\trelayToken: randomBytes(32).toString(\"base64url\"),\n\t\t\tworkspaceName: options.workspaceName,\n\t\t\tsessionId: options.sessionId,\n\t\t\tclientNodeId: options.clientNodeId,\n\t\t\tconnectionId: options.connectionId,\n\t\t\townerControlConnectionId: options.ownerControlConnectionId,\n\t\t\tstreamId: options.streamId,\n\t\t\tstream: options.stream,\n\t\t\tpreamble: { ...options.preamble, type: \"relay_preamble\", relayId },\n\t\t\texpiresAt: (options.now ?? Date.now()) + RELAY_TOKEN_TTL_MS,\n\t\t\tused: false,\n\t\t\tsettle: options.settle,\n\t\t};\n\t\tthis.pending.set(relayId, relay);\n\t\treturn relay;\n\t}\n\n\t/** Invalidate an unredeemed offer (rekey, duplicate replacement, expiry). */\n\tinvalidatePending(relayId: string): PendingRelay | undefined {\n\t\tconst relay = this.pending.get(relayId);\n\t\tif (relay) {\n\t\t\trelay.used = true;\n\t\t\tthis.pending.delete(relayId);\n\t\t}\n\t\treturn relay;\n\t}\n\n\tpendingForConversation(clientNodeId: string, workspaceName: string, sessionId: string): PendingRelay[] {\n\t\treturn Array.from(this.pending.values()).filter(\n\t\t\t(relay) =>\n\t\t\t\trelay.clientNodeId === clientNodeId &&\n\t\t\t\trelay.workspaceName === workspaceName &&\n\t\t\t\trelay.sessionId === sessionId,\n\t\t);\n\t}\n\n\tactiveForConversation(clientNodeId: string, workspaceName: string, sessionId: string): ActiveRelay[] {\n\t\treturn Array.from(this.active.values()).filter(\n\t\t\t(relay) =>\n\t\t\t\trelay.clientNodeId === clientNodeId &&\n\t\t\t\trelay.workspaceName === workspaceName &&\n\t\t\t\trelay.sessionId === sessionId,\n\t\t);\n\t}\n\n\tactiveRelays(): ActiveRelay[] {\n\t\treturn Array.from(this.active.values());\n\t}\n\n\tpendingRelays(): PendingRelay[] {\n\t\treturn Array.from(this.pending.values());\n\t}\n\n\tactiveCount(): number {\n\t\treturn this.active.size;\n\t}\n\n\tauthorizeRpc(\n\t\trelayId: string,\n\t\townerControlConnectionId: string,\n\t\tscope: { clientNodeId: string; workspaceName: string; sessionId: string },\n\t): RelayRpcAuthorizationResult {\n\t\tconst relay = this.active.get(relayId);\n\t\tif (!relay) {\n\t\t\treturn { ok: false, code: \"not_found\", message: \"active relay not found\" };\n\t\t}\n\t\tif (relay.ownerControlConnectionId !== ownerControlConnectionId) {\n\t\t\treturn { ok: false, code: \"not_held\", message: \"relay is not owned by this control connection\" };\n\t\t}\n\t\tif (\n\t\t\trelay.clientNodeId !== scope.clientNodeId ||\n\t\t\trelay.workspaceName !== scope.workspaceName ||\n\t\t\trelay.sessionId !== scope.sessionId\n\t\t) {\n\t\t\treturn { ok: false, code: \"session_mismatch\", message: \"relay RPC scope does not match active relay\" };\n\t\t}\n\t\treturn { ok: true, relay };\n\t}\n\n\tcloseActive(relayId: string, reason: RelayCloseReason): void {\n\t\tthis.active.get(relayId)?.close(reason);\n\t}\n\n\t/**\n\t * Redeem a relay token from a TUI relay hello. On success, acks the socket,\n\t * writes the preamble line, and starts the byte pump. Returns false when the\n\t * token is invalid/expired/used (caller sends bad_relay_token).\n\t */\n\tadmit(relayId: string, relayToken: string, socket: Socket, bufferedRemainder: Buffer, now = Date.now()): boolean {\n\t\tconst relay = this.pending.get(relayId);\n\t\tif (!relay || relay.used || relay.relayToken !== relayToken || now > relay.expiresAt) {\n\t\t\treturn false;\n\t\t}\n\t\trelay.used = true;\n\t\tthis.pending.delete(relayId);\n\n\t\tsocket.write(encodeControlLine({ type: \"hello_ack\", ok: true }));\n\t\tsocket.write(encodeControlLine(relay.preamble));\n\n\t\tconst startedAt = now;\n\t\tconst writeGate = new DuplexWriteGate(socket);\n\t\tlet bytesUp = 0; // TUI -> phone\n\t\tlet bytesDown = 0; // phone -> TUI\n\t\tlet settled = false;\n\t\tlet closeReason: RelayCloseReason | undefined;\n\n\t\tconst finish = (reason: RelayCloseReason, error?: string) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tthis.active.delete(relay.relayId);\n\t\t\twriteGate.dispose();\n\t\t\tsocket.destroy();\n\t\t\tvoid Promise.resolve(relay.stream.send.finish?.()).catch(() => {});\n\t\t\tvoid Promise.resolve(relay.stream.recv.stop?.(0n)).catch(() => {});\n\t\t\trelay.settle({\n\t\t\t\treason: closeReason ?? reason,\n\t\t\t\tbytesUp,\n\t\t\t\tbytesDown,\n\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t...(error === undefined ? {} : { error }),\n\t\t\t});\n\t\t};\n\n\t\tconst activeRelay: ActiveRelay = {\n\t\t\trelayId: relay.relayId,\n\t\t\tworkspaceName: relay.workspaceName,\n\t\t\tsessionId: relay.sessionId,\n\t\t\tclientNodeId: relay.clientNodeId,\n\t\t\tconnectionId: relay.connectionId,\n\t\t\townerControlConnectionId: relay.ownerControlConnectionId,\n\t\t\tstreamId: relay.streamId,\n\t\t\tclose: (reason: RelayCloseReason) => {\n\t\t\t\tcloseReason = reason;\n\t\t\t\tfinish(reason);\n\t\t\t},\n\t\t};\n\t\tthis.active.set(relay.relayId, activeRelay);\n\n\t\t// TUI -> phone: socket bytes go straight to the Iroh send stream. The\n\t\t// socket is paused while a chunk is in flight so a slow phone link cannot\n\t\t// buffer unbounded data in the write queue.\n\t\tlet writeQueue: Promise<void> = Promise.resolve();\n\t\tconst enqueueWrite = (chunk: Buffer, pauseSocket: boolean) => {\n\t\t\tbytesUp += chunk.length;\n\t\t\tif (pauseSocket) {\n\t\t\t\tsocket.pause();\n\t\t\t}\n\t\t\tconst bytes = Array.from(chunk);\n\t\t\twriteQueue = writeQueue\n\t\t\t\t.then(() => relay.stream.send.writeAll(bytes))\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (pauseSocket && !settled) {\n\t\t\t\t\t\tsocket.resume();\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch((error: unknown) => {\n\t\t\t\t\tfinish(\"error\", error instanceof Error ? error.message : String(error));\n\t\t\t\t});\n\t\t};\n\t\tif (bufferedRemainder.length > 0) {\n\t\t\tenqueueWrite(bufferedRemainder, false);\n\t\t}\n\t\tsocket.on(\"data\", (chunk: Buffer) => enqueueWrite(chunk, true));\n\t\tsocket.on(\"error\", (error: Error) => finish(\"error\", error.message));\n\t\t// A close without a daemon-initiated reason or a socket error is the TUI\n\t\t// going away (process exit, socket destroy).\n\t\tsocket.on(\"close\", () => finish(closeReason ?? \"tui_disconnected\"));\n\t\tsocket.on(\"end\", () => {\n\t\t\t// TUI half-closed: propagate to the phone's send side.\n\t\t\tvoid writeQueue.then(() => Promise.resolve(relay.stream.send.finish?.())).catch(() => {});\n\t\t});\n\n\t\t// Phone -> TUI: pull from the Iroh recv stream into the socket.\n\t\tvoid (async () => {\n\t\t\ttry {\n\t\t\t\twhile (!settled) {\n\t\t\t\t\tconst chunk = await relay.stream.recv.read(RELAY_READ_LIMIT);\n\t\t\t\t\tif (!chunk || chunk.length === 0) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst buffer = Buffer.from(Array.from(chunk));\n\t\t\t\t\tbytesDown += buffer.length;\n\t\t\t\t\tawait writeGate.write(buffer);\n\t\t\t\t\tif (settled) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!settled) {\n\t\t\t\t\t// Phone half-closed or ended: flush any bytes still buffered in the\n\t\t\t\t\t// socket write queue and send FIN to the TUI, waiting for the write\n\t\t\t\t\t// side to drain before finish() destroys the socket. A bare\n\t\t\t\t\t// socket.end() + immediate destroy discards the unflushed tail of the\n\t\t\t\t\t// phone's final response.\n\t\t\t\t\tawait writeGate.end().catch(() => {});\n\t\t\t\t\tfinish(closeReason ?? \"phone_disconnected\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof StreamClosedError) {\n\t\t\t\t\tfinish(closeReason ?? \"tui_disconnected\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfinish(\"error\", error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t})();\n\n\t\treturn true;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
|
+
import { DuplexWriteGate, StreamClosedError } from "../core/rpc/duplex-write-gate.js";
|
|
4
|
+
import { encodeControlLine } from "./control-protocol.js";
|
|
5
|
+
export const RELAY_TOKEN_TTL_MS = 10_000;
|
|
6
|
+
const RELAY_READ_LIMIT = 64 * 1024;
|
|
7
|
+
/**
|
|
8
|
+
* Daemon-side relay lifecycle: token mint/expiry (10s, single-use), preamble
|
|
9
|
+
* write, and the bidirectional raw byte pump between the phone's Iroh stream
|
|
10
|
+
* and the TUI's relay unix connection. No inspection, no reframing.
|
|
11
|
+
*/
|
|
12
|
+
export class RelayRegistry {
|
|
13
|
+
pending = new Map();
|
|
14
|
+
active = new Map();
|
|
15
|
+
mint(options) {
|
|
16
|
+
const relayId = `rl-${randomUUID()}`;
|
|
17
|
+
const relay = {
|
|
18
|
+
relayId,
|
|
19
|
+
relayToken: randomBytes(32).toString("base64url"),
|
|
20
|
+
workspaceName: options.workspaceName,
|
|
21
|
+
sessionId: options.sessionId,
|
|
22
|
+
clientNodeId: options.clientNodeId,
|
|
23
|
+
connectionId: options.connectionId,
|
|
24
|
+
ownerControlConnectionId: options.ownerControlConnectionId,
|
|
25
|
+
streamId: options.streamId,
|
|
26
|
+
stream: options.stream,
|
|
27
|
+
preamble: { ...options.preamble, type: "relay_preamble", relayId },
|
|
28
|
+
expiresAt: (options.now ?? Date.now()) + RELAY_TOKEN_TTL_MS,
|
|
29
|
+
used: false,
|
|
30
|
+
settle: options.settle,
|
|
31
|
+
};
|
|
32
|
+
this.pending.set(relayId, relay);
|
|
33
|
+
return relay;
|
|
34
|
+
}
|
|
35
|
+
/** Invalidate an unredeemed offer (rekey, duplicate replacement, expiry). */
|
|
36
|
+
invalidatePending(relayId) {
|
|
37
|
+
const relay = this.pending.get(relayId);
|
|
38
|
+
if (relay) {
|
|
39
|
+
relay.used = true;
|
|
40
|
+
this.pending.delete(relayId);
|
|
41
|
+
}
|
|
42
|
+
return relay;
|
|
43
|
+
}
|
|
44
|
+
pendingForConversation(clientNodeId, workspaceName, sessionId) {
|
|
45
|
+
return Array.from(this.pending.values()).filter((relay) => relay.clientNodeId === clientNodeId &&
|
|
46
|
+
relay.workspaceName === workspaceName &&
|
|
47
|
+
relay.sessionId === sessionId);
|
|
48
|
+
}
|
|
49
|
+
activeForConversation(clientNodeId, workspaceName, sessionId) {
|
|
50
|
+
return Array.from(this.active.values()).filter((relay) => relay.clientNodeId === clientNodeId &&
|
|
51
|
+
relay.workspaceName === workspaceName &&
|
|
52
|
+
relay.sessionId === sessionId);
|
|
53
|
+
}
|
|
54
|
+
activeRelays() {
|
|
55
|
+
return Array.from(this.active.values());
|
|
56
|
+
}
|
|
57
|
+
pendingRelays() {
|
|
58
|
+
return Array.from(this.pending.values());
|
|
59
|
+
}
|
|
60
|
+
activeCount() {
|
|
61
|
+
return this.active.size;
|
|
62
|
+
}
|
|
63
|
+
authorizeRpc(relayId, ownerControlConnectionId, scope) {
|
|
64
|
+
const relay = this.active.get(relayId);
|
|
65
|
+
if (!relay) {
|
|
66
|
+
return { ok: false, code: "not_found", message: "active relay not found" };
|
|
67
|
+
}
|
|
68
|
+
if (relay.ownerControlConnectionId !== ownerControlConnectionId) {
|
|
69
|
+
return { ok: false, code: "not_held", message: "relay is not owned by this control connection" };
|
|
70
|
+
}
|
|
71
|
+
if (relay.clientNodeId !== scope.clientNodeId ||
|
|
72
|
+
relay.workspaceName !== scope.workspaceName ||
|
|
73
|
+
relay.sessionId !== scope.sessionId) {
|
|
74
|
+
return { ok: false, code: "session_mismatch", message: "relay RPC scope does not match active relay" };
|
|
75
|
+
}
|
|
76
|
+
return { ok: true, relay };
|
|
77
|
+
}
|
|
78
|
+
closeActive(relayId, reason) {
|
|
79
|
+
this.active.get(relayId)?.close(reason);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Redeem a relay token from a TUI relay hello. On success, acks the socket,
|
|
83
|
+
* writes the preamble line, and starts the byte pump. Returns false when the
|
|
84
|
+
* token is invalid/expired/used (caller sends bad_relay_token).
|
|
85
|
+
*/
|
|
86
|
+
admit(relayId, relayToken, socket, bufferedRemainder, now = Date.now()) {
|
|
87
|
+
const relay = this.pending.get(relayId);
|
|
88
|
+
if (!relay || relay.used || relay.relayToken !== relayToken || now > relay.expiresAt) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
relay.used = true;
|
|
92
|
+
this.pending.delete(relayId);
|
|
93
|
+
socket.write(encodeControlLine({ type: "hello_ack", ok: true }));
|
|
94
|
+
socket.write(encodeControlLine(relay.preamble));
|
|
95
|
+
const startedAt = now;
|
|
96
|
+
const writeGate = new DuplexWriteGate(socket);
|
|
97
|
+
let bytesUp = 0; // TUI -> phone
|
|
98
|
+
let bytesDown = 0; // phone -> TUI
|
|
99
|
+
let settled = false;
|
|
100
|
+
let closeReason;
|
|
101
|
+
const finish = (reason, error) => {
|
|
102
|
+
if (settled) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
settled = true;
|
|
106
|
+
this.active.delete(relay.relayId);
|
|
107
|
+
writeGate.dispose();
|
|
108
|
+
socket.destroy();
|
|
109
|
+
void Promise.resolve(relay.stream.send.finish?.()).catch(() => { });
|
|
110
|
+
void Promise.resolve(relay.stream.recv.stop?.(0n)).catch(() => { });
|
|
111
|
+
relay.settle({
|
|
112
|
+
reason: closeReason ?? reason,
|
|
113
|
+
bytesUp,
|
|
114
|
+
bytesDown,
|
|
115
|
+
durationMs: Date.now() - startedAt,
|
|
116
|
+
...(error === undefined ? {} : { error }),
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
const activeRelay = {
|
|
120
|
+
relayId: relay.relayId,
|
|
121
|
+
workspaceName: relay.workspaceName,
|
|
122
|
+
sessionId: relay.sessionId,
|
|
123
|
+
clientNodeId: relay.clientNodeId,
|
|
124
|
+
connectionId: relay.connectionId,
|
|
125
|
+
ownerControlConnectionId: relay.ownerControlConnectionId,
|
|
126
|
+
streamId: relay.streamId,
|
|
127
|
+
close: (reason) => {
|
|
128
|
+
closeReason = reason;
|
|
129
|
+
finish(reason);
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
this.active.set(relay.relayId, activeRelay);
|
|
133
|
+
// TUI -> phone: socket bytes go straight to the Iroh send stream. The
|
|
134
|
+
// socket is paused while a chunk is in flight so a slow phone link cannot
|
|
135
|
+
// buffer unbounded data in the write queue.
|
|
136
|
+
let writeQueue = Promise.resolve();
|
|
137
|
+
const enqueueWrite = (chunk, pauseSocket) => {
|
|
138
|
+
bytesUp += chunk.length;
|
|
139
|
+
if (pauseSocket) {
|
|
140
|
+
socket.pause();
|
|
141
|
+
}
|
|
142
|
+
const bytes = Array.from(chunk);
|
|
143
|
+
writeQueue = writeQueue
|
|
144
|
+
.then(() => relay.stream.send.writeAll(bytes))
|
|
145
|
+
.then(() => {
|
|
146
|
+
if (pauseSocket && !settled) {
|
|
147
|
+
socket.resume();
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
.catch((error) => {
|
|
151
|
+
finish("error", error instanceof Error ? error.message : String(error));
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
if (bufferedRemainder.length > 0) {
|
|
155
|
+
enqueueWrite(bufferedRemainder, false);
|
|
156
|
+
}
|
|
157
|
+
socket.on("data", (chunk) => enqueueWrite(chunk, true));
|
|
158
|
+
socket.on("error", (error) => finish("error", error.message));
|
|
159
|
+
// A close without a daemon-initiated reason or a socket error is the TUI
|
|
160
|
+
// going away (process exit, socket destroy).
|
|
161
|
+
socket.on("close", () => finish(closeReason ?? "tui_disconnected"));
|
|
162
|
+
socket.on("end", () => {
|
|
163
|
+
// TUI half-closed: propagate to the phone's send side.
|
|
164
|
+
void writeQueue.then(() => Promise.resolve(relay.stream.send.finish?.())).catch(() => { });
|
|
165
|
+
});
|
|
166
|
+
// Phone -> TUI: pull from the Iroh recv stream into the socket.
|
|
167
|
+
void (async () => {
|
|
168
|
+
try {
|
|
169
|
+
while (!settled) {
|
|
170
|
+
const chunk = await relay.stream.recv.read(RELAY_READ_LIMIT);
|
|
171
|
+
if (!chunk || chunk.length === 0) {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
const buffer = Buffer.from(Array.from(chunk));
|
|
175
|
+
bytesDown += buffer.length;
|
|
176
|
+
await writeGate.write(buffer);
|
|
177
|
+
if (settled) {
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (!settled) {
|
|
182
|
+
// Phone half-closed or ended: flush any bytes still buffered in the
|
|
183
|
+
// socket write queue and send FIN to the TUI, waiting for the write
|
|
184
|
+
// side to drain before finish() destroys the socket. A bare
|
|
185
|
+
// socket.end() + immediate destroy discards the unflushed tail of the
|
|
186
|
+
// phone's final response.
|
|
187
|
+
await writeGate.end().catch(() => { });
|
|
188
|
+
finish(closeReason ?? "phone_disconnected");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
if (error instanceof StreamClosedError) {
|
|
193
|
+
finish(closeReason ?? "tui_disconnected");
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
finish("error", error instanceof Error ? error.message : String(error));
|
|
197
|
+
}
|
|
198
|
+
})();
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=relay-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-stream.js","sourceRoot":"","sources":["../../src/daemon/relay-stream.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport { randomBytes, randomUUID } from \"node:crypto\";\nimport type { Socket } from \"node:net\";\nimport { DuplexWriteGate, StreamClosedError } from \"../core/rpc/duplex-write-gate.ts\";\nimport type { IrohBiStreamLike } from \"../core/rpc/iroh-transport.ts\";\nimport { encodeControlLine, type RelayCloseReason, type RelayPreamble } from \"./control-protocol.ts\";\n\nexport const RELAY_TOKEN_TTL_MS = 10_000;\n\nconst RELAY_READ_LIMIT = 64 * 1024;\n\nexport interface PendingRelay {\n\trelayId: string;\n\trelayToken: string;\n\tworkspaceName: string;\n\tsessionId: string;\n\tclientNodeId: string;\n\tconnectionId: string;\n\townerControlConnectionId: string;\n\tstreamId: string;\n\t/** The phone's Iroh stream, paused until the TUI redeems the token. */\n\tstream: IrohBiStreamLike;\n\tpreamble: RelayPreamble;\n\texpiresAt: number;\n\tused: boolean;\n\t/** Resolves when the relay finishes (either side closed). */\n\tsettle(outcome: RelayOutcome): void;\n}\n\nexport interface RelayOutcome {\n\treason: RelayCloseReason;\n\tbytesUp: number;\n\tbytesDown: number;\n\tdurationMs: number;\n\terror?: string;\n}\n\nexport interface ActiveRelay {\n\trelayId: string;\n\tworkspaceName: string;\n\tsessionId: string;\n\tclientNodeId: string;\n\tconnectionId: string;\n\townerControlConnectionId: string;\n\tstreamId: string;\n\tclose(reason: RelayCloseReason): void;\n}\n\nexport type RelayRpcAuthorizationResult =\n\t| { ok: true; relay: ActiveRelay }\n\t| { ok: false; code: \"not_found\" | \"not_held\" | \"session_mismatch\"; message: string };\n\nexport interface MintRelayOptions {\n\tworkspaceName: string;\n\tsessionId: string;\n\tclientNodeId: string;\n\tconnectionId: string;\n\townerControlConnectionId: string;\n\tstreamId: string;\n\tstream: IrohBiStreamLike;\n\tpreamble: Omit<RelayPreamble, \"type\" | \"relayId\">;\n\tnow?: number;\n\tsettle(outcome: RelayOutcome): void;\n}\n\n/**\n * Daemon-side relay lifecycle: token mint/expiry (10s, single-use), preamble\n * write, and the bidirectional raw byte pump between the phone's Iroh stream\n * and the TUI's relay unix connection. No inspection, no reframing.\n */\nexport class RelayRegistry {\n\tprivate readonly pending = new Map<string, PendingRelay>();\n\tprivate readonly active = new Map<string, ActiveRelay>();\n\n\tmint(options: MintRelayOptions): PendingRelay {\n\t\tconst relayId = `rl-${randomUUID()}`;\n\t\tconst relay: PendingRelay = {\n\t\t\trelayId,\n\t\t\trelayToken: randomBytes(32).toString(\"base64url\"),\n\t\t\tworkspaceName: options.workspaceName,\n\t\t\tsessionId: options.sessionId,\n\t\t\tclientNodeId: options.clientNodeId,\n\t\t\tconnectionId: options.connectionId,\n\t\t\townerControlConnectionId: options.ownerControlConnectionId,\n\t\t\tstreamId: options.streamId,\n\t\t\tstream: options.stream,\n\t\t\tpreamble: { ...options.preamble, type: \"relay_preamble\", relayId },\n\t\t\texpiresAt: (options.now ?? Date.now()) + RELAY_TOKEN_TTL_MS,\n\t\t\tused: false,\n\t\t\tsettle: options.settle,\n\t\t};\n\t\tthis.pending.set(relayId, relay);\n\t\treturn relay;\n\t}\n\n\t/** Invalidate an unredeemed offer (rekey, duplicate replacement, expiry). */\n\tinvalidatePending(relayId: string): PendingRelay | undefined {\n\t\tconst relay = this.pending.get(relayId);\n\t\tif (relay) {\n\t\t\trelay.used = true;\n\t\t\tthis.pending.delete(relayId);\n\t\t}\n\t\treturn relay;\n\t}\n\n\tpendingForConversation(clientNodeId: string, workspaceName: string, sessionId: string): PendingRelay[] {\n\t\treturn Array.from(this.pending.values()).filter(\n\t\t\t(relay) =>\n\t\t\t\trelay.clientNodeId === clientNodeId &&\n\t\t\t\trelay.workspaceName === workspaceName &&\n\t\t\t\trelay.sessionId === sessionId,\n\t\t);\n\t}\n\n\tactiveForConversation(clientNodeId: string, workspaceName: string, sessionId: string): ActiveRelay[] {\n\t\treturn Array.from(this.active.values()).filter(\n\t\t\t(relay) =>\n\t\t\t\trelay.clientNodeId === clientNodeId &&\n\t\t\t\trelay.workspaceName === workspaceName &&\n\t\t\t\trelay.sessionId === sessionId,\n\t\t);\n\t}\n\n\tactiveRelays(): ActiveRelay[] {\n\t\treturn Array.from(this.active.values());\n\t}\n\n\tpendingRelays(): PendingRelay[] {\n\t\treturn Array.from(this.pending.values());\n\t}\n\n\tactiveCount(): number {\n\t\treturn this.active.size;\n\t}\n\n\tauthorizeRpc(\n\t\trelayId: string,\n\t\townerControlConnectionId: string,\n\t\tscope: { clientNodeId: string; workspaceName: string; sessionId: string },\n\t): RelayRpcAuthorizationResult {\n\t\tconst relay = this.active.get(relayId);\n\t\tif (!relay) {\n\t\t\treturn { ok: false, code: \"not_found\", message: \"active relay not found\" };\n\t\t}\n\t\tif (relay.ownerControlConnectionId !== ownerControlConnectionId) {\n\t\t\treturn { ok: false, code: \"not_held\", message: \"relay is not owned by this control connection\" };\n\t\t}\n\t\tif (\n\t\t\trelay.clientNodeId !== scope.clientNodeId ||\n\t\t\trelay.workspaceName !== scope.workspaceName ||\n\t\t\trelay.sessionId !== scope.sessionId\n\t\t) {\n\t\t\treturn { ok: false, code: \"session_mismatch\", message: \"relay RPC scope does not match active relay\" };\n\t\t}\n\t\treturn { ok: true, relay };\n\t}\n\n\tcloseActive(relayId: string, reason: RelayCloseReason): void {\n\t\tthis.active.get(relayId)?.close(reason);\n\t}\n\n\t/**\n\t * Redeem a relay token from a TUI relay hello. On success, acks the socket,\n\t * writes the preamble line, and starts the byte pump. Returns false when the\n\t * token is invalid/expired/used (caller sends bad_relay_token).\n\t */\n\tadmit(relayId: string, relayToken: string, socket: Socket, bufferedRemainder: Buffer, now = Date.now()): boolean {\n\t\tconst relay = this.pending.get(relayId);\n\t\tif (!relay || relay.used || relay.relayToken !== relayToken || now > relay.expiresAt) {\n\t\t\treturn false;\n\t\t}\n\t\trelay.used = true;\n\t\tthis.pending.delete(relayId);\n\n\t\tsocket.write(encodeControlLine({ type: \"hello_ack\", ok: true }));\n\t\tsocket.write(encodeControlLine(relay.preamble));\n\n\t\tconst startedAt = now;\n\t\tconst writeGate = new DuplexWriteGate(socket);\n\t\tlet bytesUp = 0; // TUI -> phone\n\t\tlet bytesDown = 0; // phone -> TUI\n\t\tlet settled = false;\n\t\tlet closeReason: RelayCloseReason | undefined;\n\n\t\tconst finish = (reason: RelayCloseReason, error?: string) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tthis.active.delete(relay.relayId);\n\t\t\twriteGate.dispose();\n\t\t\tsocket.destroy();\n\t\t\tvoid Promise.resolve(relay.stream.send.finish?.()).catch(() => {});\n\t\t\tvoid Promise.resolve(relay.stream.recv.stop?.(0n)).catch(() => {});\n\t\t\trelay.settle({\n\t\t\t\treason: closeReason ?? reason,\n\t\t\t\tbytesUp,\n\t\t\t\tbytesDown,\n\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t...(error === undefined ? {} : { error }),\n\t\t\t});\n\t\t};\n\n\t\tconst activeRelay: ActiveRelay = {\n\t\t\trelayId: relay.relayId,\n\t\t\tworkspaceName: relay.workspaceName,\n\t\t\tsessionId: relay.sessionId,\n\t\t\tclientNodeId: relay.clientNodeId,\n\t\t\tconnectionId: relay.connectionId,\n\t\t\townerControlConnectionId: relay.ownerControlConnectionId,\n\t\t\tstreamId: relay.streamId,\n\t\t\tclose: (reason: RelayCloseReason) => {\n\t\t\t\tcloseReason = reason;\n\t\t\t\tfinish(reason);\n\t\t\t},\n\t\t};\n\t\tthis.active.set(relay.relayId, activeRelay);\n\n\t\t// TUI -> phone: socket bytes go straight to the Iroh send stream. The\n\t\t// socket is paused while a chunk is in flight so a slow phone link cannot\n\t\t// buffer unbounded data in the write queue.\n\t\tlet writeQueue: Promise<void> = Promise.resolve();\n\t\tconst enqueueWrite = (chunk: Buffer, pauseSocket: boolean) => {\n\t\t\tbytesUp += chunk.length;\n\t\t\tif (pauseSocket) {\n\t\t\t\tsocket.pause();\n\t\t\t}\n\t\t\tconst bytes = Array.from(chunk);\n\t\t\twriteQueue = writeQueue\n\t\t\t\t.then(() => relay.stream.send.writeAll(bytes))\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (pauseSocket && !settled) {\n\t\t\t\t\t\tsocket.resume();\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch((error: unknown) => {\n\t\t\t\t\tfinish(\"error\", error instanceof Error ? error.message : String(error));\n\t\t\t\t});\n\t\t};\n\t\tif (bufferedRemainder.length > 0) {\n\t\t\tenqueueWrite(bufferedRemainder, false);\n\t\t}\n\t\tsocket.on(\"data\", (chunk: Buffer) => enqueueWrite(chunk, true));\n\t\tsocket.on(\"error\", (error: Error) => finish(\"error\", error.message));\n\t\t// A close without a daemon-initiated reason or a socket error is the TUI\n\t\t// going away (process exit, socket destroy).\n\t\tsocket.on(\"close\", () => finish(closeReason ?? \"tui_disconnected\"));\n\t\tsocket.on(\"end\", () => {\n\t\t\t// TUI half-closed: propagate to the phone's send side.\n\t\t\tvoid writeQueue.then(() => Promise.resolve(relay.stream.send.finish?.())).catch(() => {});\n\t\t});\n\n\t\t// Phone -> TUI: pull from the Iroh recv stream into the socket.\n\t\tvoid (async () => {\n\t\t\ttry {\n\t\t\t\twhile (!settled) {\n\t\t\t\t\tconst chunk = await relay.stream.recv.read(RELAY_READ_LIMIT);\n\t\t\t\t\tif (!chunk || chunk.length === 0) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst buffer = Buffer.from(Array.from(chunk));\n\t\t\t\t\tbytesDown += buffer.length;\n\t\t\t\t\tawait writeGate.write(buffer);\n\t\t\t\t\tif (settled) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!settled) {\n\t\t\t\t\t// Phone half-closed or ended: flush any bytes still buffered in the\n\t\t\t\t\t// socket write queue and send FIN to the TUI, waiting for the write\n\t\t\t\t\t// side to drain before finish() destroys the socket. A bare\n\t\t\t\t\t// socket.end() + immediate destroy discards the unflushed tail of the\n\t\t\t\t\t// phone's final response.\n\t\t\t\t\tawait writeGate.end().catch(() => {});\n\t\t\t\t\tfinish(closeReason ?? \"phone_disconnected\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof StreamClosedError) {\n\t\t\t\t\tfinish(closeReason ?? \"tui_disconnected\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfinish(\"error\", error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t})();\n\n\t\treturn true;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Render only the non-secret ticket fields a user should compare in Volt. */
|
|
2
|
+
export declare function formatRemotePairingVerificationLines(ticket: string): string[];
|
|
3
|
+
/** Router for `volt remote <command>` (daemon control clients); returns true when handled. */
|
|
4
|
+
export declare function handleRemoteControlCommand(args: string[], options: {
|
|
5
|
+
isStandaloneBinary: boolean;
|
|
6
|
+
}): Promise<boolean>;
|
|
7
|
+
//# sourceMappingURL=remote-cli.d.ts.map
|