@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 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/daemon/main.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { realpath, stat } from \"node:fs/promises\";\nimport type { Socket } from \"node:net\";\nimport { join } from \"node:path\";\nimport { getAgentDir, VERSION } from \"../config.ts\";\nimport { AuthStorage } from \"../core/auth-storage.ts\";\nimport {\n\tcreateIrohRemoteExplicitAccess,\n\tcreateIrohRemotePresetAccess,\n\tparseIrohRemoteRpcCapabilities,\n\tparseIrohRemoteRpcGrant,\n} from \"../core/remote/iroh/access-grant.ts\";\nimport { IrohRemoteAuditLogger } from \"../core/remote/iroh/audit.ts\";\nimport { IrohRemotePushRelayHttpClient, revokeIrohRemoteClientPushTargets } from \"../core/remote/iroh/push.ts\";\nimport {\n\tIROH_REMOTE_WORKSPACE_HAS_WORKTREES_ERROR,\n\tIrohRemoteHostStateManager,\n\tisIrohRemoteWorkspaceHasWorktreesError,\n} from \"../core/remote/iroh/state-manager.ts\";\nimport { SettingsManager } from \"../core/settings-manager.ts\";\nimport {\n\tgetCurrentThemeName,\n\tgetResolvedThemeColors,\n\tgetThemeByName,\n\tinitTheme,\n\tonThemeChange,\n\tsetTheme,\n} from \"../core/theme/runtime.ts\";\nimport { BRAVE_SEARCH_AUTH_PROVIDER } from \"../core/tools/web-search.ts\";\nimport type {\n\tControlClientStatus,\n\tControlLeaseStatus,\n\tControlRequest,\n\tControlRevokedClientStatus,\n\tControlWorkspaceStatus,\n} from \"./control-protocol.ts\";\nimport { CONTROL_PAIR_CANCEL_CAPABILITY, CONTROL_RPC_GRANTS_CAPABILITY, PROTOCOL_VERSION } from \"./control-protocol.ts\";\nimport {\n\ttype ControlConnection,\n\ttype ControlServer,\n\tprobeControlSocket,\n\tstartControlServer,\n} from \"./control-server.ts\";\nimport {\n\tacquireDaemonLock,\n\tDAEMON_LOCK_START_TIME_TOLERANCE_MS,\n\ttype DaemonLock,\n\ttype DaemonLockOwner,\n} from \"./daemon-lock.ts\";\nimport { KeepAwakeController, type KeepAwakeControllerOptions } from \"./keep-awake.ts\";\nimport type { DaemonLogger } from \"./log.ts\";\nimport { createDaemonLogger } from \"./log.ts\";\nimport {\n\tcreateDaemonControlSocketPath,\n\ttype DaemonPaths,\n\tensureDaemonDirs,\n\tgetDaemonPaths,\n\tisWindowsNamedPipePath,\n} from \"./paths.ts\";\nimport { verifyPidfileProcess, verifyVoltdProcessIdentity } from \"./process-identity.ts\";\nimport { VoltdStateStore } from \"./state.ts\";\nimport { handleWorktreeControlRequest, isWorktreeControlRequest, WorktreeManager } from \"./worktree-manager.ts\";\n\nexport interface Clock {\n\tnow(): number;\n}\n\nexport interface VoltdConfig {\n\tagentDir?: string;\n\tsocketPath?: string;\n\tlogPath?: string;\n\tforeground: boolean;\n\tclock?: Clock;\n\t/** Keep-awake controller overrides (tests inject a fake spawn here). */\n\tkeepAwake?: KeepAwakeControllerOptions;\n}\n\nexport interface PidfileContents {\n\tpid: number;\n\tversion: string;\n\tstartedAtMs: number;\n\tsocketPath: string;\n\t/** Per-daemon instance token; optional for pidfiles written by older versions. */\n\ttoken?: string;\n}\n\nexport function readPidfile(pidfilePath: string): PidfileContents | undefined {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(pidfilePath, \"utf8\")) as Partial<PidfileContents>;\n\t\tif (typeof parsed.pid !== \"number\" || typeof parsed.socketPath !== \"string\") {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tpid: parsed.pid,\n\t\t\tversion: typeof parsed.version === \"string\" ? parsed.version : \"unknown\",\n\t\t\tstartedAtMs: typeof parsed.startedAtMs === \"number\" ? parsed.startedAtMs : 0,\n\t\t\tsocketPath: parsed.socketPath,\n\t\t\t...(typeof parsed.token === \"string\" ? { token: parsed.token } : {}),\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport const VOLTD_EXIT_ALREADY_RUNNING = 3;\nexport const VOLTD_EXIT_BIND_FAILED = 4;\nexport const VOLTD_EXIT_INCOMPATIBLE_RUNNING = 5;\n\nconst DAEMON_BIND_WAIT_TIMEOUT_MS = 75_000;\nconst DAEMON_BIND_WAIT_POLL_MS = 200;\n\nasync function sleep(ms: number): Promise<void> {\n\tawait new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Facilities later milestones build on (lease broker, Iroh host, theme service). */\nexport interface VoltdRuntimeServices {\n\tagentDir: string;\n\tpaths: DaemonPaths;\n\tlogger: DaemonLogger;\n\tstate: VoltdStateStore;\n\tstateManager: IrohRemoteHostStateManager;\n\tauditLogger: IrohRemoteAuditLogger;\n\tcontrolServer: ControlServer;\n\tkeepAwake: KeepAwakeController;\n\t/** Stored Brave Search API key for the web_search tool, persisted in auth.json. */\n\twebSearchKey: { set(apiKey: string | null): void; readonly configured: boolean };\n\trequestShutdown(reason: \"cli\" | \"signal\"): void;\n}\n\nexport interface VoltdServiceExtensionInstance {\n\t/** Extra request handling; return true when the request was handled. */\n\thandleRequest?(connection: ControlConnection, request: ControlRequest): Promise<boolean> | boolean;\n\tonConnectionClosed?(connection: ControlConnection): void;\n\t/** The daemon's active theme changed (theme_set or an extension setTheme). */\n\tonThemeChanged?(): void;\n\t/** Keep-awake status changed (control toggle, phone RPC toggle, or degradation). */\n\tonKeepAwakeChanged?(): void;\n\tstatusExtras?(): { leases?: ControlLeaseStatus[]; phoneConnections?: number; relayCount?: number };\n\t/** Redeem a relay hello token; true when the socket was taken over. */\n\tadmitRelay?(relayId: string, relayToken: string, socket: Socket, bufferedRemainder: Buffer): boolean;\n\tshutdown?(): Promise<void>;\n}\n\nexport type VoltdServiceExtension = (services: VoltdRuntimeServices) => VoltdServiceExtensionInstance;\n\nexport async function runVoltDaemon(config: VoltdConfig, extensions: VoltdServiceExtension[] = []): Promise<number> {\n\tprocess.title = \"voltd\";\n\tconst agentDir = config.agentDir ?? getAgentDir();\n\tconst usingDefaultSocketPath = config.socketPath === undefined;\n\tlet selectedSocketPath = config.socketPath;\n\tconst resolvePaths = (): DaemonPaths => {\n\t\tconst basePaths = getDaemonPaths(agentDir);\n\t\treturn {\n\t\t\t...basePaths,\n\t\t\tsocketPath: selectedSocketPath ?? basePaths.socketPath,\n\t\t\tlogPath: config.logPath ?? basePaths.logPath,\n\t\t};\n\t};\n\tlet paths: DaemonPaths = resolvePaths();\n\tensureDaemonDirs(paths);\n\tconst logger = createDaemonLogger({\n\t\tlogPath: paths.logPath,\n\t\techoToStderr: config.foreground && process.stderr.isTTY,\n\t});\n\tconst log = logger.child(\"daemon\");\n\tconst clock: Clock = config.clock ?? { now: () => Date.now() };\n\tconst startedAtMs = clock.now();\n\tconst pidfileToken = randomUUID();\n\tlet daemonLock: DaemonLock | undefined;\n\tconst releaseDaemonLock = () => {\n\t\tdaemonLock?.release();\n\t\tdaemonLock = undefined;\n\t};\n\tconst finishBeforeServing = (code: number): number => {\n\t\treleaseDaemonLock();\n\t\treturn code;\n\t};\n\tconst verifyLockOwner = async (owner: DaemonLockOwner) => {\n\t\tconst pidfile = readPidfile(paths.pidfilePath);\n\t\tif (pidfile?.pid === owner.pid) {\n\t\t\tconst socketProbe = await probeControlSocket(pidfile.socketPath, {\n\t\t\t\tversion: VERSION,\n\t\t\t\ttimeoutMs: 500,\n\t\t\t\t...(pidfile.token === undefined ? {} : { authToken: pidfile.token }),\n\t\t\t});\n\t\t\tif (socketProbe.kind === \"healthy\" && socketProbe.status.pid === owner.pid) {\n\t\t\t\treturn \"match\" as const;\n\t\t\t}\n\t\t\tif (socketProbe.kind === \"live-rejected\" || socketProbe.kind === \"unresponsive\") {\n\t\t\t\treturn \"unknown\" as const;\n\t\t\t}\n\t\t}\n\t\treturn verifyVoltdProcessIdentity(owner, { toleranceMs: DAEMON_LOCK_START_TIME_TOLERANCE_MS });\n\t};\n\tconst lockResult = await acquireDaemonLock(paths.lockDirPath, { verifyOwner: verifyLockOwner });\n\tif (!lockResult.ok) {\n\t\tconst pidfile = readPidfile(paths.pidfilePath);\n\t\tif (pidfile) {\n\t\t\tconst socketProbe = await probeControlSocket(pidfile.socketPath, {\n\t\t\t\tversion: VERSION,\n\t\t\t\ttimeoutMs: 500,\n\t\t\t\t...(pidfile.token === undefined ? {} : { authToken: pidfile.token }),\n\t\t\t});\n\t\t\tif (socketProbe.kind === \"healthy\") {\n\t\t\t\tlog(\"info\", `another daemon is healthy (pid ${socketProbe.status.pid}); exiting`);\n\t\t\t\treturn VOLTD_EXIT_ALREADY_RUNNING;\n\t\t\t}\n\t\t\tif (socketProbe.kind === \"live-rejected\" && socketProbe.reason === \"protocol_mismatch\") {\n\t\t\t\tlog(\n\t\t\t\t\t\"error\",\n\t\t\t\t\t`another daemon is running with protocol ${socketProbe.protocolVersion ?? \"unknown\"}; not starting`,\n\t\t\t\t);\n\t\t\t\treturn VOLTD_EXIT_INCOMPATIBLE_RUNNING;\n\t\t\t}\n\t\t}\n\t\tconst owner = lockResult.owner ? ` by pid ${lockResult.owner.pid}` : \"\";\n\t\tlog(\"error\", `daemon startup lock is held${owner}; not starting a second daemon`);\n\t\treturn VOLTD_EXIT_BIND_FAILED;\n\t}\n\tdaemonLock = lockResult.lock;\n\tif (usingDefaultSocketPath && process.platform === \"win32\") {\n\t\tselectedSocketPath = createDaemonControlSocketPath(agentDir);\n\t\tpaths = resolvePaths();\n\t\tensureDaemonDirs(paths);\n\t}\n\n\tconst state = new VoltdStateStore({ agentDir, statePath: paths.statePath });\n\tlet migratedFromLegacyState = false;\n\tlet legacyDroppedAccess: { clients: number; revokedClients: number; pendingPairingTickets: number } | undefined;\n\ttry {\n\t\tconst loadResult = await state.load();\n\t\tmigratedFromLegacyState = loadResult.migratedFromLegacyState;\n\t\tlegacyDroppedAccess = loadResult.legacyDroppedAccess;\n\t\tif (\n\t\t\tlegacyDroppedAccess !== undefined &&\n\t\t\tlegacyDroppedAccess.clients + legacyDroppedAccess.revokedClients + legacyDroppedAccess.pendingPairingTickets >\n\t\t\t\t0\n\t\t) {\n\t\t\tlog(\n\t\t\t\t\"warn\",\n\t\t\t\t\"migrated pre-grant Iroh host state: preserved host identity and workspace metadata, \" +\n\t\t\t\t\t\"dropped legacy clients, revocations, and pending tickets; all clients must pair again\",\n\t\t\t\tlegacyDroppedAccess,\n\t\t\t);\n\t\t}\n\t} catch (error) {\n\t\tlog(\"error\", `failed to load state: ${error instanceof Error ? error.message : String(error)}`);\n\t\treturn finishBeforeServing(1);\n\t}\n\n\t// Global settings are the source of truth for daemon runtime policy. Project\n\t// settings are deliberately excluded: registering a workspace must never\n\t// widen or silently replace a paired client's workstation-level ceiling.\n\tconst settingsManager = SettingsManager.create(agentDir, agentDir, { projectTrusted: false });\n\tconst globalSettingsErrors = settingsManager.drainErrors().filter((error) => error.scope === \"global\");\n\tif (globalSettingsErrors.length > 0) {\n\t\tlog(\"error\", `failed to load global settings: ${globalSettingsErrors[0]?.error.message ?? \"unknown error\"}`);\n\t\treturn finishBeforeServing(1);\n\t}\n\tconst remoteSettings = settingsManager.getRemoteSettings() as Record<string, unknown>;\n\tconst configuredAllowTools = remoteSettings.allowTools;\n\tif (\n\t\tconfiguredAllowTools !== undefined &&\n\t\t(!Array.isArray(configuredAllowTools) || configuredAllowTools.some((tool) => typeof tool !== \"string\"))\n\t) {\n\t\tlog(\"error\", \"invalid remote.allowTools setting: expected an array of tool names\");\n\t\treturn finishBeforeServing(1);\n\t}\n\tconst allowTools =\n\t\tconfiguredAllowTools === undefined\n\t\t\t? null\n\t\t\t: Array.from(\n\t\t\t\t\tnew Set((configuredAllowTools as string[]).map((tool) => tool.trim()).filter((tool) => tool.length > 0)),\n\t\t\t\t);\n\tstate.updateSettings({ allowTools });\n\ttry {\n\t\tawait state.flush();\n\t} catch (error) {\n\t\tlog(\"error\", `failed to persist remote policy: ${error instanceof Error ? error.message : String(error)}`);\n\t\treturn finishBeforeServing(1);\n\t}\n\n\t// The daemon's theme instance: persisted name from voltd state, no hot-reload\n\t// watcher (that is the rendering TUI's job).\n\tinitTheme(state.state.settings.themeName, false);\n\tconst stateManager = new IrohRemoteHostStateManager({\n\t\tstore: {\n\t\t\tread: () => state.getHostState(),\n\t\t\twrite: async (hostState) => {\n\t\t\t\tstate.setHostState(hostState);\n\t\t\t\t// State-manager mutations are security-sensitive: callers must not\n\t\t\t\t// expose tickets or acknowledge pairing/revocation before durability.\n\t\t\t\tawait state.flush();\n\t\t\t},\n\t\t},\n\t});\n\tconst auditLogger = new IrohRemoteAuditLogger({ path: paths.auditPath });\n\tconst fallbackPushRelayClient = new IrohRemotePushRelayHttpClient({\n\t\tauthToken: process.env.VOLT_PUSH_RELAY_AUTH_TOKEN,\n\t\tbaseUrl: process.env.VOLT_PUSH_RELAY_URL,\n\t});\n\n\tlet shuttingDown = false;\n\tlet resolveExit: ((code: number) => void) | undefined;\n\tconst removeOwnedPidfile = () => {\n\t\tconst current = readPidfile(paths.pidfilePath);\n\t\tif (!current) {\n\t\t\treturn;\n\t\t}\n\t\tconst owned = current.token === pidfileToken || (current.token === undefined && current.pid === process.pid);\n\t\tif (owned) {\n\t\t\trmSync(paths.pidfilePath, { force: true });\n\t\t}\n\t};\n\tconst exitPromise = new Promise<number>((resolve) => {\n\t\tresolveExit = resolve;\n\t});\n\n\tconst extensionInstances: VoltdServiceExtensionInstance[] = [];\n\tlet controlServer: ControlServer | undefined;\n\n\tconst keepAwake = new KeepAwakeController({\n\t\t...config.keepAwake,\n\t\tlog: (level, message) => logger.log(level, \"keep-awake\", message),\n\t\tonStatusChanged: (status) => {\n\t\t\tconfig.keepAwake?.onStatusChanged?.(status);\n\t\t\tcontrolServer?.broadcast({ type: \"keep_awake_changed\", keepAwake: status });\n\t\t\tfor (const extension of extensionInstances) {\n\t\t\t\textension.onKeepAwakeChanged?.();\n\t\t\t}\n\t\t},\n\t});\n\n\t// Brave Search key storage for phone RPC: persisted in auth.json (never in\n\t// daemon state.json) so the web_search tool's fallback sees it.\n\tlet webSearchAuthStorage: AuthStorage | undefined;\n\tconst getWebSearchAuthStorage = (): AuthStorage => {\n\t\twebSearchAuthStorage ??= AuthStorage.create(join(agentDir, \"auth.json\"));\n\t\treturn webSearchAuthStorage;\n\t};\n\tconst webSearchKey: VoltdRuntimeServices[\"webSearchKey\"] = {\n\t\tset(apiKey: string | null): void {\n\t\t\tconst authStorage = getWebSearchAuthStorage();\n\t\t\tif (apiKey === null) {\n\t\t\t\tauthStorage.remove(BRAVE_SEARCH_AUTH_PROVIDER);\n\t\t\t} else {\n\t\t\t\tauthStorage.set(BRAVE_SEARCH_AUTH_PROVIDER, { type: \"api_key\", key: apiKey });\n\t\t\t}\n\t\t},\n\t\tget configured(): boolean {\n\t\t\tconst authStorage = getWebSearchAuthStorage();\n\t\t\t// Other processes may write auth.json; re-read before reporting.\n\t\t\tauthStorage.reload();\n\t\t\tconst cred = authStorage.get(BRAVE_SEARCH_AUTH_PROVIDER);\n\t\t\treturn cred?.type === \"api_key\" && cred.key.trim().length > 0;\n\t\t},\n\t};\n\n\tconst shutdown = async (reason: \"cli\" | \"signal\") => {\n\t\tif (shuttingDown) {\n\t\t\treturn;\n\t\t}\n\t\tshuttingDown = true;\n\t\tlog(\"info\", `shutting down (${reason})`);\n\t\t// Tell control clients up front: extension shutdown can drain streaming\n\t\t// runtimes for up to 60s and clients must not wait blind. New hellos are\n\t\t// already rejected via the isShuttingDown gate.\n\t\tcontrolServer?.broadcast({ type: \"daemon_shutdown\" });\n\t\tfor (const extension of extensionInstances) {\n\t\t\ttry {\n\t\t\t\tawait extension.shutdown?.();\n\t\t\t} catch (error) {\n\t\t\t\tlog(\"error\", `extension shutdown failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t}\n\t\tawait keepAwake.shutdown().catch(() => {});\n\t\tawait state.close().catch(() => {});\n\t\tawait auditLogger.log({ type: \"daemon_shutdown\", success: true, details: { reason } }).catch(() => {});\n\t\tawait controlServer?.close().catch(() => {});\n\t\tremoveOwnedPidfile();\n\t\treleaseDaemonLock();\n\t\tlog(\"info\", \"shutdown complete\");\n\t\tresolveExit?.(0);\n\t};\n\n\tconst requestShutdown = (reason: \"cli\" | \"signal\") => {\n\t\tvoid shutdown(reason);\n\t};\n\n\tconst toClientStatuses = (): ControlClientStatus[] =>\n\t\tstate.state.clients.map((client) => ({\n\t\t\tclientNodeId: client.nodeId,\n\t\t\t...(client.label === undefined ? {} : { label: client.label }),\n\t\t\tpairedAtMs: client.pairedAt ?? 0,\n\t\t\tlastSeenAtMs: client.lastSeenAt ?? 0,\n\t\t\tallowedTools: client.allowedTools\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((tool) => tool.trim())\n\t\t\t\t.filter((tool) => tool.length > 0),\n\t\t\trpcGrant: parseIrohRemoteRpcGrant(client.rpcGrant, \"client rpcGrant\"),\n\t\t}));\n\tconst toRevokedClientStatuses = (): ControlRevokedClientStatus[] =>\n\t\tstate.state.revokedClients.map((client) => ({\n\t\t\tclientNodeId: client.nodeId,\n\t\t\t...(client.label === undefined ? {} : { label: client.label }),\n\t\t\tpairedAtMs: client.pairedAt ?? 0,\n\t\t\tlastSeenAtMs: client.lastSeenAt ?? 0,\n\t\t\trevokedAtMs: client.revokedAt,\n\t\t\trpcGrant: parseIrohRemoteRpcGrant(client.rpcGrant, \"revoked client rpcGrant\"),\n\t\t\t...(client.rePairApprovedAt === undefined ? {} : { rePairApprovedAtMs: client.rePairApprovedAt }),\n\t\t}));\n\n\t// Worktree control fallback (no iroh extension running / request not handled\n\t// there): records via the shared state manager, no runtime awareness.\n\tlet fallbackWorktreeManager: WorktreeManager | undefined;\n\tconst getFallbackWorktreeManager = (): WorktreeManager => {\n\t\tfallbackWorktreeManager ??= new WorktreeManager({\n\t\t\tagentDir,\n\t\t\tstateManager,\n\t\t\tauditLogger,\n\t\t\tflushState: () => state.flush(),\n\t\t});\n\t\treturn fallbackWorktreeManager;\n\t};\n\n\tconst handleRequest = async (connection: ControlConnection, request: ControlRequest): Promise<void> => {\n\t\tfor (const extension of extensionInstances) {\n\t\t\tif (await extension.handleRequest?.(connection, request)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (isWorktreeControlRequest(request)) {\n\t\t\tawait handleWorktreeControlRequest(connection, request, {\n\t\t\t\tmanager: getFallbackWorktreeManager(),\n\t\t\t\tstateManager,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tswitch (request.type) {\n\t\t\tcase \"status\": {\n\t\t\t\tconst workspaces: ControlWorkspaceStatus[] = state.state.workspaces.map((workspace) => ({\n\t\t\t\t\tname: workspace.name,\n\t\t\t\t\tpath: workspace.path,\n\t\t\t\t\t...(workspace.allowedTools === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tallowedTools: workspace.allowedTools\n\t\t\t\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t\t\t\t.map((tool) => tool.trim())\n\t\t\t\t\t\t\t\t\t.filter((tool) => tool.length > 0),\n\t\t\t\t\t\t\t}),\n\t\t\t\t}));\n\t\t\t\tlet leases: ControlLeaseStatus[] = [];\n\t\t\t\tlet phoneConnections = 0;\n\t\t\t\tfor (const extension of extensionInstances) {\n\t\t\t\t\tconst extras = extension.statusExtras?.();\n\t\t\t\t\tif (extras?.leases) {\n\t\t\t\t\t\tleases = leases.concat(extras.leases);\n\t\t\t\t\t}\n\t\t\t\t\tphoneConnections += extras?.phoneConnections ?? 0;\n\t\t\t\t}\n\t\t\t\tconnection.send({\n\t\t\t\t\ttype: \"status_result\",\n\t\t\t\t\tid: request.id,\n\t\t\t\t\tversion: VERSION,\n\t\t\t\t\tprotocolVersion: PROTOCOL_VERSION,\n\t\t\t\t\tpid: process.pid,\n\t\t\t\t\tstartedAtMs,\n\t\t\t\t\tcapabilities: [CONTROL_PAIR_CANCEL_CAPABILITY, CONTROL_RPC_GRANTS_CAPABILITY],\n\t\t\t\t\tleases,\n\t\t\t\t\tphoneConnections,\n\t\t\t\t\tworkspaces,\n\t\t\t\t\tclients: toClientStatuses(),\n\t\t\t\t\trevokedClients: toRevokedClientStatuses(),\n\t\t\t\t\tremotePolicy: {\n\t\t\t\t\t\tallowTools: state.state.settings.allowTools,\n\t\t\t\t\t\tdetachedRuntimeTtlMs: state.state.settings.detachedRuntimeTtlMs,\n\t\t\t\t\t},\n\t\t\t\t\tkeepAwake: keepAwake.status,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"shutdown\": {\n\t\t\t\tconnection.send({ type: \"ok\", id: request.id });\n\t\t\t\trequestShutdown(\"cli\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"clients_list\": {\n\t\t\t\tconnection.send({ type: \"clients_result\", id: request.id, clients: toClientStatuses() });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"workspace_register\": {\n\t\t\t\tlet workspacePath: string;\n\t\t\t\ttry {\n\t\t\t\t\tconst stats = await stat(request.path);\n\t\t\t\t\tif (!stats.isDirectory()) {\n\t\t\t\t\t\tthrow new Error(`Workspace path is not a directory: ${request.path}`);\n\t\t\t\t\t}\n\t\t\t\t\tworkspacePath = await realpath(request.path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconnection.send({\n\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\tid: request.id,\n\t\t\t\t\t\tcode: \"invalid_workspace\",\n\t\t\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait stateManager.upsertWorkspace({ name: request.name, path: workspacePath });\n\t\t\t\tawait auditLogger\n\t\t\t\t\t.log({\n\t\t\t\t\t\ttype: \"workspace_registered\",\n\t\t\t\t\t\tworkspace: request.name,\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tdetails: { path: workspacePath, source: \"control\" },\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {});\n\t\t\t\tconnection.send({ type: \"ok\", id: request.id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"workspace_unregister\": {\n\t\t\t\t// State-only fallback (no Iroh extension running).\n\t\t\t\tlet removedWorkspace: Awaited<ReturnType<IrohRemoteHostStateManager[\"unregisterWorkspace\"]>>;\n\t\t\t\ttry {\n\t\t\t\t\tremovedWorkspace = await stateManager.unregisterWorkspace(request.name);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (!isIrohRemoteWorkspaceHasWorktreesError(error)) {\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t\tawait auditLogger\n\t\t\t\t\t\t.log({\n\t\t\t\t\t\t\ttype: \"workspace_unregistered\",\n\t\t\t\t\t\t\tworkspace: request.name,\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: IROH_REMOTE_WORKSPACE_HAS_WORKTREES_ERROR,\n\t\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\t\tsource: \"state_only_fallback\",\n\t\t\t\t\t\t\t\tworktreeCount: error.worktreeIds.length,\n\t\t\t\t\t\t\t\tworktreeIds: error.worktreeIds,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch(() => {});\n\t\t\t\t\tconnection.send({\n\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\tid: request.id,\n\t\t\t\t\t\tcode: IROH_REMOTE_WORKSPACE_HAS_WORKTREES_ERROR,\n\t\t\t\t\t\tmessage: error.message,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!removedWorkspace) {\n\t\t\t\t\tconnection.send({\n\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\tid: request.id,\n\t\t\t\t\t\tcode: \"not_found\",\n\t\t\t\t\t\tmessage: `No registered workspace named ${request.name}`,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait stateManager.removeLiveActivitiesForWorkspace(request.name);\n\t\t\t\tawait auditLogger\n\t\t\t\t\t.log({\n\t\t\t\t\t\ttype: \"workspace_unregistered\",\n\t\t\t\t\t\tworkspace: request.name,\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tdetails: { source: \"state_only_fallback\" },\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {});\n\t\t\t\tconnection.send({ type: \"ok\", id: request.id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"client_access_update\": {\n\t\t\t\tconst access =\n\t\t\t\t\trequest.access !== undefined\n\t\t\t\t\t\t? createIrohRemotePresetAccess(request.access)\n\t\t\t\t\t\t: createIrohRemoteExplicitAccess(\n\t\t\t\t\t\t\t\trequest.allowedTools ?? [],\n\t\t\t\t\t\t\t\tparseIrohRemoteRpcCapabilities(request.rpcCapabilities),\n\t\t\t\t\t\t\t);\n\t\t\t\tconst updated = await stateManager.updateClientAccess(\n\t\t\t\t\trequest.clientNodeId,\n\t\t\t\t\trequest.expectedRevision,\n\t\t\t\t\taccess,\n\t\t\t\t);\n\t\t\t\tif (!updated.ok) {\n\t\t\t\t\tconnection.send({\n\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\tid: request.id,\n\t\t\t\t\t\tcode: updated.reason,\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\tupdated.reason === \"revision_conflict\"\n\t\t\t\t\t\t\t\t? `RPC grant revision conflict (current ${updated.currentRevision ?? \"unknown\"})`\n\t\t\t\t\t\t\t\t: updated.reason === \"revision_exhausted\"\n\t\t\t\t\t\t\t\t\t? \"RPC grant revision is exhausted; revoke and re-pair the client\"\n\t\t\t\t\t\t\t\t\t: \"client not found\",\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait state.flush();\n\t\t\t\tawait auditLogger\n\t\t\t\t\t.log({\n\t\t\t\t\t\ttype: \"client_access_updated\",\n\t\t\t\t\t\tclientNodeId: request.clientNodeId,\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\texpectedRevision: request.expectedRevision,\n\t\t\t\t\t\t\trevision: updated.client.rpcGrant.revision,\n\t\t\t\t\t\t\tallowedTools: updated.client.allowedTools,\n\t\t\t\t\t\t\trpcCapabilities: updated.client.rpcGrant.capabilities,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {});\n\t\t\t\tconnection.send({\n\t\t\t\t\ttype: \"client_access_updated\",\n\t\t\t\t\tid: request.id,\n\t\t\t\t\tclient: {\n\t\t\t\t\t\tclientNodeId: updated.client.nodeId,\n\t\t\t\t\t\tlabel: updated.client.label,\n\t\t\t\t\t\tpairedAtMs: updated.client.pairedAt,\n\t\t\t\t\t\tlastSeenAtMs: updated.client.lastSeenAt,\n\t\t\t\t\t\tallowedTools: updated.client.allowedTools.length === 0 ? [] : updated.client.allowedTools.split(\",\"),\n\t\t\t\t\t\trpcGrant: updated.client.rpcGrant,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"client_revoke\": {\n\t\t\t\t// State-only fallback (no Iroh extension running).\n\t\t\t\tconst result = await stateManager.revokeClient(request.clientNodeId);\n\t\t\t\tawait auditLogger\n\t\t\t\t\t.log({\n\t\t\t\t\t\ttype: \"client_revoked\",\n\t\t\t\t\t\tclientNodeId: request.clientNodeId,\n\t\t\t\t\t\tsuccess: result.revoked,\n\t\t\t\t\t\terror: result.revoked ? undefined : \"client not found\",\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {});\n\t\t\t\tif (!result.revoked) {\n\t\t\t\t\tconnection.send({ type: \"error\", id: request.id, code: \"not_found\", message: \"client not found\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ((result.client?.pushTargets?.length ?? 0) > 0) {\n\t\t\t\t\tconst summary = await revokeIrohRemoteClientPushTargets(result.client, fallbackPushRelayClient);\n\t\t\t\t\tconst complete = summary.failed === 0 && summary.skipped === 0;\n\t\t\t\t\tif (!complete) {\n\t\t\t\t\t\tlog(\"warn\", \"remote push-target cleanup incomplete after fallback client revoke\", { ...summary });\n\t\t\t\t\t}\n\t\t\t\t\tawait auditLogger\n\t\t\t\t\t\t.log({\n\t\t\t\t\t\t\ttype: \"push_targets_revoked\",\n\t\t\t\t\t\t\tclientNodeId: request.clientNodeId,\n\t\t\t\t\t\t\tsuccess: complete,\n\t\t\t\t\t\t\terror: complete\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: \"remote push-target cleanup incomplete; relay TTL remains the lifetime bound\",\n\t\t\t\t\t\t\tdetails: { ...summary, remainingLifetimeBound: \"relay_target_ttl\", source: \"state_only_fallback\" },\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch(() => {});\n\t\t\t\t}\n\t\t\t\tconnection.send({ type: \"ok\", id: request.id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"theme_set\": {\n\t\t\t\t// Validate before applying: runtime setTheme falls back to dark on\n\t\t\t\t// failure, which must not clobber the active theme on a bad request.\n\t\t\t\tif (!getThemeByName(request.theme)) {\n\t\t\t\t\tconnection.send({\n\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\tid: request.id,\n\t\t\t\t\t\tcode: \"invalid_theme\",\n\t\t\t\t\t\tmessage: `unknown theme: ${request.theme}`,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = setTheme(request.theme, false);\n\t\t\t\tif (!result.success) {\n\t\t\t\t\tconnection.send({\n\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\tid: request.id,\n\t\t\t\t\t\tcode: \"invalid_theme\",\n\t\t\t\t\t\tmessage: result.error ?? `unknown theme: ${request.theme}`,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tstate.updateSettings({ themeName: request.theme });\n\t\t\t\tconnection.send({ type: \"ok\", id: request.id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"keep_awake_set\": {\n\t\t\t\tconst status = keepAwake.setEnabled(request.enabled);\n\t\t\t\tstate.updateSettings({ keepAwakeEnabled: request.enabled });\n\t\t\t\tconnection.send({ type: \"keep_awake_result\", id: request.id, keepAwake: status });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"client_approve_repair\": {\n\t\t\t\tconst result = await stateManager.approveClientRePair(request.clientNodeId);\n\t\t\t\tawait auditLogger\n\t\t\t\t\t.log({\n\t\t\t\t\t\ttype: \"client_repair_approved\",\n\t\t\t\t\t\tclientNodeId: request.clientNodeId,\n\t\t\t\t\t\tsuccess: result.approved,\n\t\t\t\t\t\terror: result.approved ? undefined : \"revoked client not found\",\n\t\t\t\t\t})\n\t\t\t\t\t.catch(() => {});\n\t\t\t\tif (!result.approved) {\n\t\t\t\t\tconnection.send({\n\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\tid: request.id,\n\t\t\t\t\t\tcode: \"not_found\",\n\t\t\t\t\t\tmessage: \"revoked client not found\",\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait state.flush();\n\t\t\t\tconnection.send({ type: \"ok\", id: request.id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tconnection.send({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tid: request.id,\n\t\t\t\t\tcode: \"unsupported\",\n\t\t\t\t\tmessage: `unsupported control request: ${request.type}`,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t}\n\t};\n\n\tconst bindControlServer = () =>\n\t\tstartControlServer({\n\t\t\tsocketPath: paths.socketPath,\n\t\t\tversion: VERSION,\n\t\t\tauthToken: pidfileToken,\n\t\t\thandlers: {\n\t\t\t\tonRequest: handleRequest,\n\t\t\t\tisShuttingDown: () => shuttingDown,\n\t\t\t\trelayAdmission: {\n\t\t\t\t\tadmitRelay(hello, socket, bufferedRemainder) {\n\t\t\t\t\t\tfor (const extension of extensionInstances) {\n\t\t\t\t\t\t\tif (extension.admitRelay?.(hello.relayId, hello.relayToken, socket, bufferedRemainder)) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tonConnectionClosed(connection) {\n\t\t\t\t\tfor (const extension of extensionInstances) {\n\t\t\t\t\t\textension.onConnectionClosed?.(connection);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tlog(level, message) {\n\t\t\t\t\tlogger.log(level === \"info\" ? \"info\" : level, \"control\", message);\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t// All daemon instances sharing an agent directory are serialized before bind;\n\t// the socket bind remains a final guard against external listeners.\n\ttry {\n\t\tcontrolServer = await bindControlServer();\n\t} catch (error) {\n\t\tif (isErrnoException(error) && error.code === \"EADDRINUSE\") {\n\t\t\tconst deadline = Date.now() + DAEMON_BIND_WAIT_TIMEOUT_MS;\n\t\t\tconst pidfile = readPidfile(paths.pidfilePath);\n\t\t\tconst probeOptions = {\n\t\t\t\tversion: VERSION,\n\t\t\t\t...(pidfile?.socketPath === paths.socketPath && pidfile.token !== undefined\n\t\t\t\t\t? { authToken: pidfile.token }\n\t\t\t\t\t: {}),\n\t\t\t};\n\t\t\tlet socketProbe = await probeControlSocket(paths.socketPath, probeOptions);\n\t\t\tlet loggedShutdownWait = false;\n\t\t\twhile (\n\t\t\t\tsocketProbe.kind === \"live-rejected\" &&\n\t\t\t\tsocketProbe.reason === \"shutting_down\" &&\n\t\t\t\tDate.now() < deadline\n\t\t\t) {\n\t\t\t\tif (!loggedShutdownWait) {\n\t\t\t\t\tloggedShutdownWait = true;\n\t\t\t\t\tlog(\"info\", \"another daemon is shutting down; waiting for socket release\");\n\t\t\t\t}\n\t\t\t\tawait sleep(DAEMON_BIND_WAIT_POLL_MS);\n\t\t\t\tsocketProbe = await probeControlSocket(paths.socketPath, { ...probeOptions, timeoutMs: 500 });\n\t\t\t}\n\t\t\tif (socketProbe.kind === \"healthy\") {\n\t\t\t\tlog(\"info\", `another daemon is healthy (pid ${socketProbe.status.pid}); exiting`);\n\t\t\t\treturn finishBeforeServing(VOLTD_EXIT_ALREADY_RUNNING);\n\t\t\t}\n\t\t\tif (socketProbe.kind === \"live-rejected\" && socketProbe.reason === \"protocol_mismatch\") {\n\t\t\t\tlog(\n\t\t\t\t\t\"error\",\n\t\t\t\t\t`another daemon is running with protocol ${socketProbe.protocolVersion ?? \"unknown\"}; not removing its socket`,\n\t\t\t\t);\n\t\t\t\treturn finishBeforeServing(VOLTD_EXIT_INCOMPATIBLE_RUNNING);\n\t\t\t}\n\t\t\tif (pidfile && (await verifyPidfileProcess(pidfile)) === \"match\") {\n\t\t\t\tlog(\"error\", `pidfile still verifies live daemon pid ${pidfile.pid}; not removing socket`);\n\t\t\t\treturn finishBeforeServing(VOLTD_EXIT_BIND_FAILED);\n\t\t\t}\n\t\t\tconst canRegenerateWindowsPipe =\n\t\t\t\tprocess.platform === \"win32\" && usingDefaultSocketPath && isWindowsNamedPipePath(paths.socketPath);\n\t\t\tconst canUnlinkSocketPath = !isWindowsNamedPipePath(paths.socketPath);\n\t\t\tconst retryBind = async (message: string): Promise<boolean> => {\n\t\t\t\tlog(\"warn\", message);\n\t\t\t\tif (canRegenerateWindowsPipe) {\n\t\t\t\t\tselectedSocketPath = createDaemonControlSocketPath(agentDir);\n\t\t\t\t\tpaths = resolvePaths();\n\t\t\t\t\tensureDaemonDirs(paths);\n\t\t\t\t} else if (canUnlinkSocketPath) {\n\t\t\t\t\trmSync(paths.socketPath, { force: true });\n\t\t\t\t} else {\n\t\t\t\t\tlog(\"error\", \"control pipe is occupied and cannot be unlinked; not retrying bind\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tcontrolServer = await bindControlServer();\n\t\t\t\t\treturn true;\n\t\t\t\t} catch (retryError) {\n\t\t\t\t\tlog(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t`bind retry failed: ${retryError instanceof Error ? retryError.message : String(retryError)}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (socketProbe.kind === \"live-rejected\" || socketProbe.kind === \"unresponsive\") {\n\t\t\t\tif (\n\t\t\t\t\t!canRegenerateWindowsPipe ||\n\t\t\t\t\t(socketProbe.kind === \"live-rejected\" && socketProbe.reason === \"shutting_down\")\n\t\t\t\t) {\n\t\t\t\t\tlog(\"error\", \"control socket is owned by a live daemon that is not healthy; not removing it\");\n\t\t\t\t\treturn finishBeforeServing(VOLTD_EXIT_BIND_FAILED);\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\t!(await retryBind(\n\t\t\t\t\t\t\"control pipe is occupied by a non-Volt listener; choosing a fresh pipe name and retrying bind once\",\n\t\t\t\t\t))\n\t\t\t\t) {\n\t\t\t\t\treturn finishBeforeServing(VOLTD_EXIT_BIND_FAILED);\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\t!(await retryBind(\n\t\t\t\t\tcanRegenerateWindowsPipe\n\t\t\t\t\t\t? \"stale or pre-created control pipe detected; choosing a fresh pipe name and retrying bind once\"\n\t\t\t\t\t\t: \"stale socket detected; unlinking and retrying bind once\",\n\t\t\t\t))\n\t\t\t) {\n\t\t\t\treturn finishBeforeServing(VOLTD_EXIT_BIND_FAILED);\n\t\t\t}\n\t\t} else {\n\t\t\tlog(\"error\", `bind failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\treturn finishBeforeServing(VOLTD_EXIT_BIND_FAILED);\n\t\t}\n\t}\n\tif (!controlServer) {\n\t\tlog(\"error\", \"bind failed: control server was not created\");\n\t\treturn finishBeforeServing(VOLTD_EXIT_BIND_FAILED);\n\t}\n\n\t// Pidfile is discovery metadata; liveness truth is the authenticated socket probe.\n\twriteFileSync(\n\t\tpaths.pidfilePath,\n\t\t`${JSON.stringify({ pid: process.pid, version: VERSION, startedAtMs, socketPath: paths.socketPath, token: pidfileToken } satisfies PidfileContents)}\\n`,\n\t\t{ mode: 0o600 },\n\t);\n\n\t// Broadcast every successful theme change (control theme_set, or an extension\n\t// calling ctx.ui.setTheme inside a daemon-owned runtime) to all control\n\t// clients as a resolved-token snapshot, and let service extensions push it\n\t// onward (e.g. host_theme_tokens frames to capable phones, §9.5).\n\tonThemeChange(() => {\n\t\tcontrolServer?.broadcast({\n\t\t\ttype: \"theme_snapshot\",\n\t\t\tthemeName: getCurrentThemeName() ?? \"dark\",\n\t\t\ttokens: getResolvedThemeColors(),\n\t\t});\n\t\tfor (const extension of extensionInstances) {\n\t\t\textension.onThemeChanged?.();\n\t\t}\n\t});\n\n\tconst services: VoltdRuntimeServices = {\n\t\tagentDir,\n\t\tpaths,\n\t\tlogger,\n\t\tstate,\n\t\tstateManager,\n\t\tauditLogger,\n\t\tcontrolServer,\n\t\tkeepAwake,\n\t\twebSearchKey,\n\t\trequestShutdown,\n\t};\n\tfor (const extension of extensions) {\n\t\textensionInstances.push(extension(services));\n\t}\n\n\t// Re-apply the persisted keep-awake assertion now that extensions exist, so\n\t// their onKeepAwakeChanged hooks observe the startup transition.\n\tif (state.state.settings.keepAwakeEnabled === true) {\n\t\tkeepAwake.setEnabled(true);\n\t}\n\n\tconst onSignal = () => requestShutdown(\"signal\");\n\tprocess.on(\"SIGTERM\", onSignal);\n\tprocess.on(\"SIGINT\", onSignal);\n\n\tif (\n\t\tlegacyDroppedAccess !== undefined &&\n\t\tlegacyDroppedAccess.clients + legacyDroppedAccess.revokedClients + legacyDroppedAccess.pendingPairingTickets > 0\n\t) {\n\t\tawait auditLogger\n\t\t\t.log({\n\t\t\t\ttype: \"legacy_remote_access_dropped\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdetails: { ...legacyDroppedAccess, requiresRePair: true },\n\t\t\t})\n\t\t\t.catch(() => {});\n\t}\n\tawait auditLogger\n\t\t.log({\n\t\t\ttype: \"daemon_started\",\n\t\t\tsuccess: true,\n\t\t\tdetails: { version: VERSION, migratedFromLegacyState, legacyDroppedAccess },\n\t\t})\n\t\t.catch(() => {});\n\tlog(\"info\", `voltd ${VERSION} listening`, { socketPath: paths.socketPath, pid: process.pid });\n\n\tconst code = await exitPromise;\n\tprocess.off(\"SIGTERM\", onSignal);\n\tprocess.off(\"SIGINT\", onSignal);\n\treturn code;\n}\n\nfunction isErrnoException(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** True for Windows named-pipe socket paths (\\.\pipe\... or \\?\pipe\...). */
|
|
2
|
+
export declare function isWindowsNamedPipePath(socketPath: string): boolean;
|
|
3
|
+
export interface DaemonPaths {
|
|
4
|
+
daemonDir: string;
|
|
5
|
+
socketPath: string;
|
|
6
|
+
pidfilePath: string;
|
|
7
|
+
lockDirPath: string;
|
|
8
|
+
logPath: string;
|
|
9
|
+
statePath: string;
|
|
10
|
+
auditPath: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function getDaemonDir(agentDir?: string): string;
|
|
13
|
+
export declare function getDaemonControlSecretPath(agentDir?: string): string;
|
|
14
|
+
export declare function rotateWindowsDaemonSocketSecret(agentDir?: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Actual daemon listen endpoint for a new instance. Windows named pipes cannot
|
|
17
|
+
* be unlinked, so default daemons use a fresh pipe name and publish it through
|
|
18
|
+
* the pidfile. POSIX keeps the stable socket path because stale files can be
|
|
19
|
+
* removed from a private directory.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createDaemonControlSocketPath(agentDir?: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Default socket path lives in the daemon dir; when the agent dir is nested
|
|
24
|
+
* deep enough to overflow the platform socket-path limit, fall back to a
|
|
25
|
+
* runtime dir. The actual path is recorded in the pidfile, which clients read
|
|
26
|
+
* when the default probe fails.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getDaemonSocketPath(agentDir?: string): string;
|
|
29
|
+
export declare function getDaemonPaths(agentDir?: string): DaemonPaths;
|
|
30
|
+
/** Create the daemon dir (0700) and, for fallback sockets, the socket's parent dir. */
|
|
31
|
+
export declare function ensureDaemonDirs(paths: DaemonPaths): void;
|
|
32
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/daemon/paths.ts"],"names":[],"mappings":"AAuHA,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAElE;AAED,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAErE;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAEnF;AAED,wBAAgB,+BAA+B,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAOxF;AAWD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAMtF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAS5E;AAED,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,WAAW,CAW5E;AAED,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAWzD","sourcesContent":["import { createHash, randomBytes } from \"node:crypto\";\nimport { chmodSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { getAgentDir } from \"../config.ts\";\n\n/** Unix domain socket paths are capped around 104 (macOS) / 108 (Linux) bytes. */\nconst MAX_SOCKET_PATH_BYTES = 100;\nconst WINDOWS_CONTROL_SECRET_FILE = \"control-secret.json\";\nconst WINDOWS_CONTROL_SECRET_BYTES = 32;\nconst WINDOWS_PIPE_DIGEST_HEX_CHARS = 32;\nconst WINDOWS_PIPE_RANDOM_BYTES = 16;\n\ninterface WindowsControlSecret {\n\tpipeSecret: string;\n}\n\n/**\n * Node's net module has no filesystem unix sockets on Windows: a string path\n * passed to server.listen()/createConnection() is a named pipe, which must live\n * in the flat, machine-wide \\\\.\\pipe\\ namespace. A filesystem path such as\n * ...\\daemon\\voltd.sock makes CreateNamedPipe fail with EACCES. Derive the pipe\n * name from a per-agent secret so another local user cannot pre-create the\n * daemon's predictable endpoint before startup.\n */\nfunction getWindowsNamedPipePath(agentDir: string): string {\n\tconst secret = getOrCreateWindowsControlSecret(agentDir);\n\tconst digest = createHash(\"sha256\")\n\t\t.update(agentDir.toLowerCase())\n\t\t.update(\"\\0\")\n\t\t.update(secret.pipeSecret)\n\t\t.digest(\"hex\")\n\t\t.slice(0, WINDOWS_PIPE_DIGEST_HEX_CHARS);\n\treturn `\\\\\\\\.\\\\pipe\\\\voltd-${digest}`;\n}\n\nfunction createWindowsControlSecret(): WindowsControlSecret {\n\treturn { pipeSecret: randomBytes(WINDOWS_CONTROL_SECRET_BYTES).toString(\"hex\") };\n}\n\nfunction serializeWindowsControlSecret(secret: WindowsControlSecret): string {\n\treturn `${JSON.stringify({ version: 1, pipeSecret: secret.pipeSecret })}\\n`;\n}\n\nfunction isSecretHex(value: unknown): value is string {\n\treturn typeof value === \"string\" && /^[0-9a-f]{64}$/i.test(value);\n}\n\nfunction readWindowsControlSecret(secretPath: string): WindowsControlSecret | undefined {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(secretPath, \"utf8\")) as unknown;\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst pipeSecret = (parsed as { pipeSecret?: unknown }).pipeSecret;\n\t\treturn isSecretHex(pipeSecret) ? { pipeSecret: pipeSecret.toLowerCase() } : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction chmodControlSecret(secretPath: string): void {\n\ttry {\n\t\tchmodSync(secretPath, 0o600);\n\t} catch {\n\t\t// Best effort: Windows ignores POSIX-style mode bits, but Unix-like test\n\t\t// environments and future runtimes still benefit from owner-only mode.\n\t}\n}\n\nfunction createWindowsControlSecretFile(secretPath: string): WindowsControlSecret {\n\tconst secret = createWindowsControlSecret();\n\ttry {\n\t\twriteFileSync(secretPath, serializeWindowsControlSecret(secret), { mode: 0o600, flag: \"wx\" });\n\t\tchmodControlSecret(secretPath);\n\t\treturn secret;\n\t} catch (error) {\n\t\tif (isErrnoException(error) && error.code === \"EEXIST\") {\n\t\t\tconst racedSecret = readWindowsControlSecret(secretPath);\n\t\t\tif (racedSecret) {\n\t\t\t\treturn racedSecret;\n\t\t\t}\n\t\t\treturn replaceWindowsControlSecretFile(secretPath);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction replaceWindowsControlSecretFile(secretPath: string): WindowsControlSecret {\n\tconst secret = createWindowsControlSecret();\n\tconst tempPath = join(\n\t\tdirname(secretPath),\n\t\t`.${WINDOWS_CONTROL_SECRET_FILE}.${process.pid}.${Date.now()}.${randomBytes(4).toString(\"hex\")}.tmp`,\n\t);\n\ttry {\n\t\twriteFileSync(tempPath, serializeWindowsControlSecret(secret), { mode: 0o600, flag: \"wx\" });\n\t\tchmodControlSecret(tempPath);\n\t\trenameSync(tempPath, secretPath);\n\t\tchmodControlSecret(secretPath);\n\t\treturn secret;\n\t} catch (error) {\n\t\trmSync(tempPath, { force: true });\n\t\tthrow error;\n\t}\n}\n\nfunction getOrCreateWindowsControlSecret(agentDir: string): WindowsControlSecret {\n\tconst secretPath = getDaemonControlSecretPath(agentDir);\n\tconst existingSecret = readWindowsControlSecret(secretPath);\n\tif (existingSecret) {\n\t\treturn existingSecret;\n\t}\n\tmkdirSync(getDaemonDir(agentDir), { recursive: true, mode: 0o700 });\n\treturn createWindowsControlSecretFile(secretPath);\n}\n\nfunction isErrnoException(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\n/** True for Windows named-pipe socket paths (\\\\.\\pipe\\... or \\\\?\\pipe\\...). */\nexport function isWindowsNamedPipePath(socketPath: string): boolean {\n\treturn /^\\\\\\\\[.?]\\\\pipe\\\\/.test(socketPath);\n}\n\nexport interface DaemonPaths {\n\tdaemonDir: string;\n\tsocketPath: string;\n\tpidfilePath: string;\n\tlockDirPath: string;\n\tlogPath: string;\n\tstatePath: string;\n\tauditPath: string;\n}\n\nexport function getDaemonDir(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \"daemon\");\n}\n\nexport function getDaemonControlSecretPath(agentDir: string = getAgentDir()): string {\n\treturn join(getDaemonDir(agentDir), WINDOWS_CONTROL_SECRET_FILE);\n}\n\nexport function rotateWindowsDaemonSocketSecret(agentDir: string = getAgentDir()): string {\n\tif (process.platform !== \"win32\") {\n\t\treturn getDaemonSocketPath(agentDir);\n\t}\n\tmkdirSync(getDaemonDir(agentDir), { recursive: true, mode: 0o700 });\n\treplaceWindowsControlSecretFile(getDaemonControlSecretPath(agentDir));\n\treturn getWindowsNamedPipePath(agentDir);\n}\n\nfunction getFallbackSocketPath(): string {\n\tconst uid = typeof process.getuid === \"function\" ? process.getuid() : 0;\n\tconst runtimeDir = process.env.XDG_RUNTIME_DIR;\n\tif (runtimeDir) {\n\t\treturn join(runtimeDir, `voltd-${uid}.sock`);\n\t}\n\treturn join(`/tmp/voltd-${uid}`, \"voltd.sock\");\n}\n\n/**\n * Actual daemon listen endpoint for a new instance. Windows named pipes cannot\n * be unlinked, so default daemons use a fresh pipe name and publish it through\n * the pidfile. POSIX keeps the stable socket path because stale files can be\n * removed from a private directory.\n */\nexport function createDaemonControlSocketPath(agentDir: string = getAgentDir()): string {\n\tif (process.platform !== \"win32\") {\n\t\treturn getDaemonSocketPath(agentDir);\n\t}\n\tconst scope = createHash(\"sha256\").update(agentDir.toLowerCase()).digest(\"hex\").slice(0, 16);\n\treturn `\\\\\\\\.\\\\pipe\\\\voltd-${scope}-${randomBytes(WINDOWS_PIPE_RANDOM_BYTES).toString(\"hex\")}`;\n}\n\n/**\n * Default socket path lives in the daemon dir; when the agent dir is nested\n * deep enough to overflow the platform socket-path limit, fall back to a\n * runtime dir. The actual path is recorded in the pidfile, which clients read\n * when the default probe fails.\n */\nexport function getDaemonSocketPath(agentDir: string = getAgentDir()): string {\n\tif (process.platform === \"win32\") {\n\t\treturn getWindowsNamedPipePath(agentDir);\n\t}\n\tconst defaultPath = join(getDaemonDir(agentDir), \"voltd.sock\");\n\tif (Buffer.byteLength(defaultPath, \"utf8\") <= MAX_SOCKET_PATH_BYTES) {\n\t\treturn defaultPath;\n\t}\n\treturn getFallbackSocketPath();\n}\n\nexport function getDaemonPaths(agentDir: string = getAgentDir()): DaemonPaths {\n\tconst daemonDir = getDaemonDir(agentDir);\n\treturn {\n\t\tdaemonDir,\n\t\tsocketPath: getDaemonSocketPath(agentDir),\n\t\tpidfilePath: join(daemonDir, \"voltd.pid\"),\n\t\tlockDirPath: join(daemonDir, \"voltd.lock\"),\n\t\tlogPath: join(daemonDir, \"voltd.log\"),\n\t\tstatePath: join(daemonDir, \"state.json\"),\n\t\tauditPath: join(daemonDir, \"audit.jsonl\"),\n\t};\n}\n\n/** Create the daemon dir (0700) and, for fallback sockets, the socket's parent dir. */\nexport function ensureDaemonDirs(paths: DaemonPaths): void {\n\tmkdirSync(paths.daemonDir, { recursive: true, mode: 0o700 });\n\t// Named pipes have no parent directory on disk to create or harden.\n\tif (isWindowsNamedPipePath(paths.socketPath)) {\n\t\treturn;\n\t}\n\tif (!paths.socketPath.startsWith(paths.daemonDir)) {\n\t\tconst socketDir = dirname(paths.socketPath);\n\t\tmkdirSync(socketDir, { recursive: true, mode: 0o700 });\n\t\tassertPrivateSocketDir(socketDir);\n\t}\n}\n\n/**\n * The fallback socket dir lives under a shared parent (/tmp or\n * XDG_RUNTIME_DIR) at a predictable path, and mkdir with recursive silently\n * accepts a pre-existing directory without touching its mode. Verify the\n * directory is ours before placing the socket in it, and tighten loose\n * permissions on one we own.\n */\nfunction assertPrivateSocketDir(dir: string): void {\n\tif (process.platform === \"win32\") {\n\t\treturn;\n\t}\n\tconst stats = lstatSync(dir);\n\tif (!stats.isDirectory()) {\n\t\tthrow new Error(`voltd socket directory ${dir} is not a directory`);\n\t}\n\tconst uid = typeof process.getuid === \"function\" ? process.getuid() : stats.uid;\n\tif (stats.uid !== uid) {\n\t\tthrow new Error(`refusing to use voltd socket directory ${dir}: owned by uid ${stats.uid}, not ${uid}`);\n\t}\n\tif ((stats.mode & 0o077) !== 0) {\n\t\tchmodSync(dir, 0o700);\n\t}\n}\n"]}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
import { chmodSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { getAgentDir } from "../config.js";
|
|
5
|
+
/** Unix domain socket paths are capped around 104 (macOS) / 108 (Linux) bytes. */
|
|
6
|
+
const MAX_SOCKET_PATH_BYTES = 100;
|
|
7
|
+
const WINDOWS_CONTROL_SECRET_FILE = "control-secret.json";
|
|
8
|
+
const WINDOWS_CONTROL_SECRET_BYTES = 32;
|
|
9
|
+
const WINDOWS_PIPE_DIGEST_HEX_CHARS = 32;
|
|
10
|
+
const WINDOWS_PIPE_RANDOM_BYTES = 16;
|
|
11
|
+
/**
|
|
12
|
+
* Node's net module has no filesystem unix sockets on Windows: a string path
|
|
13
|
+
* passed to server.listen()/createConnection() is a named pipe, which must live
|
|
14
|
+
* in the flat, machine-wide \\.\pipe\ namespace. A filesystem path such as
|
|
15
|
+
* ...\daemon\voltd.sock makes CreateNamedPipe fail with EACCES. Derive the pipe
|
|
16
|
+
* name from a per-agent secret so another local user cannot pre-create the
|
|
17
|
+
* daemon's predictable endpoint before startup.
|
|
18
|
+
*/
|
|
19
|
+
function getWindowsNamedPipePath(agentDir) {
|
|
20
|
+
const secret = getOrCreateWindowsControlSecret(agentDir);
|
|
21
|
+
const digest = createHash("sha256")
|
|
22
|
+
.update(agentDir.toLowerCase())
|
|
23
|
+
.update("\0")
|
|
24
|
+
.update(secret.pipeSecret)
|
|
25
|
+
.digest("hex")
|
|
26
|
+
.slice(0, WINDOWS_PIPE_DIGEST_HEX_CHARS);
|
|
27
|
+
return `\\\\.\\pipe\\voltd-${digest}`;
|
|
28
|
+
}
|
|
29
|
+
function createWindowsControlSecret() {
|
|
30
|
+
return { pipeSecret: randomBytes(WINDOWS_CONTROL_SECRET_BYTES).toString("hex") };
|
|
31
|
+
}
|
|
32
|
+
function serializeWindowsControlSecret(secret) {
|
|
33
|
+
return `${JSON.stringify({ version: 1, pipeSecret: secret.pipeSecret })}\n`;
|
|
34
|
+
}
|
|
35
|
+
function isSecretHex(value) {
|
|
36
|
+
return typeof value === "string" && /^[0-9a-f]{64}$/i.test(value);
|
|
37
|
+
}
|
|
38
|
+
function readWindowsControlSecret(secretPath) {
|
|
39
|
+
try {
|
|
40
|
+
const parsed = JSON.parse(readFileSync(secretPath, "utf8"));
|
|
41
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const pipeSecret = parsed.pipeSecret;
|
|
45
|
+
return isSecretHex(pipeSecret) ? { pipeSecret: pipeSecret.toLowerCase() } : undefined;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function chmodControlSecret(secretPath) {
|
|
52
|
+
try {
|
|
53
|
+
chmodSync(secretPath, 0o600);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Best effort: Windows ignores POSIX-style mode bits, but Unix-like test
|
|
57
|
+
// environments and future runtimes still benefit from owner-only mode.
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function createWindowsControlSecretFile(secretPath) {
|
|
61
|
+
const secret = createWindowsControlSecret();
|
|
62
|
+
try {
|
|
63
|
+
writeFileSync(secretPath, serializeWindowsControlSecret(secret), { mode: 0o600, flag: "wx" });
|
|
64
|
+
chmodControlSecret(secretPath);
|
|
65
|
+
return secret;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (isErrnoException(error) && error.code === "EEXIST") {
|
|
69
|
+
const racedSecret = readWindowsControlSecret(secretPath);
|
|
70
|
+
if (racedSecret) {
|
|
71
|
+
return racedSecret;
|
|
72
|
+
}
|
|
73
|
+
return replaceWindowsControlSecretFile(secretPath);
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function replaceWindowsControlSecretFile(secretPath) {
|
|
79
|
+
const secret = createWindowsControlSecret();
|
|
80
|
+
const tempPath = join(dirname(secretPath), `.${WINDOWS_CONTROL_SECRET_FILE}.${process.pid}.${Date.now()}.${randomBytes(4).toString("hex")}.tmp`);
|
|
81
|
+
try {
|
|
82
|
+
writeFileSync(tempPath, serializeWindowsControlSecret(secret), { mode: 0o600, flag: "wx" });
|
|
83
|
+
chmodControlSecret(tempPath);
|
|
84
|
+
renameSync(tempPath, secretPath);
|
|
85
|
+
chmodControlSecret(secretPath);
|
|
86
|
+
return secret;
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
rmSync(tempPath, { force: true });
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function getOrCreateWindowsControlSecret(agentDir) {
|
|
94
|
+
const secretPath = getDaemonControlSecretPath(agentDir);
|
|
95
|
+
const existingSecret = readWindowsControlSecret(secretPath);
|
|
96
|
+
if (existingSecret) {
|
|
97
|
+
return existingSecret;
|
|
98
|
+
}
|
|
99
|
+
mkdirSync(getDaemonDir(agentDir), { recursive: true, mode: 0o700 });
|
|
100
|
+
return createWindowsControlSecretFile(secretPath);
|
|
101
|
+
}
|
|
102
|
+
function isErrnoException(error) {
|
|
103
|
+
return error instanceof Error && "code" in error;
|
|
104
|
+
}
|
|
105
|
+
/** True for Windows named-pipe socket paths (\\.\pipe\... or \\?\pipe\...). */
|
|
106
|
+
export function isWindowsNamedPipePath(socketPath) {
|
|
107
|
+
return /^\\\\[.?]\\pipe\\/.test(socketPath);
|
|
108
|
+
}
|
|
109
|
+
export function getDaemonDir(agentDir = getAgentDir()) {
|
|
110
|
+
return join(agentDir, "daemon");
|
|
111
|
+
}
|
|
112
|
+
export function getDaemonControlSecretPath(agentDir = getAgentDir()) {
|
|
113
|
+
return join(getDaemonDir(agentDir), WINDOWS_CONTROL_SECRET_FILE);
|
|
114
|
+
}
|
|
115
|
+
export function rotateWindowsDaemonSocketSecret(agentDir = getAgentDir()) {
|
|
116
|
+
if (process.platform !== "win32") {
|
|
117
|
+
return getDaemonSocketPath(agentDir);
|
|
118
|
+
}
|
|
119
|
+
mkdirSync(getDaemonDir(agentDir), { recursive: true, mode: 0o700 });
|
|
120
|
+
replaceWindowsControlSecretFile(getDaemonControlSecretPath(agentDir));
|
|
121
|
+
return getWindowsNamedPipePath(agentDir);
|
|
122
|
+
}
|
|
123
|
+
function getFallbackSocketPath() {
|
|
124
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : 0;
|
|
125
|
+
const runtimeDir = process.env.XDG_RUNTIME_DIR;
|
|
126
|
+
if (runtimeDir) {
|
|
127
|
+
return join(runtimeDir, `voltd-${uid}.sock`);
|
|
128
|
+
}
|
|
129
|
+
return join(`/tmp/voltd-${uid}`, "voltd.sock");
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Actual daemon listen endpoint for a new instance. Windows named pipes cannot
|
|
133
|
+
* be unlinked, so default daemons use a fresh pipe name and publish it through
|
|
134
|
+
* the pidfile. POSIX keeps the stable socket path because stale files can be
|
|
135
|
+
* removed from a private directory.
|
|
136
|
+
*/
|
|
137
|
+
export function createDaemonControlSocketPath(agentDir = getAgentDir()) {
|
|
138
|
+
if (process.platform !== "win32") {
|
|
139
|
+
return getDaemonSocketPath(agentDir);
|
|
140
|
+
}
|
|
141
|
+
const scope = createHash("sha256").update(agentDir.toLowerCase()).digest("hex").slice(0, 16);
|
|
142
|
+
return `\\\\.\\pipe\\voltd-${scope}-${randomBytes(WINDOWS_PIPE_RANDOM_BYTES).toString("hex")}`;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Default socket path lives in the daemon dir; when the agent dir is nested
|
|
146
|
+
* deep enough to overflow the platform socket-path limit, fall back to a
|
|
147
|
+
* runtime dir. The actual path is recorded in the pidfile, which clients read
|
|
148
|
+
* when the default probe fails.
|
|
149
|
+
*/
|
|
150
|
+
export function getDaemonSocketPath(agentDir = getAgentDir()) {
|
|
151
|
+
if (process.platform === "win32") {
|
|
152
|
+
return getWindowsNamedPipePath(agentDir);
|
|
153
|
+
}
|
|
154
|
+
const defaultPath = join(getDaemonDir(agentDir), "voltd.sock");
|
|
155
|
+
if (Buffer.byteLength(defaultPath, "utf8") <= MAX_SOCKET_PATH_BYTES) {
|
|
156
|
+
return defaultPath;
|
|
157
|
+
}
|
|
158
|
+
return getFallbackSocketPath();
|
|
159
|
+
}
|
|
160
|
+
export function getDaemonPaths(agentDir = getAgentDir()) {
|
|
161
|
+
const daemonDir = getDaemonDir(agentDir);
|
|
162
|
+
return {
|
|
163
|
+
daemonDir,
|
|
164
|
+
socketPath: getDaemonSocketPath(agentDir),
|
|
165
|
+
pidfilePath: join(daemonDir, "voltd.pid"),
|
|
166
|
+
lockDirPath: join(daemonDir, "voltd.lock"),
|
|
167
|
+
logPath: join(daemonDir, "voltd.log"),
|
|
168
|
+
statePath: join(daemonDir, "state.json"),
|
|
169
|
+
auditPath: join(daemonDir, "audit.jsonl"),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/** Create the daemon dir (0700) and, for fallback sockets, the socket's parent dir. */
|
|
173
|
+
export function ensureDaemonDirs(paths) {
|
|
174
|
+
mkdirSync(paths.daemonDir, { recursive: true, mode: 0o700 });
|
|
175
|
+
// Named pipes have no parent directory on disk to create or harden.
|
|
176
|
+
if (isWindowsNamedPipePath(paths.socketPath)) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (!paths.socketPath.startsWith(paths.daemonDir)) {
|
|
180
|
+
const socketDir = dirname(paths.socketPath);
|
|
181
|
+
mkdirSync(socketDir, { recursive: true, mode: 0o700 });
|
|
182
|
+
assertPrivateSocketDir(socketDir);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* The fallback socket dir lives under a shared parent (/tmp or
|
|
187
|
+
* XDG_RUNTIME_DIR) at a predictable path, and mkdir with recursive silently
|
|
188
|
+
* accepts a pre-existing directory without touching its mode. Verify the
|
|
189
|
+
* directory is ours before placing the socket in it, and tighten loose
|
|
190
|
+
* permissions on one we own.
|
|
191
|
+
*/
|
|
192
|
+
function assertPrivateSocketDir(dir) {
|
|
193
|
+
if (process.platform === "win32") {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const stats = lstatSync(dir);
|
|
197
|
+
if (!stats.isDirectory()) {
|
|
198
|
+
throw new Error(`voltd socket directory ${dir} is not a directory`);
|
|
199
|
+
}
|
|
200
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : stats.uid;
|
|
201
|
+
if (stats.uid !== uid) {
|
|
202
|
+
throw new Error(`refusing to use voltd socket directory ${dir}: owned by uid ${stats.uid}, not ${uid}`);
|
|
203
|
+
}
|
|
204
|
+
if ((stats.mode & 0o077) !== 0) {
|
|
205
|
+
chmodSync(dir, 0o700);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/daemon/paths.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes } from \"node:crypto\";\nimport { chmodSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { getAgentDir } from \"../config.ts\";\n\n/** Unix domain socket paths are capped around 104 (macOS) / 108 (Linux) bytes. */\nconst MAX_SOCKET_PATH_BYTES = 100;\nconst WINDOWS_CONTROL_SECRET_FILE = \"control-secret.json\";\nconst WINDOWS_CONTROL_SECRET_BYTES = 32;\nconst WINDOWS_PIPE_DIGEST_HEX_CHARS = 32;\nconst WINDOWS_PIPE_RANDOM_BYTES = 16;\n\ninterface WindowsControlSecret {\n\tpipeSecret: string;\n}\n\n/**\n * Node's net module has no filesystem unix sockets on Windows: a string path\n * passed to server.listen()/createConnection() is a named pipe, which must live\n * in the flat, machine-wide \\\\.\\pipe\\ namespace. A filesystem path such as\n * ...\\daemon\\voltd.sock makes CreateNamedPipe fail with EACCES. Derive the pipe\n * name from a per-agent secret so another local user cannot pre-create the\n * daemon's predictable endpoint before startup.\n */\nfunction getWindowsNamedPipePath(agentDir: string): string {\n\tconst secret = getOrCreateWindowsControlSecret(agentDir);\n\tconst digest = createHash(\"sha256\")\n\t\t.update(agentDir.toLowerCase())\n\t\t.update(\"\\0\")\n\t\t.update(secret.pipeSecret)\n\t\t.digest(\"hex\")\n\t\t.slice(0, WINDOWS_PIPE_DIGEST_HEX_CHARS);\n\treturn `\\\\\\\\.\\\\pipe\\\\voltd-${digest}`;\n}\n\nfunction createWindowsControlSecret(): WindowsControlSecret {\n\treturn { pipeSecret: randomBytes(WINDOWS_CONTROL_SECRET_BYTES).toString(\"hex\") };\n}\n\nfunction serializeWindowsControlSecret(secret: WindowsControlSecret): string {\n\treturn `${JSON.stringify({ version: 1, pipeSecret: secret.pipeSecret })}\\n`;\n}\n\nfunction isSecretHex(value: unknown): value is string {\n\treturn typeof value === \"string\" && /^[0-9a-f]{64}$/i.test(value);\n}\n\nfunction readWindowsControlSecret(secretPath: string): WindowsControlSecret | undefined {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(secretPath, \"utf8\")) as unknown;\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst pipeSecret = (parsed as { pipeSecret?: unknown }).pipeSecret;\n\t\treturn isSecretHex(pipeSecret) ? { pipeSecret: pipeSecret.toLowerCase() } : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction chmodControlSecret(secretPath: string): void {\n\ttry {\n\t\tchmodSync(secretPath, 0o600);\n\t} catch {\n\t\t// Best effort: Windows ignores POSIX-style mode bits, but Unix-like test\n\t\t// environments and future runtimes still benefit from owner-only mode.\n\t}\n}\n\nfunction createWindowsControlSecretFile(secretPath: string): WindowsControlSecret {\n\tconst secret = createWindowsControlSecret();\n\ttry {\n\t\twriteFileSync(secretPath, serializeWindowsControlSecret(secret), { mode: 0o600, flag: \"wx\" });\n\t\tchmodControlSecret(secretPath);\n\t\treturn secret;\n\t} catch (error) {\n\t\tif (isErrnoException(error) && error.code === \"EEXIST\") {\n\t\t\tconst racedSecret = readWindowsControlSecret(secretPath);\n\t\t\tif (racedSecret) {\n\t\t\t\treturn racedSecret;\n\t\t\t}\n\t\t\treturn replaceWindowsControlSecretFile(secretPath);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction replaceWindowsControlSecretFile(secretPath: string): WindowsControlSecret {\n\tconst secret = createWindowsControlSecret();\n\tconst tempPath = join(\n\t\tdirname(secretPath),\n\t\t`.${WINDOWS_CONTROL_SECRET_FILE}.${process.pid}.${Date.now()}.${randomBytes(4).toString(\"hex\")}.tmp`,\n\t);\n\ttry {\n\t\twriteFileSync(tempPath, serializeWindowsControlSecret(secret), { mode: 0o600, flag: \"wx\" });\n\t\tchmodControlSecret(tempPath);\n\t\trenameSync(tempPath, secretPath);\n\t\tchmodControlSecret(secretPath);\n\t\treturn secret;\n\t} catch (error) {\n\t\trmSync(tempPath, { force: true });\n\t\tthrow error;\n\t}\n}\n\nfunction getOrCreateWindowsControlSecret(agentDir: string): WindowsControlSecret {\n\tconst secretPath = getDaemonControlSecretPath(agentDir);\n\tconst existingSecret = readWindowsControlSecret(secretPath);\n\tif (existingSecret) {\n\t\treturn existingSecret;\n\t}\n\tmkdirSync(getDaemonDir(agentDir), { recursive: true, mode: 0o700 });\n\treturn createWindowsControlSecretFile(secretPath);\n}\n\nfunction isErrnoException(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\n/** True for Windows named-pipe socket paths (\\\\.\\pipe\\... or \\\\?\\pipe\\...). */\nexport function isWindowsNamedPipePath(socketPath: string): boolean {\n\treturn /^\\\\\\\\[.?]\\\\pipe\\\\/.test(socketPath);\n}\n\nexport interface DaemonPaths {\n\tdaemonDir: string;\n\tsocketPath: string;\n\tpidfilePath: string;\n\tlockDirPath: string;\n\tlogPath: string;\n\tstatePath: string;\n\tauditPath: string;\n}\n\nexport function getDaemonDir(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \"daemon\");\n}\n\nexport function getDaemonControlSecretPath(agentDir: string = getAgentDir()): string {\n\treturn join(getDaemonDir(agentDir), WINDOWS_CONTROL_SECRET_FILE);\n}\n\nexport function rotateWindowsDaemonSocketSecret(agentDir: string = getAgentDir()): string {\n\tif (process.platform !== \"win32\") {\n\t\treturn getDaemonSocketPath(agentDir);\n\t}\n\tmkdirSync(getDaemonDir(agentDir), { recursive: true, mode: 0o700 });\n\treplaceWindowsControlSecretFile(getDaemonControlSecretPath(agentDir));\n\treturn getWindowsNamedPipePath(agentDir);\n}\n\nfunction getFallbackSocketPath(): string {\n\tconst uid = typeof process.getuid === \"function\" ? process.getuid() : 0;\n\tconst runtimeDir = process.env.XDG_RUNTIME_DIR;\n\tif (runtimeDir) {\n\t\treturn join(runtimeDir, `voltd-${uid}.sock`);\n\t}\n\treturn join(`/tmp/voltd-${uid}`, \"voltd.sock\");\n}\n\n/**\n * Actual daemon listen endpoint for a new instance. Windows named pipes cannot\n * be unlinked, so default daemons use a fresh pipe name and publish it through\n * the pidfile. POSIX keeps the stable socket path because stale files can be\n * removed from a private directory.\n */\nexport function createDaemonControlSocketPath(agentDir: string = getAgentDir()): string {\n\tif (process.platform !== \"win32\") {\n\t\treturn getDaemonSocketPath(agentDir);\n\t}\n\tconst scope = createHash(\"sha256\").update(agentDir.toLowerCase()).digest(\"hex\").slice(0, 16);\n\treturn `\\\\\\\\.\\\\pipe\\\\voltd-${scope}-${randomBytes(WINDOWS_PIPE_RANDOM_BYTES).toString(\"hex\")}`;\n}\n\n/**\n * Default socket path lives in the daemon dir; when the agent dir is nested\n * deep enough to overflow the platform socket-path limit, fall back to a\n * runtime dir. The actual path is recorded in the pidfile, which clients read\n * when the default probe fails.\n */\nexport function getDaemonSocketPath(agentDir: string = getAgentDir()): string {\n\tif (process.platform === \"win32\") {\n\t\treturn getWindowsNamedPipePath(agentDir);\n\t}\n\tconst defaultPath = join(getDaemonDir(agentDir), \"voltd.sock\");\n\tif (Buffer.byteLength(defaultPath, \"utf8\") <= MAX_SOCKET_PATH_BYTES) {\n\t\treturn defaultPath;\n\t}\n\treturn getFallbackSocketPath();\n}\n\nexport function getDaemonPaths(agentDir: string = getAgentDir()): DaemonPaths {\n\tconst daemonDir = getDaemonDir(agentDir);\n\treturn {\n\t\tdaemonDir,\n\t\tsocketPath: getDaemonSocketPath(agentDir),\n\t\tpidfilePath: join(daemonDir, \"voltd.pid\"),\n\t\tlockDirPath: join(daemonDir, \"voltd.lock\"),\n\t\tlogPath: join(daemonDir, \"voltd.log\"),\n\t\tstatePath: join(daemonDir, \"state.json\"),\n\t\tauditPath: join(daemonDir, \"audit.jsonl\"),\n\t};\n}\n\n/** Create the daemon dir (0700) and, for fallback sockets, the socket's parent dir. */\nexport function ensureDaemonDirs(paths: DaemonPaths): void {\n\tmkdirSync(paths.daemonDir, { recursive: true, mode: 0o700 });\n\t// Named pipes have no parent directory on disk to create or harden.\n\tif (isWindowsNamedPipePath(paths.socketPath)) {\n\t\treturn;\n\t}\n\tif (!paths.socketPath.startsWith(paths.daemonDir)) {\n\t\tconst socketDir = dirname(paths.socketPath);\n\t\tmkdirSync(socketDir, { recursive: true, mode: 0o700 });\n\t\tassertPrivateSocketDir(socketDir);\n\t}\n}\n\n/**\n * The fallback socket dir lives under a shared parent (/tmp or\n * XDG_RUNTIME_DIR) at a predictable path, and mkdir with recursive silently\n * accepts a pre-existing directory without touching its mode. Verify the\n * directory is ours before placing the socket in it, and tighten loose\n * permissions on one we own.\n */\nfunction assertPrivateSocketDir(dir: string): void {\n\tif (process.platform === \"win32\") {\n\t\treturn;\n\t}\n\tconst stats = lstatSync(dir);\n\tif (!stats.isDirectory()) {\n\t\tthrow new Error(`voltd socket directory ${dir} is not a directory`);\n\t}\n\tconst uid = typeof process.getuid === \"function\" ? process.getuid() : stats.uid;\n\tif (stats.uid !== uid) {\n\t\tthrow new Error(`refusing to use voltd socket directory ${dir}: owned by uid ${stats.uid}, not ${uid}`);\n\t}\n\tif ((stats.mode & 0o077) !== 0) {\n\t\tchmodSync(dir, 0o700);\n\t}\n}\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { PidfileContents } from "./main.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Process-identity verification for the pidfile SIGTERM fallbacks: a pidfile
|
|
4
|
+
* outlives its daemon, and the recorded pid can be recycled by an unrelated
|
|
5
|
+
* process. Before killing, verify the live process (a) started when the
|
|
6
|
+
* pidfile says the daemon started and (b) has a voltd-looking command line.
|
|
7
|
+
*
|
|
8
|
+
* Platform-aware by design (Windows daemon support is planned): POSIX queries
|
|
9
|
+
* `ps -o etime=,args=`; Windows queries Win32_Process via PowerShell CIM.
|
|
10
|
+
*/
|
|
11
|
+
export type ProcessQueryRunner = (command: string, args: string[]) => Promise<{
|
|
12
|
+
code: number;
|
|
13
|
+
output: string;
|
|
14
|
+
}>;
|
|
15
|
+
export interface ProcessIdentity {
|
|
16
|
+
/** Absolute process start time; undefined when the platform query lacks it. */
|
|
17
|
+
startTimeMs?: number;
|
|
18
|
+
commandLine: string;
|
|
19
|
+
}
|
|
20
|
+
export type PidfileVerification = "match" | "mismatch" | "gone";
|
|
21
|
+
export type ProcessCreationVerification = "match" | "mismatch" | "gone" | "unknown";
|
|
22
|
+
export interface VerifyPidfileOptions {
|
|
23
|
+
runner?: ProcessQueryRunner;
|
|
24
|
+
platform?: NodeJS.Platform;
|
|
25
|
+
now?: number;
|
|
26
|
+
/** Allowed |actual start - pidfile.startedAtMs| skew (spawn-to-record delay, etime rounding). */
|
|
27
|
+
toleranceMs?: number;
|
|
28
|
+
/** Injectable liveness probe (kill(pid, 0)). */
|
|
29
|
+
isProcessAlive?: (pid: number) => "alive" | "gone";
|
|
30
|
+
}
|
|
31
|
+
export declare const DEFAULT_START_TIME_TOLERANCE_MS = 15000;
|
|
32
|
+
/** Parse ps etime ("[[dd-]hh:]mm:ss") into elapsed milliseconds. */
|
|
33
|
+
export declare function parseElapsedTime(value: string): number | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Verify only process creation identity. Unlike pidfile verification, this
|
|
36
|
+
* distinguishes a verifiable recycled PID from an unavailable OS query so
|
|
37
|
+
* startup-lock recovery can reap the former while failing closed on the latter.
|
|
38
|
+
*/
|
|
39
|
+
export declare function verifyProcessCreationTime(record: {
|
|
40
|
+
pid: number;
|
|
41
|
+
startedAtMs: number;
|
|
42
|
+
}, options?: VerifyPidfileOptions): Promise<ProcessCreationVerification>;
|
|
43
|
+
/** Verify both process creation identity and the voltd command marker. */
|
|
44
|
+
export declare function verifyVoltdProcessIdentity(record: {
|
|
45
|
+
pid: number;
|
|
46
|
+
startedAtMs: number;
|
|
47
|
+
}, options?: VerifyPidfileOptions): Promise<ProcessCreationVerification>;
|
|
48
|
+
/**
|
|
49
|
+
* Verify that pidfile.pid still refers to the daemon that wrote the pidfile.
|
|
50
|
+
*
|
|
51
|
+
* - "gone": no such process (or it exited mid-check) — safe to treat as stopped.
|
|
52
|
+
* - "match": alive, start time within tolerance of startedAtMs, and a
|
|
53
|
+
* voltd-looking command line — safe to signal.
|
|
54
|
+
* - "mismatch": alive but unverifiable or verifiably different (recycled pid,
|
|
55
|
+
* another user's process, ps/powershell unavailable) — do NOT signal.
|
|
56
|
+
*/
|
|
57
|
+
export declare function verifyPidfileProcess(pidfile: Pick<PidfileContents, "pid" | "startedAtMs">, options?: VerifyPidfileOptions): Promise<PidfileVerification>;
|
|
58
|
+
//# sourceMappingURL=process-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-identity.d.ts","sourceRoot":"","sources":["../../src/daemon/process-identity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD;;;;;;;;GAQG;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEhH,MAAM,WAAW,eAAe;IAC/B,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;AAChE,MAAM,MAAM,2BAA2B,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAEpF,MAAM,WAAW,oBAAoB;IACpC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC;CACnD;AAED,eAAO,MAAM,+BAA+B,QAAS,CAAC;AAsCtD,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOlE;AAwFD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC9C,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EAC5C,OAAO,GAAE,oBAAyB,GAChC,OAAO,CAAC,2BAA2B,CAAC,CAatC;AAED,0EAA0E;AAC1E,wBAAsB,0BAA0B,CAC/C,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EAC5C,OAAO,GAAE,oBAAyB,GAChC,OAAO,CAAC,2BAA2B,CAAC,CAmBtC;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,aAAa,CAAC,EACrD,OAAO,GAAE,oBAAyB,GAChC,OAAO,CAAC,mBAAmB,CAAC,CAoB9B","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"]}
|