@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,605 @@
|
|
|
1
|
+
# RFC: Git-worktree-backed session isolation for voltd
|
|
2
|
+
|
|
3
|
+
**Status:** Draft
|
|
4
|
+
**Package:** `packages/coding-agent` (all paths below are relative to it)
|
|
5
|
+
**Protocol feature:** `worktrees.v1`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Summary
|
|
10
|
+
|
|
11
|
+
Every daemon-owned headless runtime today runs with `cwd = workspace.path` — the one registered checkout — so two concurrent sessions in the same workspace stomp on each other's files, branches, and index. This RFC adds optional **git-worktree-backed session isolation**: the daemon manages worktrees under `~/.volt/agent/worktrees/`, a session can be started "into" a worktree (from the mobile app over the iroh remote protocol, and later from the TUI), and the daemon persists a `sessionId → worktree` binding so resume, relay, lease takeover, and sanitization all follow the worktree cwd. Sessions remain stored and listed under the **parent workspace**, so `list_sessions`, `target:"last"`, and lease keying keep working unchanged.
|
|
12
|
+
|
|
13
|
+
Delivery is phased:
|
|
14
|
+
|
|
15
|
+
- **Phase 1 (foundation):** daemon worktree manager, persisted state, management-stream RPCs (`create_worktree` / `list_worktrees` / `remove_worktree`), `target:"new"` handshake extension, `worktrees.v1` capability, `volt remote worktree …` CLI.
|
|
16
|
+
- **Phase 2 (TUI):** new-session-into-worktree from the TUI; lease takeover of a worktree-bound session attaches with the worktree cwd.
|
|
17
|
+
- **Phase 3 (polish):** merge-back UX, cleanup/retention policies, prune-on-start, app affordances.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. Background
|
|
22
|
+
|
|
23
|
+
Verified anchors (line numbers may drift ±5):
|
|
24
|
+
|
|
25
|
+
**cwd flow.** `IntegratedRuntimeRegistry.createEntry` is the single point where a workspace path becomes a runtime cwd: it calls `createIrohRemoteAgentRuntimeWithSessionSelection({ …, cwd: authorization.workspace.path, … })` (`src/daemon/integrated-runtimes.ts:225-233`). That factory fans `options.cwd` into migrations, `SettingsManager.create`, `createAgentSessionServices`, `SubagentManager`, and session-dir resolution (`src/modes/rpc/iroh-remote-agent-runtime.ts:89-152`). Critically, the factory already exposes two bypass seams: `sessionDir?: string` (line 37) and `resolvedSessionTarget?` (line 34), and its internal store is `createSessionManagerTargetStore(options.cwd, options.sessionDir ?? getDefaultSessionDir(options.cwd, agentDir))` (lines 168-176).
|
|
26
|
+
|
|
27
|
+
**Session storage.** `getDefaultSessionDirPath(cwd)` is a pure encoding of the cwd into `~/.volt/agent/sessions/--<encoded-cwd>--/` (`src/core/session-manager.ts:438-451`). `SessionManager.create(cwd, sessionDir)` stores `cwd` in the session header (line 1461); `SessionManager.open(path, sessionDir, cwdOverride)` defaults to the **header cwd** (line 1477); `SessionManager.list(cwd, sessionDir)` applies a cwd filter **only** when an explicit `sessionDir` differs from the default dir for `cwd`: `filterCwd = sessionDir !== undefined && dir !== getDefaultSessionDirPath(cwd)` (lines 1570-1576). The daemon's `list_sessions` lists `SessionManager.list(workspace.path, getDefaultSessionDir(workspace.path, context.agentDir))` (`src/daemon/conversation-commands.ts:984-990`) — since `context.agentDir` is the same env-aware `getAgentDir()` (`src/config.ts:500-506`) that `getDefaultSessionDirPath` defaults to, `filterCwd` is false and **every session file in the parent's dir is listed regardless of header cwd**. This is what makes the "parent-keyed session dir" decision in §5.1.7 work.
|
|
28
|
+
|
|
29
|
+
**Daemon state.** Wire/host shape `IrohRemoteHostState { hostSecretKey?, pairingSecretTombstones?, workspaces, clients, revokedClients?, pendingPairingTickets? }` (`src/core/remote/iroh/state.ts:97-104`) with strict per-field parsers; `parseOptionalArray` maps `undefined → []` (lines 335-340), so new optional collections are backward compatible. The daemon envelope `VoltdStateFileV1` (`src/daemon/state.ts:24-51`) hard-fails on `version !== 1` (line 102) and reconstructs state via `hostStateToVoltdState`/`voltdStateToHostState` (lines 69-94) — **any new collection must be threaded through both converters, `parseIrohRemoteHostState`, `serializeIrohRemoteHostState` (state.ts:152-193), and `cloneHostState` (state-manager.ts:635-646), or it is silently dropped on the next write.** All five sites enumerate fields explicitly.
|
|
30
|
+
|
|
31
|
+
**Handshake strictness.** `parseConversationTarget` allowlists exactly `["target", "sessionId"]` via `expectKnownFields` and rejects anything else with `IrohRemoteHandshakeError("invalid_conversation_target", …)` (`src/core/remote/iroh/handshake.ts:438-462, 494-501`). `parseWorkspaceManagementTarget` pins `purpose === "unregister_workspace"` (lines 479-491). Host features `IROH_REMOTE_HOST_FEATURES = ["multi_streams.v1", "conversation_streams.v1"]` (`src/core/remote/iroh/protocol.ts:5-10`) are sent in every handshake success; `docs/iroh-remote-protocol.md` describes features as optional host capabilities, not a version bump.
|
|
32
|
+
|
|
33
|
+
**Management-stream template.** `runWorkspaceManagement` (`src/daemon/iroh-service.ts:854-905`) registers a synthetic-session active stream and runs `runWorkspaceManagementStream` (`src/daemon/workspace-streams.ts:207-282`): JSONL loop, command-type whitelist (`!== "unregister_workspace"` → `unsupported_on_workspace_management_stream`), strict request parse (`parseWorkspaceManagementUnregisterRequest`, lines 190-205: unknown fields → `invalid_request`; name mismatch → `session_mismatch`), audit log, `createRpcSuccessResponse`.
|
|
34
|
+
|
|
35
|
+
**Sanitizer.** All outbound frames map `authorization.workspace.path → "/workspace"` (`src/daemon/workspace-streams.ts:64-72`). `createSanitizerContext` derives `workspacePathVariants` from a **single root** — the variants are only separator/Unicode-normalization forms of that one path (`src/core/remote/iroh/outbound-filter.ts:121-146`). There is no multi-root support today.
|
|
36
|
+
|
|
37
|
+
**Trust & tools.** `getAllowTools` = daemon settings `allowTools` else `workspace.allowedTools` (`src/daemon/iroh-service.ts:429-435`); `projectTrusted` = `resolveIrohRemoteWorkspaceProjectTrusted(workspace, { trustStore })` (`src/core/remote/iroh/host-policy.ts:15-29`) with ancestor-walking `ProjectTrustStore.get` (`src/core/trust-manager.ts:44-58`) and ancestor-walking `hasTrustRequiringProjectResources` (lists `.mcp.json`, `.volt/*`, `.agents/skills`; trust-manager.ts:180-215). A worktree under `~/.volt/agent/worktrees` is **not** filesystem-nested under the workspace, so it would not inherit trust without explicit plumbing.
|
|
38
|
+
|
|
39
|
+
**Lease/registry keying.** Both `LeaseBroker` (`src/daemon/lease-broker.ts:64-66`) and `IntegratedRuntimeRegistry.getRegistryKey` (`integrated-runtimes.ts:152-154`) key on `${workspaceName}\0${sessionId}` — no path dimension. TUI attach resolves its workspace by **path-prefix match** against registered workspaces and **auto-registers** the cwd on miss (`src/modes/interactive/daemon-attach.ts:192-229`).
|
|
40
|
+
|
|
41
|
+
**Relay preamble.** `RelayPreamble.authorization` carries `{ clientNodeId, workspaceName, workspacePath }` and `resolvedTarget.workspacePath` (`src/daemon/control-protocol.ts:219-244`); the TUI reconstructs authorization from it for relay serving.
|
|
42
|
+
|
|
43
|
+
**Git helpers.** No `git worktree` invocation exists anywhere in `src/`. `src/core/review.ts:108-125` has a private promise-wrapped `spawn` runner; `src/utils/child-process.ts:18-36` provides the cross-platform `spawnProcess`/`waitForChildProcess` seam.
|
|
44
|
+
|
|
45
|
+
**CLI.** `volt remote <cmd>` routes through `handleRemoteControlCommand` (`src/daemon/remote-cli.ts`), which talks to the daemon over the control socket using `ControlRequest` types (`src/daemon/control-protocol.ts:50-70`, e.g. `workspace_register` at line 67, handled in `src/daemon/main.ts:308+`).
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 3. Goals / Non-goals
|
|
50
|
+
|
|
51
|
+
### Goals
|
|
52
|
+
|
|
53
|
+
1. A session can optionally run in a daemon-managed git worktree, isolated from the main checkout and from other worktrees of the same workspace.
|
|
54
|
+
2. Worktree lifecycle (create/list/remove/prune) is controllable from the mobile app (iroh management stream) and the CLI; Phase 2 adds the TUI.
|
|
55
|
+
3. Sessions stay keyed and listable **under the parent workspace** — `list_sessions`, `target:"session"`, `target:"last"`, push notifications, and leases keep the `(workspaceName, sessionId)` model.
|
|
56
|
+
4. Resume of a worktree-bound session (daemon restart, phone reattach, TUI takeover) lands in the worktree cwd.
|
|
57
|
+
5. Worktree runtimes inherit the parent workspace's trust decision and tool allowlist — **never wider**.
|
|
58
|
+
6. No absolute host paths cross the wire: paths are computed server-side; the sanitizer covers both the worktree path and the parent path.
|
|
59
|
+
7. Full backward compatibility: old app builds, old state files, old daemons keep working; new features are gated on `worktrees.v1`.
|
|
60
|
+
|
|
61
|
+
### Non-goals
|
|
62
|
+
|
|
63
|
+
- Automatic merge/rebase of worktree branches back into the base branch (Phase 3 provides *guidance* UX only; git operations stay user-initiated).
|
|
64
|
+
- Dependency bootstrap inside worktrees (`node_modules`, venvs) — documented limitation, see §6.
|
|
65
|
+
- Multiple concurrent runtimes for the *same* sessionId in different worktrees (sessions are single-cwd by construction).
|
|
66
|
+
- Worktrees for non-git workspaces, submodule-heavy special-casing, or bare-repo workspaces beyond a clean error.
|
|
67
|
+
- Changing the TUI's default behavior when launched inside an arbitrary directory.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 4. High-level proposal
|
|
72
|
+
|
|
73
|
+
Model a worktree as a **child resource of a registered workspace**, not as a workspace of its own. The alternative — auto-registering each worktree as a separate workspace — was considered and rejected: it fragments pairing/allowlists (`allowedWorkspaces` is per-client), splits `lastSessionIdByWorkspace`, breaks the one-name-per-repo mental model in the app, collides with the NFC-lowercase name-alias check in `upsertIrohRemoteWorkspace` (`src/core/remote/iroh/workspace.ts:53-86`), and multiplies unregister/cleanup paths. Keeping the parent workspace as the authorization and keying unit means the only new state is a worktree table plus a session binding, and the only cwd change is at the two runtime-creation choke points.
|
|
74
|
+
|
|
75
|
+
Storage layout:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
~/.volt/agent/worktrees/ (0700)
|
|
79
|
+
--<encoded-workspace-path>--/ (same encoding as session dirs)
|
|
80
|
+
<worktreeId>/ (the git worktree checkout)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Keying the directory by encoded workspace *path* (reusing the `--…--` scheme from `getDefaultSessionDirPath`) rather than workspace *name* survives workspace renames and name collisions.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 5. Detailed design
|
|
88
|
+
|
|
89
|
+
### 5.1 Phase 1 — foundation
|
|
90
|
+
|
|
91
|
+
#### 5.1.1 New module: `src/daemon/worktree-manager.ts`
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import type { IrohRemoteAuditLogger } from "../core/remote/iroh/audit.ts";
|
|
95
|
+
import type { IrohRemoteHostStateManager } from "../core/remote/iroh/state-manager.ts";
|
|
96
|
+
import type { IrohRemoteWorkspace, IrohRemoteWorkspaceWorktree } from "../core/remote/iroh/state.ts";
|
|
97
|
+
|
|
98
|
+
/** join(agentDir, "worktrees") — sibling of sessions/, daemon/, trust.json. */
|
|
99
|
+
export function getWorktreesRoot(agentDir: string): string;
|
|
100
|
+
|
|
101
|
+
/** Deterministic checkout path; never accepts a caller-supplied path. */
|
|
102
|
+
export function getWorktreeCheckoutPath(agentDir: string, workspacePath: string, worktreeId: string): string;
|
|
103
|
+
|
|
104
|
+
export const WORKTREE_ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;
|
|
105
|
+
|
|
106
|
+
export type WorktreeError =
|
|
107
|
+
| "not_a_git_repository"
|
|
108
|
+
| "worktree_exists"
|
|
109
|
+
| "worktree_branch_conflict"
|
|
110
|
+
| "worktree_not_found"
|
|
111
|
+
| "worktree_dirty"
|
|
112
|
+
| "worktree_busy" // has an active runtime / bound streaming session
|
|
113
|
+
| "worktree_limit_reached"
|
|
114
|
+
| "invalid_worktree_id"
|
|
115
|
+
| "git_failed";
|
|
116
|
+
|
|
117
|
+
export interface WorktreeGitRunner {
|
|
118
|
+
(args: string[], cwd: string): Promise<{ ok: boolean; code: number | null; stdout: string; stderr: string }>;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface WorktreeManagerOptions {
|
|
122
|
+
agentDir: string;
|
|
123
|
+
stateManager: IrohRemoteHostStateManager;
|
|
124
|
+
auditLogger: IrohRemoteAuditLogger;
|
|
125
|
+
/** Injectable for tests; defaults to spawnProcess/waitForChildProcess wrapper. */
|
|
126
|
+
runGit?: WorktreeGitRunner;
|
|
127
|
+
/** Injectable for tests / policy: max worktrees per workspace (default 16). */
|
|
128
|
+
maxWorktreesPerWorkspace?: number;
|
|
129
|
+
/** Seam for "is a runtime using this worktree" (wired to IntegratedRuntimeRegistry). */
|
|
130
|
+
hasActiveRuntimeForSession?: (workspaceName: string, sessionId: string) => boolean;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface WorktreeStatus extends IrohRemoteWorkspaceWorktree {
|
|
134
|
+
/** Checkout directory exists and `git worktree list` still knows it. */
|
|
135
|
+
available: boolean;
|
|
136
|
+
/** `git status --porcelain` non-empty (best-effort; undefined when unavailable). */
|
|
137
|
+
dirty?: boolean;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export class WorktreeManager {
|
|
141
|
+
constructor(options: WorktreeManagerOptions);
|
|
142
|
+
|
|
143
|
+
/** git worktree add; persists the record via stateManager with flush(). */
|
|
144
|
+
create(workspace: IrohRemoteWorkspace, options: {
|
|
145
|
+
id?: string; // default: generated slug (adjective-noun-nn)
|
|
146
|
+
branch?: string; // default: `volt/<id>`
|
|
147
|
+
baseRef?: string; // default: HEAD of the main checkout
|
|
148
|
+
}): Promise<{ ok: true; worktree: IrohRemoteWorkspaceWorktree } | { ok: false; error: WorktreeError; detail?: string }>;
|
|
149
|
+
|
|
150
|
+
list(workspace: IrohRemoteWorkspace): Promise<WorktreeStatus[]>;
|
|
151
|
+
|
|
152
|
+
/** Refuses dirty/busy unless force; `git worktree remove [--force]`, then drops the record. */
|
|
153
|
+
remove(workspace: IrohRemoteWorkspace, worktreeId: string, options?: { force?: boolean }):
|
|
154
|
+
Promise<{ ok: true } | { ok: false; error: WorktreeError; detail?: string }>;
|
|
155
|
+
|
|
156
|
+
/** Reconcile persisted records vs filesystem vs `git worktree list --porcelain`;
|
|
157
|
+
* runs `git worktree prune` in the main checkout. Safe to run on daemon start. */
|
|
158
|
+
prune(workspace: IrohRemoteWorkspace): Promise<{ removedRecords: string[]; orphanCheckouts: string[] }>;
|
|
159
|
+
|
|
160
|
+
/** Lookup used by conversation open/resume and relay preamble resolution. */
|
|
161
|
+
resolveSessionWorktree(workspaceName: string, sessionId: string): Promise<IrohRemoteWorkspaceWorktree | undefined>;
|
|
162
|
+
bindSession(workspaceName: string, worktreeId: string, sessionId: string): Promise<void>;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Git invocations (always executed with `cwd = workspace.path`, i.e. the main checkout — never a caller path):
|
|
167
|
+
|
|
168
|
+
| Operation | Command |
|
|
169
|
+
|---|---|
|
|
170
|
+
| validate repo | `git rev-parse --git-common-dir` |
|
|
171
|
+
| create | `git worktree add <checkoutPath> -b <branch> <baseRef>` |
|
|
172
|
+
| enumerate | `git worktree list --porcelain` |
|
|
173
|
+
| remove | `git worktree remove [--force] <checkoutPath>` |
|
|
174
|
+
| prune | `git worktree prune` |
|
|
175
|
+
| dirty check | `git -C <checkoutPath> status --porcelain --no-optional-locks` |
|
|
176
|
+
|
|
177
|
+
The default `runGit` is a ~15-line wrapper over `spawnProcess` + `waitForChildProcess` (`src/utils/child-process.ts:18-36, 49+`) with `stdio: ["ignore","pipe","pipe"]`, mirroring the private `runCommand` in `src/core/review.ts:108-125` (which stays private; do not export it — its error shape is review-specific).
|
|
178
|
+
|
|
179
|
+
**Path containment invariant:** `getWorktreeCheckoutPath` is the only producer of checkout paths; it validates `worktreeId` against `WORKTREE_ID_PATTERN`, then asserts `resolve(path)` starts with `resolve(getWorktreesRoot(agentDir)) + sep` before any git call. RPCs and control commands accept **ids and refs only, never paths** (branch/baseRef are validated with `git check-ref-format`-equivalent syntax checks and passed as separate argv entries, never shell-interpolated).
|
|
180
|
+
|
|
181
|
+
#### 5.1.2 State schema
|
|
182
|
+
|
|
183
|
+
Add the worktree table to the host state (so the existing operation-queue/state-manager machinery applies), and thread it through all five enumeration sites.
|
|
184
|
+
|
|
185
|
+
`src/core/remote/iroh/state.ts`:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
export interface IrohRemoteWorkspaceWorktree {
|
|
189
|
+
/** ^[a-z0-9][a-z0-9._-]{0,63}$ — unique per workspace. */
|
|
190
|
+
id: string;
|
|
191
|
+
workspaceName: string;
|
|
192
|
+
/** Absolute checkout path under getWorktreesRoot(agentDir); host-local, never sent on the wire. */
|
|
193
|
+
path: string;
|
|
194
|
+
branch: string;
|
|
195
|
+
baseRef?: string;
|
|
196
|
+
createdAt: number;
|
|
197
|
+
/** Sessions bound to this worktree (usually exactly one). */
|
|
198
|
+
sessionIds: string[];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface IrohRemoteHostState {
|
|
202
|
+
hostSecretKey?: number[];
|
|
203
|
+
pairingSecretTombstones?: IrohRemotePairingSecretTombstone[];
|
|
204
|
+
workspaces: IrohRemoteWorkspace[];
|
|
205
|
+
worktrees?: IrohRemoteWorkspaceWorktree[]; // NEW (optional ⇒ old files parse)
|
|
206
|
+
clients: IrohRemoteClient[];
|
|
207
|
+
revokedClients?: IrohRemoteRevokedClient[];
|
|
208
|
+
pendingPairingTickets?: IrohRemotePendingPairingTicket[];
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Parse/serialize/clone changes (all five sites are field-enumerating today, so each must be touched):
|
|
213
|
+
|
|
214
|
+
1. `parseIrohRemoteHostState` (state.ts:132-150): add
|
|
215
|
+
```ts
|
|
216
|
+
worktrees: parseOptionalArray(state.worktrees, "worktrees", parseIrohRemoteWorkspaceWorktree),
|
|
217
|
+
```
|
|
218
|
+
with a new strict parser:
|
|
219
|
+
```ts
|
|
220
|
+
export function parseIrohRemoteWorkspaceWorktree(value: unknown): IrohRemoteWorkspaceWorktree {
|
|
221
|
+
const worktree = expectRecord(value, "Iroh remote worktree");
|
|
222
|
+
const baseRef = expectOptionalString(worktree.baseRef, "worktree baseRef");
|
|
223
|
+
return {
|
|
224
|
+
id: expectWorktreeId(worktree.id), // pattern check, non-empty
|
|
225
|
+
workspaceName: expectString(worktree.workspaceName, "worktree workspaceName"),
|
|
226
|
+
path: expectString(worktree.path, "worktree path"),
|
|
227
|
+
branch: expectString(worktree.branch, "worktree branch"),
|
|
228
|
+
...(baseRef === undefined ? {} : { baseRef }),
|
|
229
|
+
createdAt: expectNumber(worktree.createdAt, "worktree createdAt"),
|
|
230
|
+
sessionIds: parseArray(worktree.sessionIds, "worktree sessionIds",
|
|
231
|
+
(entry) => expectString(entry, "worktree session id")),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
2. `serializeIrohRemoteHostState` (state.ts:152-193): add `worktrees: (state.worktrees ?? []).map((w) => ({ ...w, sessionIds: [...w.sessionIds] }))`.
|
|
236
|
+
3. `src/daemon/state.ts` — `VoltdStateFileV1` gains `worktrees: IrohRemoteWorkspaceWorktree[]`; `createEmptyVoltdState` initializes `[]`; **both** `voltdStateToHostState` and `hostStateToVoltdState` (state.ts:69-94) copy it (`hostState.worktrees ?? []` on the return trip). `parseVoltdState` needs no change beyond what `parseIrohRemoteHostState` provides, since it already delegates (line 105).
|
|
237
|
+
4. `cloneHostState` (`src/core/remote/iroh/state-manager.ts:635-646`): add `worktrees: (state.worktrees ?? []).map(cloneWorktree)`.
|
|
238
|
+
5. `IrohRemoteHostStateManager` (state-manager.ts:75+): new queued methods, mirroring `upsertWorkspace`/`unregisterWorkspace`:
|
|
239
|
+
```ts
|
|
240
|
+
upsertWorktree(worktree: IrohRemoteWorkspaceWorktree): Promise<IrohRemoteWorkspaceWorktree>;
|
|
241
|
+
removeWorktree(workspaceName: string, worktreeId: string): Promise<IrohRemoteWorkspaceWorktree | undefined>;
|
|
242
|
+
listWorktrees(workspaceName?: string): Promise<IrohRemoteWorkspaceWorktree[]>;
|
|
243
|
+
bindWorktreeSession(workspaceName: string, worktreeId: string, sessionId: string): Promise<void>;
|
|
244
|
+
findWorktreeForSession(workspaceName: string, sessionId: string): Promise<IrohRemoteWorkspaceWorktree | undefined>;
|
|
245
|
+
```
|
|
246
|
+
`unregisterWorkspace` (state-manager.ts:123-137) checks `state.worktrees` for the workspace inside the same exclusive state mutation. If any child exists it throws the structured `workspace_has_worktrees` conflict without changing the workspace, worktree records, pending tickets, or filesystem. The user must explicitly remove each worktree first; unregister never owns checkout deletion (§5.1.6).
|
|
247
|
+
|
|
248
|
+
Durability rule: `create` persists via `VoltdStateStore.flush()` (state.ts:306-315 pattern, as used for the freshly minted iroh key at `iroh-service.ts:513-521`) **after** `git worktree add` succeeds, so a crash window leaves at worst an orphan checkout (reconciled by `prune`), never a record pointing at nothing that a subsequent create could double-book. Bindings (`bindWorktreeSession`) also use `flush()` — low-frequency, and a lost binding degrades to a resume in the wrong cwd.
|
|
249
|
+
|
|
250
|
+
#### 5.1.3 Management-stream RPCs
|
|
251
|
+
|
|
252
|
+
Add a new management purpose rather than widening the existing `unregister_workspace` stream, keeping the one-purpose-per-stream property the protocol doc promises ("Discovery and management payloads reject unknown purposes and unexpected fields", `docs/iroh-remote-protocol.md:76-82`).
|
|
253
|
+
|
|
254
|
+
`handshake.ts`:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
export interface IrohRemoteWorkspaceManagementTarget {
|
|
258
|
+
purpose: "unregister_workspace" | "manage_worktrees"; // widened union
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`parseWorkspaceManagementTarget` (handshake.ts:479-491) accepts `"manage_worktrees"` in addition to `"unregister_workspace"`; the response-side `parseWorkspaceManagementResponseMetadata` is widened symmetrically. Old daemons reject `manage_worktrees` hellos with `invalid_conversation_target` — which is exactly why clients must gate on `worktrees.v1` (§5.1.8) before opening the stream.
|
|
263
|
+
|
|
264
|
+
New commands on the `manage_worktrees` stream (`src/daemon/workspace-streams.ts`, new `runWorktreeManagementStream` alongside `runWorkspaceManagementStream`, same JSONL framing, same strict-parse conventions as `parseWorkspaceManagementUnregisterRequest`):
|
|
265
|
+
|
|
266
|
+
**create_worktree**
|
|
267
|
+
|
|
268
|
+
```jsonc
|
|
269
|
+
// request — field allowlist: id, type, workspaceName, worktreeName?, branch?, baseRef?
|
|
270
|
+
{"id":"1","type":"create_worktree","workspaceName":"myrepo","worktreeName":"fix-login","baseRef":"main"}
|
|
271
|
+
|
|
272
|
+
// success (createRpcSuccessResponse shape) — NOTE: no filesystem paths on the wire
|
|
273
|
+
{"id":"1","type":"response","command":"create_worktree","success":true,
|
|
274
|
+
"data":{"worktree":{"id":"fix-login","branch":"volt/fix-login","baseRef":"main","createdAt":1751900000000,"sessionIds":[]}}}
|
|
275
|
+
|
|
276
|
+
// failure (createIrohRemoteRpcErrorResponse shape)
|
|
277
|
+
{"id":"1","type":"response","command":"create_worktree","success":false,"error":"worktree_branch_conflict"}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**list_worktrees**
|
|
281
|
+
|
|
282
|
+
```jsonc
|
|
283
|
+
{"id":"2","type":"list_worktrees","workspaceName":"myrepo"}
|
|
284
|
+
|
|
285
|
+
{"id":"2","type":"response","command":"list_worktrees","success":true,
|
|
286
|
+
"data":{"worktrees":[
|
|
287
|
+
{"id":"fix-login","branch":"volt/fix-login","createdAt":1751900000000,
|
|
288
|
+
"sessionIds":["s-abc"],"available":true,"dirty":false}]}}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**remove_worktree**
|
|
292
|
+
|
|
293
|
+
```jsonc
|
|
294
|
+
// field allowlist: id, type, workspaceName, worktreeId, force?
|
|
295
|
+
{"id":"3","type":"remove_worktree","workspaceName":"myrepo","worktreeId":"fix-login","force":false}
|
|
296
|
+
|
|
297
|
+
{"id":"3","type":"response","command":"remove_worktree","success":true,
|
|
298
|
+
"data":{"worktreeId":"fix-login","removed":true,"stoppedRuntimeCount":1,"closedStreamCount":1}}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Validation rules, matching the unregister precedent exactly:
|
|
302
|
+
|
|
303
|
+
- `workspaceName` must equal `authorization.workspace.name` → else `session_mismatch`.
|
|
304
|
+
- Any field outside the allowlist → `invalid_request`.
|
|
305
|
+
- Commands other than the three above → `unsupported_on_workspace_management_stream` (reuse the existing error string; the stream *is* a workspaceManagement stream).
|
|
306
|
+
- No `path` field is accepted anywhere; a request carrying one is `invalid_request`.
|
|
307
|
+
- `remove_worktree` with active runtimes bound to the worktree: without `force` → `worktree_busy`; with `force`, stop those runtimes via `IntegratedRuntimeRegistry.stopEntry` first (mirroring `cleanupUnregisteredWorkspace`, `iroh-service.ts:1631-1651`), then `git worktree remove --force`.
|
|
308
|
+
|
|
309
|
+
Each command writes an audit event (`src/core/remote/iroh/audit.ts:4-12` free-form shape): `{type:"worktree_created"|"worktree_removed"|"worktree_pruned", clientNodeId, workspace:<name>, success, details:{worktreeId, branch?, force?, stoppedRuntimeCount?}}`.
|
|
310
|
+
|
|
311
|
+
The pure-state RPC helpers live in a new `src/core/remote/iroh/worktree-rpc.ts` mirroring `workspace-rpc.ts:44-94` (`handleIrohRemoteWorktreeRpcCommand` handling all three types), so the conversation-stream dispatch (`handleRemoteHostRpcCommand`, `src/daemon/conversation-commands.ts:1433-1482`) and the relay path can reuse them later if we choose to also expose these on conversation streams (Open Question 1).
|
|
312
|
+
|
|
313
|
+
#### 5.1.4 Handshake extension: `target:"new"` into a worktree
|
|
314
|
+
|
|
315
|
+
Phase 1 deliberately requires the worktree to be **created first** via `create_worktree` and only *referenced* at conversation open. Creating a worktree inline during the handshake would put a multi-second `git worktree add` inside `DEFAULT_IROH_REMOTE_HANDSHAKE_TIMEOUT_MS` — rejected.
|
|
316
|
+
|
|
317
|
+
```jsonc
|
|
318
|
+
{"type":"volt_iroh_hello","protocol":"volt-rpc/0","workspace":"myrepo",
|
|
319
|
+
"conversation":{"target":"new","worktreeId":"fix-login"}}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Type change (`handshake.ts:18-28`):
|
|
323
|
+
|
|
324
|
+
```ts
|
|
325
|
+
export type IrohRemoteConversationTarget =
|
|
326
|
+
| { target: "last" }
|
|
327
|
+
| { target: "new"; worktreeId?: string }
|
|
328
|
+
| { target: "session"; sessionId: string };
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
`parseConversationTarget` changes (handshake.ts:438-462):
|
|
332
|
+
|
|
333
|
+
- Widen the allowlist: `expectKnownFields(target, "handshake conversation", ["target", "sessionId", "worktreeId"])`.
|
|
334
|
+
- `worktreeId` is permitted **only** when `target === "new"`; on `"last"`/`"session"` it throws `invalid_conversation_target` ("… must not include worktreeId") — resume targets derive the worktree from the persisted binding, never from the client, so a client cannot re-point an existing session at a different checkout.
|
|
335
|
+
- `worktreeId` must be a string matching `WORKTREE_ID_PATTERN` (add `expectWorktreeId` beside `expectRemoteSessionId`, handshake.ts:513-522).
|
|
336
|
+
|
|
337
|
+
Success-response metadata (`IrohRemoteConversationHandshakeMetadata`, handshake.ts:32-37) gains optional `worktreeId?: string`, and the response-side allowlist in `parseOptionalHandshakeSuccessMode`'s `conversation` check (`expectKnownResponseFields`) is widened to include it. Old clients that parse responses strictly never see the field because they never send worktree hellos (the daemon echoes `worktreeId` only for worktree-bound conversations, and only worktree-capable clients can create those).
|
|
338
|
+
|
|
339
|
+
**Failure outcomes.** `IROH_REMOTE_OUTCOMES` (`protocol.ts:19-37`) is a closed enum on both sides, so Phase 1 does **not** add a new outcome value. An unknown/unavailable `worktreeId` on `target:"new"` fails with the existing `invalid_conversation_target`; a resume whose bound worktree checkout has vanished fails with the existing `session_unavailable`. A dedicated `worktree_unavailable` outcome is deferred to a later protocol revision (Open Question 3).
|
|
340
|
+
|
|
341
|
+
#### 5.1.5 cwd plumbing
|
|
342
|
+
|
|
343
|
+
Exact touch points:
|
|
344
|
+
|
|
345
|
+
1. **`IntegratedRuntimeRegistry`** (`src/daemon/integrated-runtimes.ts`):
|
|
346
|
+
- `IntegratedRuntimeRegistryOptions` gains `resolveWorktree: (workspaceName: string, hello: IrohRemoteHello, targetSessionId: string | undefined) => Promise<IrohRemoteWorkspaceWorktree | undefined>` and `bindWorktreeSession(...)` seams, wired to the `WorktreeManager` in `IrohDaemonService` (constructor wiring at `iroh-service.ts:349-366`).
|
|
347
|
+
- `createEntry` (lines 218-260): before building the runtime, resolve the worktree —
|
|
348
|
+
- `hello.conversation.target === "new"` with `worktreeId` → `resolveWorktree` must return that record (available on disk) or throw `createConversationOpenError("invalid_conversation_target", …)`;
|
|
349
|
+
- `target === "session"` / `"last"` with a resolved id → `findWorktreeForSession(workspaceName, targetSessionId)`.
|
|
350
|
+
- The factory call becomes:
|
|
351
|
+
```ts
|
|
352
|
+
const runtimeResult = await (this.options.createRuntime ?? createIrohRemoteAgentRuntimeWithSessionSelection)({
|
|
353
|
+
agentDir: this.options.agentDir,
|
|
354
|
+
allowTools: this.options.getAllowTools(authorization.workspace) ?? authorization.allowTools,
|
|
355
|
+
conversationTarget: createIrohRuntimeConversationTarget(handshake.hello, authorization),
|
|
356
|
+
cwd: worktree?.path ?? authorization.workspace.path, // CHANGED
|
|
357
|
+
sessionDir: getDefaultSessionDir(authorization.workspace.path, this.options.agentDir), // NEW — always parent-keyed
|
|
358
|
+
onSubagentRuntimeCreated: (event) => this.registerSubagentRuntime(event, authorization),
|
|
359
|
+
profile: this.options.profile,
|
|
360
|
+
projectTrusted: this.options.getProjectTrustedForWorkspace(authorization.workspace), // unchanged: parent path
|
|
361
|
+
});
|
|
362
|
+
```
|
|
363
|
+
Note `sessionDir` is now passed for *all* daemon runtimes (worktree or not); for the non-worktree case it is identical to today's derived default, so behavior is unchanged.
|
|
364
|
+
- After a `created` selection for a worktree conversation, call `bindWorktreeSession(workspaceName, worktree.id, sessionId)`. `IntegratedRuntimeEntry` gains `worktreeId?: string` for cleanup/audit.
|
|
365
|
+
2. **`createIrohRemoteAgentRuntimeWithSessionSelection`** (`src/modes/rpc/iroh-remote-agent-runtime.ts`): **no changes needed** — the existing `sessionDir` option (line 37) already flows to `createSessionManagerTargetStore(options.cwd, options.sessionDir ?? …)` (lines 168-176), and `SessionManager.create(cwd, sessionDir)` / `open(path, sessionDir, cwd)` (`session-target.ts:100-118`) already produce worktree-cwd headers inside the parent dir.
|
|
366
|
+
3. **Relay preamble resolution** (`iroh-service.ts:1055-1068`): before `resolveIrohRemoteSessionTarget`, look up `findWorktreeForSession`; when bound, build the store as `createSessionManagerTargetStore(worktree.path, getDefaultSessionDir(authorization.workspace.path, this.services.agentDir))`. (The `filterCwd` behavior of `SessionManager.list` — custom dir + non-matching cwd ⇒ filter by header cwd, `session-manager.ts:1570-1576` — then correctly restricts resolution to that worktree's sessions.)
|
|
367
|
+
4. **Sanitizer** (`getRemoteSanitizerOptions`, `workspace-streams.ts:64-72`, and the conversation path at `iroh-service.ts:1439-1441`): for worktree-bound streams, `workspacePath` becomes `worktree.path` (so `cwd`/`path` strict fields map to `/workspace`), **and** the parent `workspace.path` must still be redacted (bash output can mention it via `git worktree list`, `.git` gitdir pointers, etc.). Extend `IrohRemoteOutboundSanitizerOptions` (`outbound-filter.ts:28-32`) with `additionalRedactedPaths?: string[]`; `createSanitizerContext` folds their normalization/separator variants into `workspacePathVariants` (all mapping to `remoteWorkspacePath`).
|
|
368
|
+
5. **Availability validation:** `authorizeClient`'s `validateWorkspace` hook (`state-manager.ts:163-186`) stays parent-based; worktree availability is checked at conversation open in `createEntry` (a missing checkout is an open-time failure, not an authorization failure, so discovery/management streams keep working while a worktree is broken).
|
|
369
|
+
|
|
370
|
+
#### 5.1.6 Lifecycle interactions
|
|
371
|
+
|
|
372
|
+
- **Workspace unregister:** refuse before changing state when any persisted child worktree exists. The stable conflict is `workspace_has_worktrees`; clients show the worktrees and require explicit `remove_worktree` operations. Dirty, unmerged, busy, missing-checkout, and clean records all block equally, so the state layer never needs to infer whether data is disposable. Per-worktree `force:true` remains the only destructive opt-in and stops bound runtimes first. Once no records remain, unregister may close streams/runtimes and remove workspace-scoped Live Activity/relay state, but it never removes the workspace worktrees directory or unknown/orphan checkout directories. The retained `cleanupUnregisteredWorkspace` compatibility guard is inspection/audit-only and performs no git or filesystem mutation.
|
|
373
|
+
- **Detached-runtime retention** (`integrated-runtimes.ts:735-760` sweep): Phase 1 does **not** delete worktrees when a runtime is swept — the checkout may hold uncommitted work; the sessionId→worktree binding persists so the session can be resumed later into the same worktree. Cleanup policy is Phase 3.
|
|
374
|
+
- **`lastSessionIdByWorkspace`** (`state.ts:57`, consumed at `integrated-runtimes.ts:100-116`): unchanged. `target:"last"` may resolve to a worktree-bound session; the binding lookup in §5.1.5(1) makes that resume land in the worktree. This is by design (last means last).
|
|
375
|
+
- **Push notifications / live activities:** keyed `{workspaceName, sessionId}` — no change needed.
|
|
376
|
+
|
|
377
|
+
#### 5.1.7 Session-dir keying decision (normative)
|
|
378
|
+
|
|
379
|
+
**Decision: worktree sessions are stored in the parent workspace's default session dir (`getDefaultSessionDir(workspace.path, agentDir)`) with `header.cwd = worktree.path`.**
|
|
380
|
+
|
|
381
|
+
Rationale:
|
|
382
|
+
|
|
383
|
+
- `list_sessions` uses `SessionManager.list(workspace.path, getDefaultSessionDir(workspace.path, agentDir))` (`conversation-commands.ts:984-990`); because that dir equals `getDefaultSessionDirPath(workspace.path)` when `agentDir` matches the env-aware default, `filterCwd` is false and worktree sessions **appear in the workspace's session list with zero changes**. The alternative (letting `getDefaultSessionDirPath` encode the worktree cwd) makes worktree sessions permanently invisible to the app.
|
|
384
|
+
- `target:"session"` resume works: the daemon consults the persisted binding first, then opens with `SessionManager.open(path, parentDir, worktree.path)` — never trusting the header alone, so a deleted-then-recreated worktree at the same path is fine, and a *missing* worktree fails deterministically instead of resurrecting a dead cwd (which is what bare `SessionManager.open`'s header-cwd default would do, session-manager.ts:1477).
|
|
385
|
+
- `lastSessionIdByWorkspace` and lease/registry keys stay `(workspaceName, sessionId)`.
|
|
386
|
+
- No wire change: `RemoteSessionListEntry` carries no paths (`conversation-commands.ts:953-970`). Worktree attribution in the list UI comes from `list_worktrees.sessionIds`, not from the session list (a `worktreeId` field on the session summary is a compatible later addition since the summary is host-constructed).
|
|
387
|
+
|
|
388
|
+
Caveat to document: `SessionManager.list`'s `filterCwd` compares against `getDefaultSessionDirPath(cwd)` with the *default* agentDir; a caller passing a non-default `agentDir` inconsistent with `$VOLT_CODING_AGENT_DIR` would flip the filter on and hide worktree sessions. The daemon always uses `services.agentDir` = env-aware `getAgentDir()`, so this is a latent footgun, not a live bug; a Phase 1 test pins it.
|
|
389
|
+
|
|
390
|
+
#### 5.1.8 Capability flag
|
|
391
|
+
|
|
392
|
+
`src/core/remote/iroh/protocol.ts:5-10`:
|
|
393
|
+
|
|
394
|
+
```ts
|
|
395
|
+
export const IROH_REMOTE_WORKTREES_FEATURE = "worktrees.v1";
|
|
396
|
+
export const IROH_REMOTE_HOST_FEATURES = [
|
|
397
|
+
IROH_REMOTE_MULTI_STREAMS_FEATURE,
|
|
398
|
+
IROH_REMOTE_CONVERSATION_STREAMS_FEATURE,
|
|
399
|
+
IROH_REMOTE_WORKTREES_FEATURE,
|
|
400
|
+
] as const;
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
This flows automatically into every handshake success (`engine.createHandshakeSuccessResponse`, `src/core/remote/iroh/engine.ts:478-496`) and `remoteHost` metadata (`metadata.ts:31-43`). **Do not** add it to `assertRequiredHandshakeFeatures` (handshake.ts:629-638) — it is optional. Clients must check for `worktrees.v1` before (a) sending `worktreeId` in a hello or (b) opening a `manage_worktrees` stream; old hosts reject both with `invalid_conversation_target`.
|
|
404
|
+
|
|
405
|
+
A later `worktrees.v2` can add inline-create or new outcomes.
|
|
406
|
+
|
|
407
|
+
#### 5.1.9 Trust and allowedTools inheritance (normative)
|
|
408
|
+
|
|
409
|
+
**Rule: a worktree runtime uses exactly the parent workspace's policy. It can never be wider.**
|
|
410
|
+
|
|
411
|
+
- `allowTools`: unchanged call `this.options.getAllowTools(authorization.workspace)` (`integrated-runtimes.ts:227`) — the workspace record *is* the parent; there is no per-worktree `allowedTools` field, deliberately.
|
|
412
|
+
- `projectTrusted`: unchanged call `getProjectTrustedForWorkspace(authorization.workspace)` (`integrated-runtimes.ts:232` → `host-policy.ts:15-29`), i.e. trust is always evaluated against **`workspace.path`**, never the worktree checkout path. The worktree contains a branch of the same repository the user already made a trust decision about; evaluating `hasTrustRequiringProjectResources` against a path under `~/.volt/agent/worktrees` would walk `~/.volt/agent` ancestors, which is meaningless, and would invite trust prompts the daemon cannot surface.
|
|
413
|
+
- Corollary: **never write trust.json entries for worktree paths** (an entry for `~/.volt/agent/worktrees` would, via `findNearestTrustEntry`'s ancestor walk, blanket-trust every future worktree of every workspace).
|
|
414
|
+
- Known asymmetry, accepted: a *branch* checked out in a worktree could contain a `.mcp.json`/`.volt` config that the trunk (against which trust was decided) does not. This is identical in kind to `git checkout <branch>` in the main checkout today, which also does not re-prompt. Documented in Security (§7), not mitigated in Phase 1.
|
|
415
|
+
|
|
416
|
+
#### 5.1.10 CLI: `volt remote worktree …`
|
|
417
|
+
|
|
418
|
+
New control requests (`src/daemon/control-protocol.ts` `ControlRequest` union, beside `workspace_register` at line 67) and handlers in `src/daemon/main.ts` (beside `workspace_register` at line 308):
|
|
419
|
+
|
|
420
|
+
```ts
|
|
421
|
+
| { type: "worktree_create"; id: string; workspaceName: string; worktreeName?: string; branch?: string; baseRef?: string }
|
|
422
|
+
| { type: "worktree_list"; id: string; workspaceName?: string }
|
|
423
|
+
| { type: "worktree_remove"; id: string; workspaceName: string; worktreeId: string; force?: boolean }
|
|
424
|
+
| { type: "worktree_prune"; id: string; workspaceName?: string }
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
`src/daemon/remote-cli.ts` gains a `worktree` command group in `handleRemoteControlCommand`'s switch and `printRemoteUsage`:
|
|
428
|
+
|
|
429
|
+
```
|
|
430
|
+
volt remote worktree add [--workspace <name>] [--name <id>] [--branch <ref>] [--base <ref>]
|
|
431
|
+
volt remote worktree list [--workspace <name>] [--json]
|
|
432
|
+
volt remote worktree remove <id> [--workspace <name>] [--force]
|
|
433
|
+
volt remote worktree prune [--workspace <name>]
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
`--workspace` defaults via the same cwd-prefix match used by `handlePairCommand` (remote-cli.ts:118-137). The control plane is local-socket-only (trusted user), so responses *may* include checkout paths for display — the no-paths rule applies to the iroh wire, not the control socket.
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### 5.2 Phase 2 — TUI
|
|
441
|
+
|
|
442
|
+
#### 5.2.1 New session into a worktree from the TUI
|
|
443
|
+
|
|
444
|
+
Flow: TUI issues `worktree_create` over the control socket (daemon must be running; if not, offer to start it, reusing `ensureDaemonRunning`), then starts a **new local session with an explicit cwd override** equal to the worktree path and `sessionDir = getDefaultSessionDir(<parent path>)`.
|
|
445
|
+
|
|
446
|
+
Implementation surface: the TUI's runtime today uses its own process cwd. `SessionManager.create(cwd, sessionDir)` supports arbitrary cwd/sessionDir (session-manager.ts:1461-1464), and `interactive-mode.ts` constructs its session manager at startup — the change is threading an optional `{ cwd, sessionDir }` override through interactive-mode session creation and the `/worktree new` command UI. **Phase 2 requires an audit of every cwd consumer inside interactive mode (footer git status, extension discovery, `.volt` settings resolution).** Settings/trust note: `SettingsManager.create(worktreePath, …)` will read the worktree's `.volt` project settings — same content as the repo branch; trust must again be pinned to the parent path (the TUI trust prompt flow should recognize daemon-managed worktree paths via `worktree_resolve`, below, and skip re-prompting by reusing the parent decision).
|
|
447
|
+
|
|
448
|
+
#### 5.2.2 Fixing the auto-registration trap
|
|
449
|
+
|
|
450
|
+
`createDaemonAttach.resolveWorkspace` (daemon-attach.ts:192-229) prefix-matches the TUI cwd against workspace paths and otherwise **auto-registers a new workspace**. A TUI launched inside `~/.volt/agent/worktrees/--…--/fix-login` would silently mint a bogus workspace, splitting lease keys from the daemon's worktree conversations.
|
|
451
|
+
|
|
452
|
+
Fix: add control request `{ type: "worktree_resolve"; id: string; path: string }` → `{ workspaceName, worktreeId } | not_found`. `resolveWorkspace` calls it before the auto-register fallback; on a hit, it uses the **parent workspace name** for `lease_acquire`, so lease keys stay `(parentWorkspaceName, sessionId)` and co-attach/relay work identically to main-checkout sessions.
|
|
453
|
+
|
|
454
|
+
#### 5.2.3 Lease takeover with the worktree cwd
|
|
455
|
+
|
|
456
|
+
- **Session file reload (warm/cold handoff, `interactive-mode.ts:1824-1841`):** the session header cwd *is* the worktree path, so `SessionManager.open` without override already yields the worktree cwd. The TUI must additionally verify the checkout exists and refuse takeover with a clear error when it does not (rather than resurrecting a ghost cwd — session-manager.ts:1477 behavior).
|
|
457
|
+
- **Relay serving after takeover:** the TUI builds its serving authorization from `RelayPreamble.authorization` and passes `workspacePath` into `runIrohRemoteRpcMode` (interactive-mode.ts:1973-1990, 2027-2033) — sanitization would use the parent path while the runtime emits worktree paths, leaking host paths to the phone. Extend `RelayPreamble` (`control-protocol.ts:219-244`):
|
|
458
|
+
```ts
|
|
459
|
+
authorization: { clientNodeId: string; workspaceName: string; workspacePath: string;
|
|
460
|
+
worktreeId?: string; worktreePath?: string };
|
|
461
|
+
resolvedTarget: { /* existing fields */; worktreeId?: string };
|
|
462
|
+
```
|
|
463
|
+
and `runIrohRemoteRpcMode`'s options gain the same `additionalRedactedPaths` extension from §5.1.5(4) with `workspacePath = worktreePath ?? workspacePath`. Compatibility: control-plane `PROTOCOL_VERSION` stays 1 — new optional fields on the preamble are additive. Add a `worktrees` capability to the control `HelloMessage` (control role) so the daemon can gate relay offers per TUI; an old TUI simply never receives relays for worktree sessions (the daemon serves them itself).
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
### 5.3 Phase 3 — polish
|
|
468
|
+
|
|
469
|
+
1. **Merge-back UX.** Non-mutating guidance surfaces:
|
|
470
|
+
- `list_worktrees` response gains `aheadBehind: { ahead: number; behind: number }` (computed with `git rev-list --left-right --count`, same runner). *Implementation note:* the separately proposed `hasUncommitted` field was consolidated into the existing Phase 1 `dirty` field — both are `git status --porcelain` non-empty, and shipping two names for one fact would be redundant. To make the base ref stable for later guidance, `create` resolves a defaulted base to the main checkout's current branch name (falling back to its commit sha) and persists it.
|
|
471
|
+
- CLI `volt remote worktree diff <id>` (control-plane only) prints `git -C <checkout> diff <baseRef>...HEAD` locally.
|
|
472
|
+
- App/TUI affordance text: suggested `git merge volt/<id>` / `git push -u origin volt/<id>` + PR instructions. Actual merges/pushes remain user actions in a shell or agent session — the daemon never mutates the main checkout.
|
|
473
|
+
2. **Cleanup policies** (all opt-in, persisted in `VoltdStateFileV1.settings`):
|
|
474
|
+
```ts
|
|
475
|
+
settings: { /* existing */; worktreeCleanup?: {
|
|
476
|
+
retention?: { enabled: boolean; ttlMs: number }; // clean worktrees only
|
|
477
|
+
pruneOnStart?: boolean } } // default true
|
|
478
|
+
```
|
|
479
|
+
*Implementation note:* the proposed `onSessionDelete` policy was deferred — the daemon has no session-deletion surface (no `delete_session` RPC or control command) to hook it to. Add it alongside whatever session-deletion surface lands first.
|
|
480
|
+
- Retention sweep hooks `onRuntimeDisposed` (`integrated-runtimes.ts:75`, wired at `iroh-service.ts:364-365`) → schedule a worktree TTL; on expiry, remove **only if clean** (`git status --porcelain` empty and branch fully merged into `baseRef`), else audit `worktree_retention_skipped_dirty`.
|
|
481
|
+
- `pruneOnStart`: run `WorktreeManager.prune` for every workspace during daemon startup (after state load, before endpoint bind), reconciling records ↔ filesystem ↔ `git worktree list --porcelain`; quarantine unrecognized directories under the worktrees root by renaming to `<dir>.orphan-<ts>` (never delete unrecognized content destructively).
|
|
482
|
+
3. **App affordances** (iOS side, out of this repo's scope but protocol-relevant): worktree picker on new-session, worktree badge in session list (join `list_worktrees.sessionIds`), dirty indicator, remove-with-confirmation.
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## 6. Failure modes and edge cases
|
|
487
|
+
|
|
488
|
+
| Case | Behavior |
|
|
489
|
+
|---|---|
|
|
490
|
+
| **Non-git workspace** | `create_worktree` → `not_a_git_repository` (from `rev-parse --git-common-dir` failure). Conversation `target:"new"` without `worktreeId` is unaffected. |
|
|
491
|
+
| **Bare repo / repo with no commits** | `worktree add -b … HEAD` fails → `git_failed` with stderr detail (sanitized: strip absolute paths before putting stderr in RPC detail). |
|
|
492
|
+
| **Branch name conflict** | `git worktree add -b` refuses existing branches → map to `worktree_branch_conflict`; client may retry with explicit `branch`. No auto-suffixing (surprise branches are worse than an error). Duplicate `worktreeId` → `worktree_exists` (checked against state *and* filesystem before git runs). |
|
|
493
|
+
| **Dirty / locked worktree on remove** | `git worktree remove` refuses dirty/locked → `worktree_dirty` (no force) with `dirty:true` detail; `--force` path stops bound runtimes first (§5.1.3). Locked worktrees (`git worktree lock`) surface as `git_failed` detail; we never auto-unlock. |
|
|
494
|
+
| **Workspace unregister with child worktrees** | Refuse atomically with `workspace_has_worktrees`. Preserve the workspace record, every child record, all runtimes/checkouts, and unknown directories. The user lists and removes children individually; only per-worktree `force:true` can discard dirty or busy work. |
|
|
495
|
+
| **Worktree deleted out-of-band** | `list_worktrees` reports `available:false`. Conversation open referencing it → `invalid_conversation_target` (new) / `session_unavailable` (resume). `prune` drops the record and runs `git worktree prune` to clear the stale gitdir entry. Session files remain (parent dir) and can be viewed read-only. |
|
|
496
|
+
| **Daemon crash mid-create** | Order is: git add (idempotent-checkable) → state record → `flush()`. Crash before flush leaves an orphan checkout + branch, reconciled by `pruneOnStart` (which detects checkouts with no record and quarantines/adopts per policy). Crash after flush is fully consistent. |
|
|
497
|
+
| **Debounced-write loss** | Bindings written debounced could lose ≤250 ms on hard kill (`DEFAULT_STATE_DEBOUNCE_MS`, state.ts:180); a lost binding degrades to "resume lands in the parent cwd" — wrong but safe. Mitigation: `bindWorktreeSession` uses `flush()`, since it's low-frequency. |
|
|
498
|
+
| **Windows** | Checkout paths under `%USERPROFILE%\.volt\agent\worktrees\--…--\<id>` can approach MAX_PATH with the encoded workspace path; mitigate by hashing the encoded segment when it exceeds ~80 chars (`--<prefix>-<sha1-8>--`). Use `spawnProcess` (cross-spawn on win32). `git worktree` requires `core.longpaths` for deep repos — surface the git error verbatim in `detail`. Path-containment checks must compare case-insensitively on win32 and use `path.sep`-aware prefix checks. The sanitizer already generates both separator variants (outbound-filter.ts:131-140). |
|
|
499
|
+
| **Untracked deps (`node_modules`, venvs, build caches)** | Worktrees share git objects but not untracked files: a fresh worktree has no `node_modules`. Phase 1: documented limitation + `create_worktree` response is fast precisely because we do **not** bootstrap. Phase 3 open question: optional post-create hook (`.volt/worktree-init` script) — deliberately *not* proposed now because it executes repo-controlled code and interacts with trust (§7). |
|
|
500
|
+
| **Concurrent creates, same id** | State-manager operation queue (`runExclusive`) serializes record insertion; second create sees the record → `worktree_exists` before touching git. |
|
|
501
|
+
| **`git` missing / launchd PATH** | A service-installed daemon may have a minimal PATH. `WorktreeManager` resolves git once at first use (`spawnProcess("git", ["--version"])`), caches the result, and returns `git_failed` with a "git not found on daemon PATH; see docs/daemon.md" detail. Verification item for Phase 1: test under `launchctl`-spawned voltd (`service-install.ts` env). |
|
|
502
|
+
| **Worktree of a worktree / registered workspace is itself a worktree** | `--git-common-dir` resolves to the main repo; git handles this natively. No special-casing, but add a test. |
|
|
503
|
+
| **Session forked/branched (`SessionManager.forkFrom`)** | Fork rewrites header cwd to the target cwd (session-manager.ts:1509-1560); a fork of a worktree session into the parent cwd detaches from the worktree by construction — acceptable. |
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## 7. Security considerations
|
|
508
|
+
|
|
509
|
+
1. **Path containment.** The iroh wire never carries filesystem paths inbound: `create_worktree`/`remove_worktree` accept ids/refs only; checkout paths are computed solely by `getWorktreeCheckoutPath` with pattern-validated ids and a resolve-plus-prefix assertion under `getWorktreesRoot`. Any request containing `path`/`workspacePath` fields is `invalid_request` (same defense `workspace-rpc.ts:96-100` uses today).
|
|
510
|
+
2. **No argv/shell injection.** All git calls use `spawnProcess(command, argsArray)` — no shell. `branch`/`baseRef` are syntax-validated (reject leading `-` to prevent option injection, plus ref-format checks) and always passed as separate argv entries.
|
|
511
|
+
3. **No policy widening.** §5.1.9: parent `allowTools`, parent trust, no per-worktree overrides, no trust.json writes for worktree paths. The daemon settings `allowTools` override (`iroh-service.ts:429-435`) continues to dominate.
|
|
512
|
+
4. **Branch-content trust gap (accepted risk).** A worktree checks out a branch whose `.volt`/`.mcp.json` may differ from what was trusted. Equivalent to in-place `git checkout`; called out in docs. Mitigation lever if needed later: evaluate `hasTrustRequiringProjectResources(worktree.path)` and *deny* (not prompt) when the worktree introduces trust-requiring resources absent from the parent — deferred, since it produces false positives on any repo that already has them.
|
|
513
|
+
5. **Outbound path hygiene.** Worktree streams sanitize with root = worktree path **and** `additionalRedactedPaths = [workspace.path, getWorktreesRoot(agentDir)]`, so neither the parent checkout path nor the agent-dir layout leaks (bash output like `git worktree list` prints both). Git stderr embedded in RPC `detail` fields passes through the same sanitizer because `writeIrohRemoteJsonLine` already sanitizes every frame (workspace-streams.ts:74-82).
|
|
514
|
+
6. **Filesystem hygiene.** `worktrees/` root created 0700 (matching `ensureDaemonDirs`, `paths.ts:58-65`). Prune never deletes unrecognized directories destructively (quarantine-rename, mirroring the state-file `.corrupt-<ts>` pattern, state.ts:259-272). Workspace unregister never invokes git removal or recursive deletion; it refuses while records exist and preserves unknown/orphan directories even after an empty workspace is unregistered.
|
|
515
|
+
7. **Resource limits.** `maxWorktreesPerWorkspace` (default 16) → `worktree_limit_reached`; prevents a paired phone from filling the disk with checkouts. Audit every create/remove with client node id.
|
|
516
|
+
8. **Session pinning.** Resume targets ignore client-supplied worktree hints entirely (§5.1.4); a client cannot redirect an existing session into a different checkout to exfiltrate files outside its sanitizer root.
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## 8. Backward / forward compatibility
|
|
521
|
+
|
|
522
|
+
| Surface | Old client/state → New daemon | New client/state → Old daemon |
|
|
523
|
+
|---|---|---|
|
|
524
|
+
| **State file** | `parseIrohRemoteHostState` reads missing `worktrees` as `[]` via `parseOptionalArray` — old files load cleanly; `version` stays 1. | Old daemon reading a new file: parsers copy only known keys, so `worktrees` is **silently dropped and lost on the next write**. Checkouts survive on disk as orphans; a re-upgrade's `pruneOnStart` quarantines them. Documented downgrade caveat; no schema-version bump (rejecting the file outright would be worse). |
|
|
525
|
+
| **Handshake** | Old app + new daemon: identical hellos, identical parses; `worktrees.v1` in `features` is ignored by old clients (the features list is already open-ended and clients treat unknown entries as inert capabilities). | New app + old daemon: the app must gate on `worktrees.v1`; a gating client never sends `worktreeId` or `manage_worktrees`. A non-gating client gets a deterministic `invalid_conversation_target` handshake error. |
|
|
526
|
+
| **Management stream** | Existing successful `unregister_workspace` frames are unchanged; a workspace with child worktrees now returns the stable `workspace_has_worktrees` conflict. | `manage_worktrees` hello → `invalid_conversation_target` on old daemons (same gate as above). |
|
|
527
|
+
| **Conversation resume** | Old app can resume a worktree-bound session by id; the daemon resolves the binding server-side and the app transparently runs in the worktree (paths sanitized to `/workspace` either way). | After a daemon downgrade, worktree records are gone; resuming such a session opens with the session header cwd (the worktree path). If the checkout still exists it works incidentally; if not, the open fails. Documented. |
|
|
528
|
+
| **Control socket / relay** | Old TUI + new daemon: `RelayPreamble` additions are optional fields; old TUIs are never offered worktree-session relays (gated on the TUI's control-hello `worktrees` capability). | New TUI + old daemon: `worktree_*` control requests get the daemon's standard unknown-request error; the CLI prints "daemon does not support worktrees; restart/upgrade voltd". `PROTOCOL_VERSION` stays 1. |
|
|
529
|
+
| **CLI** | n/a | `volt remote worktree …` against an old daemon surfaces the unknown-request error above. |
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## 9. Testing strategy
|
|
534
|
+
|
|
535
|
+
Repo conventions: targeted vitest runs from the package root (`node ../../node_modules/vitest/dist/cli.js --run test/<file>.test.ts`), `./test.sh` from the repo root for the non-e2e suite, `npm run check` after code changes. No real git required for unit tests — inject `runGit`; one integration test uses a real temp git repo.
|
|
536
|
+
|
|
537
|
+
### Phase 1
|
|
538
|
+
|
|
539
|
+
- **`test/daemon-worktree-manager.test.ts`** — unit tests with a fake `WorktreeGitRunner`: create success/limit/duplicate-id/branch-conflict/non-git mappings; remove dirty/busy/force ordering (runtimes stopped before git); prune reconciliation (record-without-checkout, checkout-without-record → quarantine); path containment (`getWorktreeCheckoutPath` rejects ids failing `WORKTREE_ID_PATTERN`, traversal attempts, and asserts the worktrees-root prefix); ref syntax validation (leading `-`, invalid ref chars). Plus one **real-git integration test** (temp repo via `git init` + commit): create → list --porcelain agreement → dirty detection → remove.
|
|
540
|
+
- **Workspace unregister safety** — state-level and management-stream regressions pin `workspace_has_worktrees`; dirty, unmerged, busy, and stray checkout fixtures remain present; no git runner call or recursive deletion occurs; a normal empty workspace still unregisters successfully; failed attempts are audited with worktree ids/counts.
|
|
541
|
+
- **State round-trip** — extend the existing state tests: `parseIrohRemoteHostState`/`serializeIrohRemoteHostState`/`cloneHostState`/`voltdStateToHostState`/`hostStateToVoltdState` preserve `worktrees`; old files without the key parse to `[]`; malformed worktree entries fail parse with the standard error shape.
|
|
542
|
+
- **Handshake** — `parseConversationTarget`: `worktreeId` accepted on `new`, rejected on `last`/`session`, pattern-validated; response metadata round-trip with `worktreeId`; `worktrees.v1` present in `IROH_REMOTE_HOST_FEATURES` and absent from `assertRequiredHandshakeFeatures`.
|
|
543
|
+
- **Management stream** — mirror the existing `unregister_workspace` stream tests for the three new commands: allowlist violations → `invalid_request`; cross-workspace name → `session_mismatch`; unknown command → `unsupported_on_workspace_management_stream`; audit events written; no `path` fields in any success payload (assert recursively).
|
|
544
|
+
- **Runtime plumbing** — via the injectable `createRuntime` seam in `IntegratedRuntimeRegistryOptions`: worktree-bound `new` passes `cwd = worktree.path` and parent-keyed `sessionDir`; non-worktree `new` is byte-identical to today's options; resume of a bound session resolves the binding; missing checkout at open → `invalid_conversation_target`/`session_unavailable`; `bindWorktreeSession` called exactly once after `created`.
|
|
545
|
+
- **Session-dir pin test** — create a session with worktree cwd in the parent session dir, then assert `SessionManager.list(parentPath, parentDir)` includes it (pins the `filterCwd` footgun in §5.1.7).
|
|
546
|
+
- **Sanitizer** — `additionalRedactedPaths`: parent path and worktrees root redact to `/workspace` in strings and strict fields, both separator variants, NFC/NFD variants.
|
|
547
|
+
- **Control protocol / CLI** — `worktree_*` request parse/dispatch in `main.ts`; `remote-cli` argument handling (`--workspace` default via cwd-prefix match, `--json` output shape).
|
|
548
|
+
|
|
549
|
+
### Phase 2
|
|
550
|
+
|
|
551
|
+
- `worktree_resolve` control request: hit → parent workspace name used for `lease_acquire` (no auto-registration); miss → existing fallback preserved.
|
|
552
|
+
- TUI new-session-into-worktree: session created with worktree cwd + parent sessionDir; interactive-mode cwd consumers audited with regression tests for footer git status and settings resolution under an overridden cwd.
|
|
553
|
+
- Takeover: `RelayPreamble` round-trip with `worktreeId`/`worktreePath`; relay serving sanitizes with the worktree path as root and parent path redacted; takeover refused with a clear error when the checkout is missing.
|
|
554
|
+
- Old-TUI gating: daemon does not offer worktree-session relays to control clients without the `worktrees` capability.
|
|
555
|
+
|
|
556
|
+
### Phase 3
|
|
557
|
+
|
|
558
|
+
- Retention sweep: clean+merged worktree removed on TTL expiry; dirty or unmerged worktree skipped with `worktree_retention_skipped_dirty` audit.
|
|
559
|
+
- `pruneOnStart`: orphan checkout quarantined (renamed, not deleted); stale record dropped; recognized checkouts untouched.
|
|
560
|
+
- `aheadBehind`/`hasUncommitted` computation against a real temp repo.
|
|
561
|
+
- Settings parse/serialize round-trip for `worktreeCleanup`.
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
## 10. Rollout and phase acceptance criteria
|
|
566
|
+
|
|
567
|
+
### Phase 1 — daemon foundation
|
|
568
|
+
|
|
569
|
+
Accepted when:
|
|
570
|
+
1. `volt remote worktree add/list/remove/prune` work end-to-end against a running daemon on a real git workspace.
|
|
571
|
+
2. A paired client (or the iroh test harness) can `create_worktree` over a `manage_worktrees` stream and open a `target:"new"` conversation with `worktreeId`; the runtime's bash tool observes `pwd` = the worktree checkout; a second concurrent session in the same workspace without a worktree observes the main checkout.
|
|
572
|
+
3. Daemon restart + `target:"session"` resume of the worktree-bound session lands back in the worktree.
|
|
573
|
+
4. `list_sessions` shows worktree-bound sessions alongside normal ones; `volt daemon status` unchanged.
|
|
574
|
+
5. No frame on the iroh wire contains the worktree path, the parent path, or the agent dir (sanitizer tests + a manual grep of a captured stream).
|
|
575
|
+
6. Old state files load; a state file written by the new daemon loads in the previous release (worktrees dropped, nothing else lost).
|
|
576
|
+
7. `npm run check` and `./test.sh` pass.
|
|
577
|
+
|
|
578
|
+
### Phase 2 — TUI
|
|
579
|
+
|
|
580
|
+
Accepted when:
|
|
581
|
+
1. `/worktree new` (or equivalent picker) in the TUI creates a worktree via the daemon and opens a session running in it.
|
|
582
|
+
2. A TUI can take over a phone-opened worktree session (warm and cold); the footer shows the worktree cwd; relayed phone frames remain path-sanitized.
|
|
583
|
+
3. A TUI launched inside a daemon-managed worktree does not auto-register a bogus workspace.
|
|
584
|
+
4. Old TUI + new daemon and new TUI + old daemon both degrade per §8.
|
|
585
|
+
|
|
586
|
+
### Phase 3 — polish
|
|
587
|
+
|
|
588
|
+
Accepted when:
|
|
589
|
+
1. `list_worktrees` reports ahead/behind and dirty status; CLI `worktree diff` works.
|
|
590
|
+
2. Opt-in retention removes only clean, fully merged worktrees; audit records every removal and skip.
|
|
591
|
+
3. `pruneOnStart` reconciles records/filesystem/git without destroying unrecognized content.
|
|
592
|
+
4. `docs/daemon.md` and `docs/iroh-remote-protocol.md` updated (worktree section, RPC shapes, `worktrees.v1`, downgrade caveats).
|
|
593
|
+
|
|
594
|
+
Suggested flag strategy: none needed — the feature is inert unless a client creates a worktree, and `worktrees.v1` gates the wire surface.
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## 11. Open questions
|
|
599
|
+
|
|
600
|
+
1. **Conversation-stream exposure.** ~~Should `create_worktree`/`list_worktrees` also be accepted on conversation streams?~~ **Resolved: implemented.** Conversation streams (and the TUI-owned relay path via `RELAY_RPC_COMMAND_TYPES`) accept `create_worktree` and `list_worktrees`, dispatched through `handleRemoteHostRpcCommand` with the daemon's backend (`ConversationCommandContext.createWorktreeBackend`). `remove_worktree` stays management-stream-only.
|
|
601
|
+
2. **Inline create at handshake (`worktrees.v2`).** `{"target":"new","worktree":{"create":true,…}}` would save a round trip but puts git latency inside the handshake timeout. Revisit with a longer per-mode timeout or an async "creating" handshake state.
|
|
602
|
+
3. **Dedicated `worktree_unavailable` outcome.** `IROH_REMOTE_OUTCOMES` is a closed enum on both ends; adding a value breaks old clients that parse strictly. Bundle with the next protocol revision.
|
|
603
|
+
4. **Post-create bootstrap hook.** `.volt/worktree-init` (deps install) executes repo-controlled code under daemon identity — needs a trust story first. Phase 3+ at earliest.
|
|
604
|
+
5. **Worktree id slugs.** Generated default (`adjective-noun-nn`) vs. requiring an explicit name from clients. Current design: generated default, explicit override allowed.
|
|
605
|
+
6. **`worktreeId` on session summaries.** **Resolved: implemented.** `RemoteSessionListEntry.worktreeId` is joined from the persisted bindings in `listRemoteWorkspaceSessionSummaries` (ids only, best-effort). Attribution may be absent while a TUI owns the lease (the relay-side state manager has no worktree records).
|