(value: string | undefined, srcBaseDir: string)
| 97 | type CLIMode = "plan" | "exec"; |
| 98 | |
| 99 | function parseRuntimeConfig(value: string | undefined, srcBaseDir: string): RuntimeConfig { |
| 100 | if (!value) { |
| 101 | // Default to local for `mux run` (no worktree isolation needed for one-off) |
| 102 | return { type: "local" }; |
| 103 | } |
| 104 | |
| 105 | const parsed = parseRuntimeModeAndHost(value); |
| 106 | if (!parsed) { |
| 107 | throw new Error( |
| 108 | `Invalid runtime: '${value}'. Use 'local', 'worktree', 'ssh <host>', or 'docker <image>'` |
| 109 | ); |
| 110 | } |
| 111 | |
| 112 | switch (parsed.mode) { |
| 113 | case RUNTIME_MODE.LOCAL: |
| 114 | return { type: "local" }; |
| 115 | case RUNTIME_MODE.WORKTREE: |
| 116 | return { type: "worktree", srcBaseDir }; |
| 117 | case RUNTIME_MODE.SSH: |
| 118 | // STARTUP-PERF: Use a STABLE remote `srcBaseDir` (default: `~/mux`, |
| 119 | // matching the desktop app) instead of the CLI's ephemeral temp dir. |
| 120 | // |
| 121 | // The remote `baseRepoPath` is derived as |
| 122 | // <srcBaseDir>/<projectId>/.mux-base.git |
| 123 | // where `projectId` is keyed by the *local* project path. If |
| 124 | // `srcBaseDir` is ephemeral (a fresh `mux-run-*` temp dir per |
| 125 | // invocation), every CLI run gets a brand-new remote base repo even |
| 126 | // when running back-to-back against the same SSH host + project, so |
| 127 | // every run pays the full cold-init cost (git init, push, fetch, |
| 128 | // worktree-add ~2.2s). |
| 129 | // |
| 130 | // Anchoring `srcBaseDir` to the stable `~/mux` location lets the second |
| 131 | // and subsequent `mux run` invocations reuse the existing shared base |
| 132 | // repo on the remote, hitting the warm path |
| 133 | // (`Reusing existing remote project snapshot`) — a single bounded SSH |
| 134 | // round-trip instead of a full create + sync + push. |
| 135 | return { type: "ssh", host: parsed.host, srcBaseDir: "~/mux" }; |
| 136 | case RUNTIME_MODE.DOCKER: |
| 137 | return { type: "docker", image: parsed.image }; |
| 138 | default: |
| 139 | return { type: "local" }; |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | function parseThinkingLevel(value: string | undefined): ParsedThinkingInput { |
| 144 | if (!value) return DEFAULT_THINKING_LEVEL; // Default for mux run |
no test coverage detected