mindwire 0.1.30 → 0.1.32

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/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { defaultStateDirectory, superviseComputer, ensureComputer, computerPairingURI, stopComputer, computerClient, SDK_VERSION, readJSON, writeJSON, currentProcessIdentity, processStateAlive, acquireProcessLock, computerPairingQRData } from './chunk-RN7ERVJ2.js';
2
+ import { defaultStateDirectory, superviseComputer, ensureComputer, computerPairingURI, stopComputer, computerClient, SDK_VERSION, readJSON, writeJSON, currentProcessIdentity, processStateAlive, acquireProcessLock, computerPairingQRData } from './chunk-5X5PAFM7.js';
3
3
  import './chunk-T6TD76UA.js';
4
4
  import { promisify, parseArgs } from 'util';
5
5
  import { fileURLToPath, pathToFileURL } from 'url';
@@ -12,6 +12,7 @@ import { setTimeout as setTimeout$1 } from 'timers/promises';
12
12
  import { execFile, spawn } from 'child_process';
13
13
  import { homedir, tmpdir } from 'os';
14
14
  import * as fs from 'fs/promises';
15
+ import { cursorTo, clearLine } from 'readline';
15
16
 
16
17
  var enterScreen = "\x1B[?1049h\x1B[?25l";
17
18
  var leaveScreen = "\x1B[0m\x1B[?25h\x1B[?1049l";
@@ -469,6 +470,43 @@ function deviceSummary(devices, showKeys = false) {
469
470
  return ` ${name} \xB7 ${status}${identity}`;
470
471
  }).join("\n");
471
472
  }
473
+ var ConnectionProgress = class {
474
+ constructor(stream) {
475
+ this.stream = stream;
476
+ this.render();
477
+ this.timer = setInterval(() => this.render(), 1e3);
478
+ this.timer.unref();
479
+ process.once("exit", this.exiting);
480
+ }
481
+ stream;
482
+ startedAt = Date.now();
483
+ timer;
484
+ message = "Starting Mindwire\u2026";
485
+ closed = false;
486
+ exiting = () => this.close();
487
+ update(message) {
488
+ this.message = message;
489
+ this.render();
490
+ }
491
+ close() {
492
+ if (this.closed) return;
493
+ this.closed = true;
494
+ clearInterval(this.timer);
495
+ process.off("exit", this.exiting);
496
+ cursorTo(this.stream, 0);
497
+ clearLine(this.stream, 0);
498
+ }
499
+ render() {
500
+ const seconds = Math.floor((Date.now() - this.startedAt) / 1e3);
501
+ const elapsed = seconds > 0 ? ` \xB7 ${seconds}s` : "";
502
+ const width = Math.max(1, (this.stream.columns || 80) - elapsed.length - 1);
503
+ const message = this.message.replace(/[\x00-\x1f\x7f-\x9f]/g, "");
504
+ const text = message.length > width ? message.slice(0, width - 1) + "\u2026" : message;
505
+ cursorTo(this.stream, 0);
506
+ clearLine(this.stream, 0);
507
+ this.stream.write(text + elapsed);
508
+ }
509
+ };
472
510
 
473
511
  // src/cli.ts
474
512
  var help = `Mindwire \u2014 connect this computer to your phone
@@ -588,13 +626,12 @@ async function main(args = process.argv.slice(2)) {
588
626
  cloudflareTokenFile: values["cloudflare-token-file"] ? path.resolve(values["cloudflare-token-file"]) : void 0
589
627
  };
590
628
  }
591
- emit("starting", {}, "Starting Mindwire\u2026");
592
- const client2 = await ensureComputer(
593
- directory,
594
- fileURLToPath(import.meta.url),
595
- patch,
596
- (phase) => emit("progress", { message: phase }, phase)
597
- );
629
+ const progress = !values.json && process.stderr.isTTY && process.env.TERM !== "dumb" ? new ConnectionProgress(process.stderr) : void 0;
630
+ emit("starting", {}, progress ? void 0 : "Starting Mindwire\u2026");
631
+ const client2 = await ensureComputer(directory, fileURLToPath(import.meta.url), patch, (phase) => {
632
+ if (progress) progress.update(phase);
633
+ else emit("progress", { message: phase }, phase);
634
+ }).finally(() => progress?.close());
598
635
  const info = await client2.computer.info();
599
636
  emit("ready", { computerId: info.computerId, routes: info.routes }, "Mindwire is running in the background.");
600
637
  if (command === "start") return;
@@ -670,7 +707,7 @@ Mindwire continues running in the background.`);
670
707
  }
671
708
  if (!authorized) {
672
709
  authorized = true;
673
- emit("authorized", {}, "Phone authorized. Waiting for it to save the connection\u2026");
710
+ emit("authorized", {}, "Phone approved. Keep Mindwire open on your phone while it saves the connection\u2026");
674
711
  }
675
712
  await setTimeout$1(750);
676
713
  continue;
@@ -733,7 +770,7 @@ ${command2}`);
733
770
  ]);
734
771
  emit(
735
772
  "status",
736
- { ...info, daemonVersion: health.version, ...work, startup, recovering: controller?.recovering, relayError: controller?.error },
773
+ { ...info, daemonVersion: health.version, ...work, startup, recovering: controller?.recovering, relayError: controller?.error, relayErrorCode: controller?.errorCode },
737
774
  `Mindwire ${health.version} \xB7 ${work.idle ? "idle" : "working"}
738
775
  Startup: ${startup.enabled ? "on" : "off"}
739
776
  ${info.routes.map((route) => route.kind === "ssh" ? `SSH ${route.host}:${route.port}` : route.url).join("\n")}${controller?.error ? `
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/computer/pairing-display.ts","../src/computer/startup.ts","../src/computer/connection-flow.ts","../src/cli.ts"],"names":["resolve","delay","safeName","path2","client","createHash","command"],"mappings":"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","file":"cli.js","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { mkdtempSync, chmodSync, writeFileSync, rmSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { computerPairingQRData, computerPairingURI, type ComputerConnectionCode } from \"../computer.js\";\n\nexport type PairingQRMode = \"auto\" | \"terminal\" | \"browser\" | \"none\";\ntype Output = Pick<NodeJS.WriteStream, \"isTTY\" | \"columns\" | \"rows\" | \"write\" | \"on\" | \"off\">;\ninterface DisplayOptions {\n mode?: PairingQRMode;\n output?: Output;\n environment?: NodeJS.ProcessEnv;\n openBrowser?: (url: string) => Promise<boolean>;\n}\nexport interface PairingDisplay { close(): void }\n\nconst enterScreen = \"\\x1b[?1049h\\x1b[?25l\";\nconst leaveScreen = \"\\x1b[0m\\x1b[?25h\\x1b[?1049l\";\nconst clearScreen = \"\\x1b[H\\x1b[2J\";\nfunction scanInstruction(invitation: ComputerConnectionCode): string {\n return \"mode\" in invitation && invitation.mode === \"reconnect\"\n ? \"Workspaces → your computer → Reconnect Computer → Scan Connection Code\"\n : \"Mindwire → Add computer → Scan QR code\";\n}\n\n/** qrcode's small terminal renderer ignores margin/width. Render its matrix with\n * a four-module quiet zone, two square QR modules per terminal character. */\nexport async function createPairingQR(invitation: ComputerConnectionCode) {\n const QR = await import(\"qrcode\");\n const data = computerPairingQRData(invitation);\n const options = { errorCorrectionLevel: \"L\" as const, margin: 4 };\n const { modules } = QR.create(data, options);\n const width = modules.size + options.margin * 2;\n const black = (x: number, y: number): boolean => x >= 0 && y >= 0 && x < modules.size && y < modules.size\n && !!modules.data[y * modules.size + x];\n const lines: string[] = [];\n for (let y = -options.margin; y < modules.size + options.margin; y += 2) {\n let line = \"\";\n for (let x = -options.margin; x < modules.size + options.margin; x++) {\n const top = black(x, y), bottom = black(x, y + 1);\n line += top ? (bottom ? \"█\" : \"▀\") : (bottom ? \"▄\" : \" \");\n }\n // Explicit bright white background; a terminal's dark theme must not invert the QR.\n lines.push(\"\\x1b[30;107m\" + line + \"\\x1b[0m\");\n }\n const svg = await QR.toString(data, { ...options, type: \"svg\" });\n // Leave one column for auto-wrap and rows for instructions and the cursor.\n return { lines, columns: Math.max(width, scanInstruction(invitation).length) + 1, rows: lines.length + 5, svg };\n}\n\nfunction escapeHTML(value: string): string {\n return value.replace(/[&<>\"']/g, ch => ({ \"&\": \"&amp;\", \"<\": \"&lt;\", \">\": \"&gt;\", '\"': \"&quot;\", \"'\": \"&#39;\" })[ch]!);\n}\n\nfunction browserPage(invitation: ComputerConnectionCode, svg: string): string {\n const reconnect = \"mode\" in invitation && invitation.mode === \"reconnect\";\n const title = reconnect ? \"Reconnect your phone\" : \"Connect your phone\";\n return `<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; base-uri 'none'; form-action 'none'\">\n<title>${title} · Mindwire</title>\n<style>\n*{box-sizing:border-box}body{margin:0;background:#141416;color:#f5f5f7;font:16px/1.5 system-ui,sans-serif}\nmain{width:min(100% - 40px,520px);margin:32px auto;text-align:center}small{color:#a6a6af;letter-spacing:.16em}\nh1{font-size:28px;letter-spacing:-.04em;line-height:1.2;margin:16px 0 6px}p{color:#b7b7bf;margin:8px 0;overflow-wrap:anywhere}\n.code{width:min(100%,480px);margin:24px auto 16px;background:#fff;border-radius:16px;padding:8px}\nsvg{display:block;width:100%;height:auto}.steps{margin:20px 0}.steps p{color:#e1e1e6}\nbutton{font:inherit;font-weight:600;color:#f5f5f7;border:1px solid #45454b;background:#252528;border-radius:10px;padding:10px 18px;cursor:pointer}\nbutton:disabled{opacity:.45;cursor:default}button:focus-visible{outline:3px solid #a4b8ef;outline-offset:3px}\ntextarea{width:100%;margin-top:12px;padding:8px;color:inherit;background:#252528;border:1px solid #45454b;border-radius:8px}\n[hidden]{display:none!important}#expiry{font-size:14px}footer{font-size:13px;color:#93939d;margin:18px 0}\n</style></head><body><main>\n<small>MINDWIRE</small><h1>${title}</h1><p>${escapeHTML(invitation.name)}</p>\n<div class=\"code\" id=\"code\" role=\"img\" aria-label=\"Mindwire connection QR code\">${svg}</div>\n<p id=\"expiry\" data-expires=\"${escapeHTML(invitation.expiresAt)}\" aria-live=\"off\"></p>\n<div class=\"steps\"><p>${reconnect\n ? \"In Mindwire, open your computer in <strong>Workspaces</strong>, then <strong>Reconnect Computer → Scan Connection Code</strong>.\"\n : \"In Mindwire, open <strong>Add computer</strong> and scan.\"}</p>\n<p>${reconnect ? \"Your saved pairing and workspace stay the same. No new approval is needed.\" : \"Saved keys reconnect automatically. Approve on this computer only if asked.\"}</p></div>\n<button type=\"button\" id=\"copy\">Copy ${reconnect ? \"reconnect\" : \"pairing\"} link</button>\n<textarea id=\"link\" readonly hidden aria-label=\"Pairing link\">${escapeHTML(computerPairingURI(invitation))}</textarea>\n<footer>You can close this page after ${reconnect ? \"reconnecting\" : \"pairing\"}.</footer>\n</main><script>\nconst expiry=document.getElementById('expiry'),code=document.getElementById('code'),copy=document.getElementById('copy'),link=document.getElementById('link');\nfunction tick(){const seconds=Math.max(0,Math.ceil((Date.parse(expiry.dataset.expires)-Date.now())/1000));\nif(!seconds){code.remove();copy.disabled=true;link.value='';link.hidden=true;expiry.textContent='Code expired. Run mindwire connect for a new code.';return;}\nexpiry.textContent='Expires in '+Math.floor(seconds/60)+':'+String(seconds%60).padStart(2,'0');}\ntick();setInterval(tick,1000);\ncopy.addEventListener('click',async()=>{try{await navigator.clipboard.writeText(link.value);copy.textContent='Copied';}\ncatch{link.hidden=false;link.focus();link.select();copy.textContent='Select and copy the link';}});\n</script></body></html>`;\n}\n\nasync function openBrowser(url: string): Promise<boolean> {\n const [command, args]: [string, string[]] = process.platform === \"darwin\" ? [\"open\", [url]]\n : process.platform === \"win32\" ? [\"rundll32.exe\", [\"url.dll,FileProtocolHandler\", url]] : [\"xdg-open\", [url]];\n return new Promise(resolve => {\n const child = spawn(command, args, { stdio: \"ignore\", windowsHide: true });\n const finish = (ok: boolean) => { clearTimeout(timer); resolve(ok); };\n const timer = setTimeout(() => { child.kill(); finish(false); }, 5000);\n child.once(\"error\", () => finish(false));\n child.once(\"exit\", code => finish(code === 0));\n });\n}\n\n/** Display one existing invitation. Resizing never starts another service or pairing. */\nexport async function showPairingInvitation(invitation: ComputerConnectionCode, options: DisplayOptions = {}): Promise<PairingDisplay> {\n const reconnect = \"mode\" in invitation && invitation.mode === \"reconnect\";\n const instruction = scanInstruction(invitation);\n const nextStep = reconnect ? \"Scan with a saved phone.\" : \"Approve on this computer only if asked.\";\n const waiting = reconnect ? \"Your saved pairing stays the same.\" : \"Waiting for your phone…\";\n const command = \"mindwire connect\";\n const output = options.output ?? process.stdout;\n const environment = options.environment ?? process.env;\n const mode = options.mode ?? \"auto\";\n const interactive = !!output.isTTY && environment.TERM !== \"dumb\";\n const linkOnly = mode === \"none\" || (!interactive && mode !== \"browser\");\n if (linkOnly) {\n const destination = reconnect ? \"Workspaces → your computer → Reconnect Computer\" : \"Add computer\";\n output.write(`Paste this link in Mindwire → ${destination} (expires in 5 minutes):\\n${computerPairingURI(invitation)}\\n\\n${waiting}\\n`);\n return { close() {} };\n }\n\n const qr = await createPairingQR(invitation);\n const useScreen = interactive && mode !== \"browser\";\n let closed = false, pageDirectory: string | undefined;\n let browser: \"idle\" | \"opening\" | \"opened\" | \"failed\" = \"idle\";\n let pageURL: string | undefined;\n let browserAttempt: Promise<void> | undefined;\n const fits = () => (output.columns ?? 0) >= qr.columns && (output.rows ?? 0) >= qr.rows;\n const draw = () => {\n if (closed || !useScreen) return;\n let lines: string[];\n if (fits()) {\n lines = [instruction, \"\", ...qr.lines, \"\", waiting];\n } else {\n const size = `Terminal QR needs ${qr.columns} columns × ${qr.rows} rows.`;\n lines = browser === \"opened\" ? [\"QR opened in your browser.\", instruction, nextStep]\n : browser === \"opening\" ? [\"Opening a resizable QR in your browser…\", nextStep]\n : browser === \"failed\" ? [\"Couldn't open a browser here.\", size, \"Enlarge this terminal, or run:\", `${command} --no-qr`]\n : [size, \"Enlarge this terminal, or use --qr browser.\"];\n // Tiny windows may clip instructions; they must never wrap a QR or scroll the display.\n lines = lines.map(line => line.slice(0, Math.max(0, (output.columns ?? 80) - 1)))\n .slice(0, Math.max(0, (output.rows ?? 24) - 1));\n }\n output.write(clearScreen + lines.join(\"\\r\\n\"));\n };\n const ensureBrowser = (): Promise<void> => {\n if (browserAttempt) return browserAttempt;\n browser = \"opening\";\n draw();\n browserAttempt = (async () => {\n try {\n pageDirectory = mkdtempSync(join(tmpdir(), \"mindwire-pair-\"));\n chmodSync(pageDirectory, 0o700);\n const file = join(pageDirectory, \"pair.html\");\n writeFileSync(file, browserPage(invitation, qr.svg), { mode: 0o600 });\n pageURL = pathToFileURL(file).href;\n // An SSH session's browser would be on the remote machine. Keep auto mode local.\n const remoteShell = !!(environment.SSH_CONNECTION || environment.SSH_CLIENT || environment.SSH_TTY);\n const opened = (mode === \"browser\" || !remoteShell) && await (options.openBrowser ?? openBrowser)(pageURL);\n browser = opened ? \"opened\" : \"failed\";\n } catch {\n browser = \"failed\";\n }\n if (closed) return;\n if (useScreen) draw();\n else output.write(browser === \"opened\"\n ? `QR opened in your browser.\\n${instruction}\\n${nextStep}\\n`\n : `Open this local QR page in a browser:\\n${pageURL ?? `Page unavailable. Run ${command} --no-qr for a link.`}\\n\\n${waiting}\\n`);\n })();\n return browserAttempt;\n };\n const resize = () => {\n draw();\n if (!closed && mode === \"auto\" && !fits()) void ensureBrowser();\n };\n const close = () => {\n if (closed) return;\n closed = true;\n output.off(\"resize\", resize);\n process.off(\"exit\", close);\n process.off(\"SIGINT\", interrupt);\n process.off(\"SIGTERM\", terminate);\n process.off(\"SIGHUP\", hangup);\n if (useScreen) output.write(leaveScreen);\n if (pageDirectory) {\n try { rmSync(pageDirectory, { recursive: true, force: true }); } catch { /* Best effort on process exit. */ }\n }\n };\n const interrupt = () => { close(); process.exit(130); };\n const terminate = () => { close(); process.exit(143); };\n const hangup = () => { close(); process.exit(129); };\n process.once(\"exit\", close);\n process.once(\"SIGINT\", interrupt);\n process.once(\"SIGTERM\", terminate);\n process.once(\"SIGHUP\", hangup);\n if (useScreen) {\n output.write(enterScreen);\n output.on(\"resize\", resize);\n draw();\n }\n try {\n if (mode === \"browser\" || (mode === \"auto\" && !fits())) await ensureBrowser();\n return { close };\n } catch (error) {\n close();\n throw error;\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport * as fs from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport * as path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { ensureComputer, readJSON, writeJSON, type ControllerState } from \"./lifecycle.js\";\nimport { currentProcessIdentity, processStateAlive, type ProcessState } from \"./process.js\";\nimport { acquireProcessLock } from \"./lock.js\";\n\nconst execute = promisify(execFile);\ntype Command = [string, ...string[]];\nexport interface StartupPlan {\n kind: \"launchd\" | \"systemd\" | \"task-scheduler\";\n name: string; file: string; content: string;\n query: Command; enable: Command[]; disable: Command[];\n}\nexport interface StartupState { enabled: boolean; running?: boolean; kind?: StartupPlan[\"kind\"]; name?: string; file?: string }\nconst xml = (value: string) => value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\").replace(/'/g, \"&apos;\");\nconst systemd = (value: string, expandEnvironment = false) => '\"' + value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/%/g, \"%%\")\n .replace(/\\$/g, () => expandEnvironment ? \"$$\" : \"$\") + '\"';\nconst windowsArg = (value: string) => '\"' + value.replace(/(\\\\*)\"/g, '$1$1\\\\\"').replace(/(\\\\+)$/g, \"$1$1\") + '\"';\n\n/** Per-user startup, with no root service, password, or copied pairing secret. */\nexport function startupPlan(options: {\n directory: string; cliPath: string; executable?: string; platform?: NodeJS.Platform;\n home?: string; uid?: number; user?: string; environmentPath?: string;\n}): StartupPlan {\n const { directory, cliPath } = options;\n const executable = options.executable ?? process.execPath, home = options.home ?? homedir();\n const platform = options.platform ?? process.platform;\n const environmentPath = options.environmentPath ?? process.env.PATH ?? path.dirname(executable);\n for (const value of [directory, cliPath, executable, home, environmentPath]) {\n if (/[\\r\\n\\x00]/.test(value)) throw new Error(\"Startup paths cannot contain control characters.\");\n }\n const id = createHash(\"sha256\").update(directory).digest(\"hex\").slice(0, 12);\n const name = `sh.mindwire.computer.${id}`;\n const args = [cliPath, \"_watch\", \"--state-dir\", directory];\n if (platform === \"darwin\") {\n const domain = `gui/${options.uid ?? process.getuid?.()}`;\n const file = path.join(home, \"Library\", \"LaunchAgents\", name + \".plist\");\n return { kind: \"launchd\", name, file,\n content: `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\"><dict>\n<key>Label</key><string>${name}</string>\n<key>ProgramArguments</key><array>${[executable, ...args].map(v => `<string>${xml(v)}</string>`).join(\"\")}</array>\n<key>WorkingDirectory</key><string>${xml(home)}</string>\n<key>EnvironmentVariables</key><dict><key>PATH</key><string>${xml(environmentPath)}</string></dict>\n<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>\n<key>ThrottleInterval</key><integer>10</integer>\n<key>StandardOutPath</key><string>${xml(path.join(directory, \"startup.log\"))}</string>\n<key>StandardErrorPath</key><string>${xml(path.join(directory, \"startup.log\"))}</string>\n</dict></plist>\n`, query: [\"launchctl\", \"print\", `${domain}/${name}`],\n enable: [[\"launchctl\", \"enable\", `${domain}/${name}`], [\"launchctl\", \"bootstrap\", domain, file]],\n disable: [[\"launchctl\", \"bootout\", `${domain}/${name}`]] };\n }\n if (platform === \"linux\") {\n const file = path.join(home, \".config\", \"systemd\", \"user\", name + \".service\");\n return { kind: \"systemd\", name, file,\n content: `[Unit]\nDescription=Mindwire computer connection\nAfter=network-online.target\n[Service]\nType=simple\nExecStart=${[executable, ...args].map(value => systemd(value, true)).join(\" \")}\nWorkingDirectory=${systemd(home)}\nEnvironment=${systemd(\"PATH=\" + environmentPath)}\nRestart=always\nRestartSec=10\nKillMode=process\n[Install]\nWantedBy=default.target\n`, query: [\"systemctl\", \"--user\", \"is-active\", name + \".service\"],\n enable: [[\"systemctl\", \"--user\", \"daemon-reload\"], [\"systemctl\", \"--user\", \"enable\", \"--now\", name + \".service\"]],\n disable: [[\"systemctl\", \"--user\", \"disable\", \"--now\", name + \".service\"], [\"systemctl\", \"--user\", \"daemon-reload\"]] };\n }\n if (platform === \"win32\") {\n if (!options.user) throw new Error(\"Couldn't determine the Windows user for startup.\");\n const file = path.join(directory, \"startup-task.xml\");\n return { kind: \"task-scheduler\", name, file,\n content: `<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<Task version=\"1.2\" xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n<Triggers><LogonTrigger><Enabled>true</Enabled><UserId>${xml(options.user)}</UserId></LogonTrigger></Triggers>\n<Principals><Principal id=\"Owner\"><UserId>${xml(options.user)}</UserId><LogonType>InteractiveToken</LogonType><RunLevel>LeastPrivilege</RunLevel></Principal></Principals>\n<Settings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><StartWhenAvailable>true</StartWhenAvailable><ExecutionTimeLimit>PT0S</ExecutionTimeLimit><RestartOnFailure><Interval>PT1M</Interval><Count>999</Count></RestartOnFailure></Settings>\n<Actions Context=\"Owner\"><Exec><Command>${xml(executable)}</Command><Arguments>${xml(args.map(windowsArg).join(\" \"))}</Arguments><WorkingDirectory>${xml(home)}</WorkingDirectory></Exec></Actions>\n</Task>\n`, query: [\"schtasks.exe\", \"/Query\", \"/TN\", name],\n enable: [[\"schtasks.exe\", \"/Create\", \"/TN\", name, \"/XML\", file, \"/F\"], [\"schtasks.exe\", \"/Run\", \"/TN\", name]],\n disable: [[\"schtasks.exe\", \"/End\", \"/TN\", name], [\"schtasks.exe\", \"/Delete\", \"/TN\", name, \"/F\"]] };\n }\n throw new Error(\"Automatic startup supports macOS, Linux with systemd, and Windows. Run mindwire start on this system.\");\n}\n\nconst run = async ([command, ...args]: Command) => { await execute(command, args, { timeout: 15_000, windowsHide: true }); };\nexport async function startupStatus(directory: string): Promise<StartupState> {\n const state = await readJSON<StartupState>(path.join(directory, \"computer-startup.json\")) ?? { enabled: false };\n const guardian = await readJSON<ProcessState>(path.join(directory, \"computer-guardian.json\"));\n return { ...state, running: state.enabled && await processStateAlive(guardian) };\n}\n\nexport async function configureStartup(directory: string, cliPath: string, enabled: boolean, runtime: {\n plan?: StartupPlan; run?: (command: Command) => Promise<void>; verify?: () => Promise<void>;\n} = {}): Promise<StartupState> {\n await fs.mkdir(directory, { recursive: true, mode: 0o700 });\n const lockPath = path.join(directory, \"startup.lock\");\n const lock = await acquireProcessLock(lockPath);\n if (!lock) throw new Error(\"Startup is already being configured. Try again shortly.\");\n try {\n const user = process.platform === \"win32\" && !runtime.plan\n ? (await execute(\"whoami.exe\", [], { timeout: 3000, windowsHide: true })).stdout.trim() : undefined;\n const plan = runtime.plan ?? startupPlan({ directory, cliPath, user });\n const command = runtime.run ?? run;\n let loaded = false;\n try { await command(plan.query); loaded = true; } catch { /* Not installed/loaded. */ }\n if (enabled) {\n const previous = await fs.readFile(plan.file, plan.kind === \"task-scheduler\" ? \"utf16le\" : \"utf8\").catch(() => \"\");\n const changed = previous !== plan.content;\n if (changed) {\n await fs.mkdir(path.dirname(plan.file), { recursive: true, mode: 0o700 });\n const temporary = plan.file + `.tmp-${process.pid}`;\n try {\n await fs.writeFile(temporary, plan.content, { mode: 0o600, encoding: plan.kind === \"task-scheduler\" ? \"utf16le\" : \"utf8\" });\n await fs.rename(temporary, plan.file);\n } finally { await fs.rm(temporary, { force: true }); }\n }\n // Never restart the controller to update its login registration. The\n // currently running service and its terminal processes remain untouched.\n if (!loaded || changed && plan.kind !== \"launchd\") {\n for (const action of plan.enable) await command(action);\n }\n await command(plan.query); // Report success only after native registration.\n if (runtime.verify) await runtime.verify();\n else {\n let running = false;\n for (let attempt = 0; attempt < 60; attempt++) {\n const guardian = await readJSON<ProcessState>(path.join(directory, \"computer-guardian.json\"));\n if (await processStateAlive(guardian)) { running = true; break; }\n await delay(250);\n }\n if (!running) throw new Error(`Automatic startup was registered but its guardian didn't start. Inspect ${path.join(directory, \"startup.log\")}.`);\n }\n } else {\n if (loaded || await fs.stat(plan.file).then(() => true, () => false)) {\n for (const action of plan.disable) {\n try { await command(action); }\n catch (error) { if (action.includes(\"/End\") || action.includes(\"bootout\") && !loaded) continue; throw error; }\n }\n }\n await fs.rm(plan.file, { force: true });\n }\n const state: StartupState = { enabled, kind: plan.kind, name: plan.name, file: plan.file };\n await writeJSON(path.join(directory, \"computer-startup.json\"), state);\n return { ...state, running: enabled };\n } finally { await lock.close(); }\n}\n\n/** Native startup managers supervise this small guardian. It adopts an existing\n * controller and honours an explicit stop; it never owns or kills user work. */\nexport async function watchComputer(directory: string, cliPath: string): Promise<void> {\n let stopping = false;\n const abort = new AbortController();\n const stop = () => { stopping = true; abort.abort(); };\n process.on(\"SIGTERM\", stop); process.on(\"SIGINT\", stop);\n let reportedError = \"\";\n const guardianPath = path.join(directory, \"computer-guardian.json\");\n try {\n await writeJSON(guardianPath, await currentProcessIdentity());\n while (!stopping) {\n const paused = await readJSON<{ stopped: boolean }>(path.join(directory, \"computer-stopped.json\"));\n const controller = await readJSON<ControllerState>(path.join(directory, \"computer-controller.json\"));\n if (!paused?.stopped && !await processStateAlive(controller)) {\n try { await ensureComputer(directory, cliPath, {}, undefined, { resume: false, signal: abort.signal }); reportedError = \"\"; }\n catch (error) {\n if (stopping) break;\n const message = error instanceof Error ? error.message : \"Computer recovery failed.\";\n if (message !== reportedError) { process.stderr.write(`Mindwire recovery: ${message}\\n`); reportedError = message; }\n }\n }\n // A user stop is durable; a reboot or repeated guardian launch won't undo it.\n for (let tick = 0; tick < 10 && !stopping; tick++) await delay(500);\n }\n } finally {\n if ((await readJSON<{ pid: number }>(guardianPath))?.pid === process.pid) await writeJSON(guardianPath, { pid: 0 });\n process.off(\"SIGTERM\", stop); process.off(\"SIGINT\", stop);\n }\n}\n","import type { ComputerReconnectCode, ComputerDevice, ComputerInfo } from \"../computer.js\";\n\nexport type ConnectionAction = \"resume\" | \"reconnect\" | \"pair\";\n\nexport function connectionAction(value: string | undefined): ConnectionAction | undefined {\n if (value === undefined) return undefined;\n if (value === \"resume\" || value === \"reconnect\" || value === \"pair\") return value;\n throw new Error(\"Use mindwire connect, mindwire connect resume, mindwire reconnect, or mindwire connect pair.\");\n}\n\n/** Safe to copy into either a Unix shell or PowerShell, even when an ID starts\n * with a dash. Validate old daemons too; these values originated on a phone. */\nexport function approvalCommand(pairingId: string, requestId: string): string {\n if (![pairingId, requestId].every(id => /^[A-Za-z0-9_-]{8,128}$/.test(id))) {\n throw new Error(\"Invalid phone pairing request. Run mindwire connect to create a new code.\");\n }\n return `mindwire approve -- ${pairingId} ${requestId}`;\n}\n\n/** Saved approvals do not prove that the phone still has its key or address.\n * Every disconnected phone uses the same QR; the signed handshake chooses resume\n * or fresh approval. The old commands remain aliases, not separate UX paths. */\nexport async function chooseConnectionAction(options: {\n requested?: ConnectionAction;\n devices: ComputerDevice[];\n}): Promise<ConnectionAction> {\n if (options.requested === \"pair\" || options.requested === \"reconnect\") return \"pair\";\n return options.devices.some(device => !device.revoked && device.connected) ? \"resume\" : \"pair\";\n}\n\n/** A fresh key is never merged by name. Replacement requires the owner's explicit\n * choice of the exact approvals shown here; a different same-name phone can be added. */\nexport async function choosePairingDecision(options: {\n replacements: ComputerDevice[];\n question: (prompt: string) => Promise<string>;\n}): Promise<{ approve: boolean; replaceDeviceIds?: string[] }> {\n const replacements = options.replacements.filter(device => !device.revoked);\n const prompt = replacements.length\n ? `\\nPrevious approvals with this name:\\n${deviceSummary(replacements, true)}\\n\\nAllow this phone? [r = replace these approvals, a = add a different phone, N = deny]: `\n : \"Allow this phone to access this computer? [y/N] \";\n for (;;) {\n const answer = (await options.question(prompt)).trim().toLowerCase();\n if ([\"\", \"n\", \"no\"].includes(answer)) return { approve: false };\n if (replacements.length) {\n if ([\"r\", \"replace\"].includes(answer)) return { approve: true, replaceDeviceIds: replacements.map(device => device.id) };\n if ([\"a\", \"add\"].includes(answer)) return { approve: true };\n } else if ([\"y\", \"yes\"].includes(answer)) return { approve: true };\n }\n}\n\n/** Ask once; preserve existing opt-outs. Scripts must opt in with --startup. */\nexport async function chooseStartupAction(options: {\n state: { enabled: boolean; running?: boolean; kind?: string };\n startup?: boolean;\n noStartup?: boolean;\n question?: (prompt: string) => Promise<string>;\n}): Promise<boolean | undefined> {\n if (options.startup && options.noStartup) throw new Error(\"Choose either --startup or --no-startup.\");\n if (options.startup) return !options.state.enabled || !options.state.running ? true : undefined;\n if (options.noStartup) return options.state.kind ? undefined : false;\n if (options.state.kind) return options.state.enabled && !options.state.running ? true : undefined;\n if (!options.question) return undefined;\n for (;;) {\n const answer = (await options.question(\n \"\\nStart Mindwire automatically after you sign in to this computer? [Y/n] \")).trim().toLowerCase();\n if ([\"\", \"y\", \"yes\"].includes(answer)) return true;\n if ([\"n\", \"no\"].includes(answer)) return false;\n }\n}\n\nexport function reconnectCode(info: ComputerInfo, name: string, now = new Date()): ComputerReconnectCode {\n if (info.routes.length === 0) throw new Error(\"No connection address is ready. Run mindwire status and retry once the tunnel is online.\");\n return { version: 1, mode: \"reconnect\", computerId: info.computerId, registryId: info.registryId,\n fingerprint: info.fingerprint, name, routes: info.routes,\n expiresAt: new Date(now.getTime() + 5 * 60_000).toISOString() };\n}\n\nexport function deviceSummary(devices: ComputerDevice[], showKeys = false): string {\n const saved = devices.filter(device => !device.revoked);\n const names = new Map<string, number>();\n const safeName = (device: ComputerDevice) => device.name.replace(/[\\x00-\\x1f\\x7f-\\x9f]/g, \"\");\n for (const device of saved) names.set(safeName(device), (names.get(safeName(device)) ?? 0) + 1);\n return saved\n .sort((a, b) => a.name.localeCompare(b.name) || a.id.localeCompare(b.id))\n .map(device => {\n const name = safeName(device);\n const status = device.connected === true ? \"connected\" : \"paired\";\n const identity = showKeys || (names.get(name) ?? 0) > 1 ? ` · key ${device.id.slice(0, 8)}` : \"\";\n return ` ${name} · ${status}${identity}`;\n }).join(\"\\n\");\n}\n","#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { fileURLToPath } from \"node:url\";\nimport { realpathSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { createInterface } from \"node:readline/promises\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { computerPairingURI, type ComputerUpdate } from \"./computer.js\";\nimport { SDK_VERSION } from \"./version.js\";\nimport { computerClient, defaultStateDirectory, ensureComputer, readJSON, stopComputer, superviseComputer, type ComputerConfig } from \"./computer/lifecycle.js\";\nimport type { RelayOptions } from \"./computer/relay.js\";\nimport { showPairingInvitation, type PairingQRMode } from \"./computer/pairing-display.js\";\nimport { configureStartup, startupStatus, watchComputer } from \"./computer/startup.js\";\nimport { approvalCommand, chooseConnectionAction, choosePairingDecision, chooseStartupAction, connectionAction, deviceSummary } from \"./computer/connection-flow.js\";\n\nconst help = `Mindwire — connect this computer to your phone\n\n npm install -g mindwire\n mindwire connect Connect your phone; saved keys reconnect automatically\n mindwire reconnect Show a connection QR again (also repairs a missing pairing)\n mindwire connect pair Pair another phone with this computer\n mindwire connect --relay none --host laptop.tailnet Use your existing VPN\n mindwire connect --relay none Direct SSH only (reachable network required)\n mindwire connect --relay cloudflare Cloudflare quick tunnel\n mindwire connect --relay ngrok ngrok (uses its configured account)\n mindwire connect --relay custom --relay-url wss://computer.example/ssh\n\n mindwire start Start the saved connection in the background\n mindwire startup enable|disable Manage automatic startup after computer login\n mindwire startup status Check automatic startup\n mindwire status Show connection and running service\n mindwire devices List paired phones\n mindwire revoke DEVICE_ID Disconnect and revoke one phone\n mindwire update [--version VERSION] Download a verified release; wait until idle\n mindwire stop Stop when no work or terminals are running\n\nOptions:\n --directory PATH Initial workspace directory (default: home)\n --host HOST Reachable LAN, public or VPN hostname\n --relay none|cloudflare|ngrok|custom Provider (default: Cloudflare internet tunnel)\n --relay-url URL Stable configured WebSocket hostname\n --cloudflare-token-file PATH Named Cloudflare tunnel token file\n --state-dir PATH Private state directory\n --json Structured output (QR invitation includes a secret)\n --qr auto|terminal|browser Fit the QR to your terminal or open a local page\n --no-qr Print only the pairing link\n --startup Enable automatic startup without a prompt\n --no-startup Skip automatic startup setup\n --replace-device DEVICE_ID With approve: replace a lost phone key (repeatable)\n\nThe default works across Wi-Fi and mobile networks. Mindwire privately downloads\na verified Cloudflare helper when needed. Relays carry encrypted SSH.\nQuick tunnel addresses change on restart; use a stable hostname/VPN for regular use.\nngrok needs its installed CLI and account. Direct SSH needs no relay when reachable.\nNothing changes your system SSH login.\n`;\n\nfunction safeName(text: string): string { return text.replace(/[\\x00-\\x1f\\x7f-\\x9f]/g, \"\"); }\n\nexport async function main(args = process.argv.slice(2)): Promise<void> {\n const { values, positionals } = parseArgs({ args, allowPositionals: true, options: {\n help: { type: \"boolean\", short: \"h\" }, json: { type: \"boolean\" }, \"no-qr\": { type: \"boolean\" }, qr: { type: \"string\" },\n \"state-dir\": { type: \"string\" }, directory: { type: \"string\" }, host: { type: \"string\" },\n relay: { type: \"string\" }, \"relay-url\": { type: \"string\" }, \"cloudflare-token-file\": { type: \"string\" },\n \"daemon-bin\": { type: \"string\" }, bind: { type: \"string\" }, port: { type: \"string\" }, \"websocket-port\": { type: \"string\" },\n version: { type: \"string\" }, force: { type: \"boolean\" }, startup: { type: \"boolean\" }, \"no-startup\": { type: \"boolean\" },\n \"replace-device\": { type: \"string\", multiple: true },\n } });\n const command = positionals[0] ?? \"help\";\n if (values.help || command === \"help\") { process.stdout.write(help); return; }\n if (values.qr && ![\"auto\", \"terminal\", \"browser\"].includes(values.qr)) throw new Error(\"Choose --qr auto, terminal or browser.\");\n if (values.startup && values[\"no-startup\"]) throw new Error(\"Choose either --startup or --no-startup.\");\n const directory = path.resolve(values[\"state-dir\"] ?? defaultStateDirectory());\n const emit = (event: string, data: object = {}, text?: string) => {\n if (values.json) process.stdout.write(JSON.stringify({ event, ...data }) + \"\\n\");\n else if (text) process.stdout.write(text + \"\\n\");\n };\n if (command === \"_serve\") { await superviseComputer(directory); return; }\n if (command === \"_watch\") { await watchComputer(directory, fileURLToPath(import.meta.url)); return; }\n if (command === \"startup\") {\n const action = positionals[1] ?? \"status\";\n if (![\"enable\", \"disable\", \"status\"].includes(action)) throw new Error(\"Use mindwire startup enable, disable or status.\");\n const state = action === \"status\" ? await startupStatus(directory)\n : await configureStartup(directory, fileURLToPath(import.meta.url), action === \"enable\");\n emit(\"startup\", state, state.enabled ? \"Mindwire starts after you sign in to this computer and recovers automatically.\"\n : \"Automatic startup is off. Use mindwire start to run the service.\");\n return;\n }\n if ([\"connect\", \"start\", \"reconnect\"].includes(command)) {\n const requestedAction = command === \"reconnect\" ? \"reconnect\" : command === \"connect\" ? connectionAction(positionals[1]) : undefined;\n const patch: Partial<ComputerConfig> = {};\n if (values.directory) patch.directory = path.resolve(values.directory);\n if (values.host) patch.host = values.host;\n if (values.bind) patch.bind = values.bind;\n for (const [flag, field] of [[\"port\", \"sshPort\"], [\"websocket-port\", \"websocketPort\"]] as const) {\n if (values[flag] !== undefined) {\n const n = Number(values[flag]);\n if (!Number.isInteger(n) || n < 0 || n > 65535) throw new Error(`Invalid --${flag}.`);\n patch[field] = n;\n }\n }\n if (values[\"daemon-bin\"] || process.env.MINDWIRE_DAEMON) patch.daemonBin = path.resolve(values[\"daemon-bin\"] ?? process.env.MINDWIRE_DAEMON!);\n if (values.version) patch.version = values.version.replace(/^v/, \"\");\n if (values.relay || values[\"relay-url\"] || values[\"cloudflare-token-file\"]) {\n const kind = values.relay ?? \"custom\";\n if (![\"none\", \"cloudflare\", \"ngrok\", \"custom\"].includes(kind)) throw new Error(\"Choose relay none, cloudflare, ngrok or custom.\");\n patch.relay = { kind: kind as RelayOptions[\"kind\"], url: values[\"relay-url\"],\n cloudflareTokenFile: values[\"cloudflare-token-file\"] ? path.resolve(values[\"cloudflare-token-file\"]) : undefined };\n }\n emit(\"starting\", {}, \"Starting Mindwire…\");\n const client = await ensureComputer(directory, fileURLToPath(import.meta.url), patch,\n phase => emit(\"progress\", { message: phase }, phase));\n const info = await client.computer.info();\n emit(\"ready\", { computerId: info.computerId, routes: info.routes }, \"Mindwire is running in the background.\");\n if (command === \"start\") return;\n if (info.routes.some(route => route.kind === \"websocket\")) {\n emit(\"secure_connection\", {}, \"Your phone connects over end-to-end encrypted SSH. The tunnel carries encrypted traffic; only phones you approve can connect.\");\n }\n const devices = await client.computer.devices();\n const saved = devices.filter(device => !device.revoked);\n if (saved.length) emit(\"saved_devices\", { devices: saved }, `\\nSaved approvals on this computer\\n${deviceSummary(saved)}`);\n const question = !values.json && process.stdin.isTTY ? async (prompt: string): Promise<string> => {\n const input = createInterface({ input: process.stdin, output: process.stderr });\n try { return await input.question(prompt); } finally { input.close(); }\n } : undefined;\n const action = await chooseConnectionAction({ requested: requestedAction, devices });\n const startupPreference = await startupStatus(directory);\n const startupAction = await chooseStartupAction({ state: startupPreference,\n startup: values.startup, noStartup: values[\"no-startup\"],\n question: action === \"pair\" && saved.length === 0 ? question : undefined });\n if (startupAction !== undefined) {\n try {\n const startup = await configureStartup(directory, fileURLToPath(import.meta.url), startupAction);\n emit(\"startup\", startup, startup.enabled\n ? \"Automatic startup enabled. Saved phones can reconnect after you sign in to this computer.\"\n : \"Automatic startup is off. Run mindwire connect after restarting, or mindwire startup enable to change this.\");\n } catch {\n emit(\"startup_unavailable\", {}, \"Mindwire is running, but startup setup didn't complete. Run mindwire startup enable to check your system's startup service.\");\n }\n } else {\n emit(\"startup\", startupPreference, startupPreference.enabled\n ? \"Automatic startup is on. Change it with mindwire startup disable.\"\n : \"Automatic startup is off. Enable it with mindwire startup enable.\");\n }\n if (action === \"resume\") {\n const connected = saved.filter(device => device.connected);\n emit(\"connected\", { computerId: info.computerId, devices: connected }, `\\nConnected:\\n${deviceSummary(connected)}\\nMindwire continues running in the background.`);\n emit(\"connect_hint\", {}, \"To scan again or add a phone, run mindwire reconnect.\");\n return;\n }\n const invitation = await client.computer.invite((await client.computer.info()).routes);\n const uri = computerPairingURI(invitation);\n emit(\"invitation\", { invitation, uri });\n const display = values.json ? undefined : await showPairingInvitation(invitation, {\n mode: values[\"no-qr\"] ? \"none\" : (values.qr ?? \"auto\") as PairingQRMode,\n });\n try {\n let shownRequest: string | undefined;\n let authorized = false;\n while (Date.now() < Date.parse(invitation.expiresAt)) {\n const pairing = await client.computer.pairing(invitation.pairingId);\n if (pairing.status === \"waiting\" && requestedAction !== \"pair\" && requestedAction !== \"reconnect\") {\n const connected = (await client.computer.devices()).filter(device => !device.revoked && device.connected);\n if (connected.length && ((info.pairingVersion ?? 0) < 2 || (await client.computer.closeUnusedPairing(invitation.pairingId)).cancelled)) {\n display?.close();\n emit(\"connected\", { computerId: info.computerId, devices: connected }, `Connected:\\n${deviceSummary(connected)}\\nMindwire continues running in the background.`);\n return;\n }\n }\n if (pairing.status === \"approved\") {\n display?.close();\n if (pairing.completed) {\n emit(\"paired\", { computerId: info.computerId, completed: true }, \"Phone connected and saved. You can close this terminal; Mindwire keeps running.\");\n return;\n }\n if (!authorized) {\n authorized = true;\n emit(\"authorized\", {}, \"Phone authorized. Waiting for it to save the connection…\");\n }\n await delay(750);\n continue;\n }\n if (pairing.status === \"rejected\") { display?.close(); emit(\"rejected\", {}, \"Pairing declined.\"); return; }\n if (pairing.request && shownRequest !== pairing.request.id) {\n display?.close();\n shownRequest = pairing.request.id;\n const key = Buffer.from(pairing.request.publicKey.split(\" \")[1] ?? \"\", \"base64\");\n const fingerprint = \"SHA256:\" + createHash(\"sha256\").update(key).digest(\"base64\").replace(/=+$/, \"\");\n const deviceId = createHash(\"sha256\").update(key).digest(\"base64url\");\n const replacements = (info.pairingVersion ?? 0) >= 2 ? (await client.computer.devices()).filter(device =>\n !device.revoked && device.id !== deviceId && device.name === pairing.request!.name) : [];\n emit(\"approval_required\", { pairingId: invitation.pairingId, request: pairing.request, fingerprint, replacements },\n `\\n${safeName(pairing.request.name)} wants to connect.\\nDevice key: ${fingerprint}\\nAccess: files and commands as your computer account.`);\n if (!question) {\n const command = approvalCommand(invitation.pairingId, pairing.request.id);\n emit(\"approval_command\", { command }, `Review this device, then run:\\n${command}`);\n } else {\n const decision = await choosePairingDecision({ replacements, question });\n await client.computer.decide(invitation.pairingId, pairing.request.id, decision.approve,\n decision.replaceDeviceIds ? { replaceDeviceIds: decision.replaceDeviceIds } : {});\n }\n }\n await delay(750);\n }\n throw new Error(authorized\n ? \"The phone was approved but did not finish saving. Run mindwire connect and scan again; its saved key will be reused.\"\n : \"Connection code expired. Run mindwire connect to show a new QR code.\");\n } finally { display?.close(); }\n }\n if (command === \"stop\") { await stopComputer(directory, values.force === true); emit(\"stopped\", {}, \"Mindwire stopped.\"); return; }\n const client = await computerClient(directory);\n switch (command) {\n case \"status\": {\n const [info, health, work, controller, startup] = await Promise.all([client.computer.info(), client.health(), client.service.updateStatus(),\n readJSON<{ error?: string; phase?: string; recovering?: boolean }>(path.join(directory, \"computer-controller.json\")), startupStatus(directory)]);\n emit(\"status\", { ...info, daemonVersion: health.version, ...work, startup, recovering: controller?.recovering, relayError: controller?.error },\n `Mindwire ${health.version} · ${work.idle ? \"idle\" : \"working\"}\\nStartup: ${startup.enabled ? \"on\" : \"off\"}\\n${info.routes.map(route => route.kind === \"ssh\" ? `SSH ${route.host}:${route.port}` : route.url).join(\"\\n\")}${controller?.error ? `\\n${controller.error}` : \"\"}`);\n break;\n }\n case \"devices\": {\n const devices = await client.computer.devices();\n emit(\"devices\", { devices }, devices.length ? devices.map(d => `${safeName(d.name)} ${d.id}${d.revoked ? \" (revoked)\" : \"\"}`).join(\"\\n\") : \"No paired phones yet. Run mindwire connect.\");\n break;\n }\n case \"revoke\": {\n if (!positionals[1]) throw new Error(\"Use mindwire revoke DEVICE_ID (from mindwire devices).\");\n await client.computer.revoke(positionals[1]); emit(\"revoked\", {}, \"Device revoked and disconnected.\"); break;\n }\n case \"approve\": case \"reject\": {\n if (!positionals[1] || !positionals[2]) throw new Error(`Use mindwire ${command} PAIRING_ID REQUEST_ID.`);\n await client.computer.decide(positionals[1], positionals[2], command === \"approve\",\n values[\"replace-device\"] ? { replaceDeviceIds: values[\"replace-device\"] } : {});\n emit(command, {}, command === \"approve\" ? \"Phone approved. Waiting for it to save the connection.\" : \"Phone declined.\"); break;\n }\n case \"update\": {\n const version = (values.version ?? SDK_VERSION).replace(/^v/, \"\");\n const health = await client.health();\n if (health.version.replace(/^v/, \"\") === version) { emit(\"updated\", { version }, `Mindwire ${version} is already installed.`); return; }\n const requested = await client.computer.requestUpdate(version);\n emit(\"update_queued\", requested, \"Update queued. It will wait until all work and terminals are finished.\");\n let last = \"\";\n for (;;) {\n const update = await readJSON<ComputerUpdate>(path.join(directory, \"computer-update.json\"));\n if (update?.id !== requested.id) throw new Error(\"The update request changed. Run mindwire status.\");\n if (update.status !== last) { last = update.status; emit(\"update\", update, `Update: ${update.status}`); }\n if (update.status === \"complete\") return;\n if (update.status === \"failed\") throw new Error(update.error ?? \"Update failed.\");\n await delay(750);\n }\n }\n default: throw new Error(`Unknown command ${command}. Run mindwire --help.`);\n }\n}\n\nfunction isCLIEntry(): boolean {\n if (!process.argv[1]) return false;\n try {\n // npm links its bin command: argv keeps the link, while ESM resolves the module.\n return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url));\n } catch {\n // Importing the CLI from an eval or another program must not start a service.\n return false;\n }\n}\n\nif (isCLIEntry()) {\n void main().catch(error => {\n const message = error instanceof Error ? error.message : String(error);\n if (process.argv.includes(\"--json\")) process.stderr.write(JSON.stringify({ event: \"error\", message }) + \"\\n\");\n else process.stderr.write(`Mindwire: ${message}\\n`);\n process.exitCode = 1;\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/computer/pairing-display.ts","../src/computer/startup.ts","../src/computer/connection-flow.ts","../src/computer/connection-progress.ts","../src/cli.ts"],"names":["resolve","delay","safeName","path2","client","createHash","command"],"mappings":"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","file":"cli.js","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { mkdtempSync, chmodSync, writeFileSync, rmSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { computerPairingQRData, computerPairingURI, type ComputerConnectionCode } from \"../computer.js\";\n\nexport type PairingQRMode = \"auto\" | \"terminal\" | \"browser\" | \"none\";\ntype Output = Pick<NodeJS.WriteStream, \"isTTY\" | \"columns\" | \"rows\" | \"write\" | \"on\" | \"off\">;\ninterface DisplayOptions {\n mode?: PairingQRMode;\n output?: Output;\n environment?: NodeJS.ProcessEnv;\n openBrowser?: (url: string) => Promise<boolean>;\n}\nexport interface PairingDisplay { close(): void }\n\nconst enterScreen = \"\\x1b[?1049h\\x1b[?25l\";\nconst leaveScreen = \"\\x1b[0m\\x1b[?25h\\x1b[?1049l\";\nconst clearScreen = \"\\x1b[H\\x1b[2J\";\nfunction scanInstruction(invitation: ComputerConnectionCode): string {\n return \"mode\" in invitation && invitation.mode === \"reconnect\"\n ? \"Workspaces → your computer → Reconnect Computer → Scan Connection Code\"\n : \"Mindwire → Add computer → Scan QR code\";\n}\n\n/** qrcode's small terminal renderer ignores margin/width. Render its matrix with\n * a four-module quiet zone, two square QR modules per terminal character. */\nexport async function createPairingQR(invitation: ComputerConnectionCode) {\n const QR = await import(\"qrcode\");\n const data = computerPairingQRData(invitation);\n const options = { errorCorrectionLevel: \"L\" as const, margin: 4 };\n const { modules } = QR.create(data, options);\n const width = modules.size + options.margin * 2;\n const black = (x: number, y: number): boolean => x >= 0 && y >= 0 && x < modules.size && y < modules.size\n && !!modules.data[y * modules.size + x];\n const lines: string[] = [];\n for (let y = -options.margin; y < modules.size + options.margin; y += 2) {\n let line = \"\";\n for (let x = -options.margin; x < modules.size + options.margin; x++) {\n const top = black(x, y), bottom = black(x, y + 1);\n line += top ? (bottom ? \"█\" : \"▀\") : (bottom ? \"▄\" : \" \");\n }\n // Explicit bright white background; a terminal's dark theme must not invert the QR.\n lines.push(\"\\x1b[30;107m\" + line + \"\\x1b[0m\");\n }\n const svg = await QR.toString(data, { ...options, type: \"svg\" });\n // Leave one column for auto-wrap and rows for instructions and the cursor.\n return { lines, columns: Math.max(width, scanInstruction(invitation).length) + 1, rows: lines.length + 5, svg };\n}\n\nfunction escapeHTML(value: string): string {\n return value.replace(/[&<>\"']/g, ch => ({ \"&\": \"&amp;\", \"<\": \"&lt;\", \">\": \"&gt;\", '\"': \"&quot;\", \"'\": \"&#39;\" })[ch]!);\n}\n\nfunction browserPage(invitation: ComputerConnectionCode, svg: string): string {\n const reconnect = \"mode\" in invitation && invitation.mode === \"reconnect\";\n const title = reconnect ? \"Reconnect your phone\" : \"Connect your phone\";\n return `<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; base-uri 'none'; form-action 'none'\">\n<title>${title} · Mindwire</title>\n<style>\n*{box-sizing:border-box}body{margin:0;background:#141416;color:#f5f5f7;font:16px/1.5 system-ui,sans-serif}\nmain{width:min(100% - 40px,520px);margin:32px auto;text-align:center}small{color:#a6a6af;letter-spacing:.16em}\nh1{font-size:28px;letter-spacing:-.04em;line-height:1.2;margin:16px 0 6px}p{color:#b7b7bf;margin:8px 0;overflow-wrap:anywhere}\n.code{width:min(100%,480px);margin:24px auto 16px;background:#fff;border-radius:16px;padding:8px}\nsvg{display:block;width:100%;height:auto}.steps{margin:20px 0}.steps p{color:#e1e1e6}\nbutton{font:inherit;font-weight:600;color:#f5f5f7;border:1px solid #45454b;background:#252528;border-radius:10px;padding:10px 18px;cursor:pointer}\nbutton:disabled{opacity:.45;cursor:default}button:focus-visible{outline:3px solid #a4b8ef;outline-offset:3px}\ntextarea{width:100%;margin-top:12px;padding:8px;color:inherit;background:#252528;border:1px solid #45454b;border-radius:8px}\n[hidden]{display:none!important}#expiry{font-size:14px}footer{font-size:13px;color:#93939d;margin:18px 0}\n</style></head><body><main>\n<small>MINDWIRE</small><h1>${title}</h1><p>${escapeHTML(invitation.name)}</p>\n<div class=\"code\" id=\"code\" role=\"img\" aria-label=\"Mindwire connection QR code\">${svg}</div>\n<p id=\"expiry\" data-expires=\"${escapeHTML(invitation.expiresAt)}\" aria-live=\"off\"></p>\n<div class=\"steps\"><p>${reconnect\n ? \"In Mindwire, open your computer in <strong>Workspaces</strong>, then <strong>Reconnect Computer → Scan Connection Code</strong>.\"\n : \"In Mindwire, open <strong>Add computer</strong> and scan.\"}</p>\n<p>${reconnect ? \"Your saved pairing and workspace stay the same. No new approval is needed.\" : \"Saved keys reconnect automatically. Approve on this computer only if asked.\"}</p></div>\n<button type=\"button\" id=\"copy\">Copy ${reconnect ? \"reconnect\" : \"pairing\"} link</button>\n<textarea id=\"link\" readonly hidden aria-label=\"Pairing link\">${escapeHTML(computerPairingURI(invitation))}</textarea>\n<footer>You can close this page after ${reconnect ? \"reconnecting\" : \"pairing\"}.</footer>\n</main><script>\nconst expiry=document.getElementById('expiry'),code=document.getElementById('code'),copy=document.getElementById('copy'),link=document.getElementById('link');\nfunction tick(){const seconds=Math.max(0,Math.ceil((Date.parse(expiry.dataset.expires)-Date.now())/1000));\nif(!seconds){code.remove();copy.disabled=true;link.value='';link.hidden=true;expiry.textContent='Code expired. Run mindwire connect for a new code.';return;}\nexpiry.textContent='Expires in '+Math.floor(seconds/60)+':'+String(seconds%60).padStart(2,'0');}\ntick();setInterval(tick,1000);\ncopy.addEventListener('click',async()=>{try{await navigator.clipboard.writeText(link.value);copy.textContent='Copied';}\ncatch{link.hidden=false;link.focus();link.select();copy.textContent='Select and copy the link';}});\n</script></body></html>`;\n}\n\nasync function openBrowser(url: string): Promise<boolean> {\n const [command, args]: [string, string[]] = process.platform === \"darwin\" ? [\"open\", [url]]\n : process.platform === \"win32\" ? [\"rundll32.exe\", [\"url.dll,FileProtocolHandler\", url]] : [\"xdg-open\", [url]];\n return new Promise(resolve => {\n const child = spawn(command, args, { stdio: \"ignore\", windowsHide: true });\n const finish = (ok: boolean) => { clearTimeout(timer); resolve(ok); };\n const timer = setTimeout(() => { child.kill(); finish(false); }, 5000);\n child.once(\"error\", () => finish(false));\n child.once(\"exit\", code => finish(code === 0));\n });\n}\n\n/** Display one existing invitation. Resizing never starts another service or pairing. */\nexport async function showPairingInvitation(invitation: ComputerConnectionCode, options: DisplayOptions = {}): Promise<PairingDisplay> {\n const reconnect = \"mode\" in invitation && invitation.mode === \"reconnect\";\n const instruction = scanInstruction(invitation);\n const nextStep = reconnect ? \"Scan with a saved phone.\" : \"Approve on this computer only if asked.\";\n const waiting = reconnect ? \"Your saved pairing stays the same.\" : \"Waiting for your phone…\";\n const command = \"mindwire connect\";\n const output = options.output ?? process.stdout;\n const environment = options.environment ?? process.env;\n const mode = options.mode ?? \"auto\";\n const interactive = !!output.isTTY && environment.TERM !== \"dumb\";\n const linkOnly = mode === \"none\" || (!interactive && mode !== \"browser\");\n if (linkOnly) {\n const destination = reconnect ? \"Workspaces → your computer → Reconnect Computer\" : \"Add computer\";\n output.write(`Paste this link in Mindwire → ${destination} (expires in 5 minutes):\\n${computerPairingURI(invitation)}\\n\\n${waiting}\\n`);\n return { close() {} };\n }\n\n const qr = await createPairingQR(invitation);\n const useScreen = interactive && mode !== \"browser\";\n let closed = false, pageDirectory: string | undefined;\n let browser: \"idle\" | \"opening\" | \"opened\" | \"failed\" = \"idle\";\n let pageURL: string | undefined;\n let browserAttempt: Promise<void> | undefined;\n const fits = () => (output.columns ?? 0) >= qr.columns && (output.rows ?? 0) >= qr.rows;\n const draw = () => {\n if (closed || !useScreen) return;\n let lines: string[];\n if (fits()) {\n lines = [instruction, \"\", ...qr.lines, \"\", waiting];\n } else {\n const size = `Terminal QR needs ${qr.columns} columns × ${qr.rows} rows.`;\n lines = browser === \"opened\" ? [\"QR opened in your browser.\", instruction, nextStep]\n : browser === \"opening\" ? [\"Opening a resizable QR in your browser…\", nextStep]\n : browser === \"failed\" ? [\"Couldn't open a browser here.\", size, \"Enlarge this terminal, or run:\", `${command} --no-qr`]\n : [size, \"Enlarge this terminal, or use --qr browser.\"];\n // Tiny windows may clip instructions; they must never wrap a QR or scroll the display.\n lines = lines.map(line => line.slice(0, Math.max(0, (output.columns ?? 80) - 1)))\n .slice(0, Math.max(0, (output.rows ?? 24) - 1));\n }\n output.write(clearScreen + lines.join(\"\\r\\n\"));\n };\n const ensureBrowser = (): Promise<void> => {\n if (browserAttempt) return browserAttempt;\n browser = \"opening\";\n draw();\n browserAttempt = (async () => {\n try {\n pageDirectory = mkdtempSync(join(tmpdir(), \"mindwire-pair-\"));\n chmodSync(pageDirectory, 0o700);\n const file = join(pageDirectory, \"pair.html\");\n writeFileSync(file, browserPage(invitation, qr.svg), { mode: 0o600 });\n pageURL = pathToFileURL(file).href;\n // An SSH session's browser would be on the remote machine. Keep auto mode local.\n const remoteShell = !!(environment.SSH_CONNECTION || environment.SSH_CLIENT || environment.SSH_TTY);\n const opened = (mode === \"browser\" || !remoteShell) && await (options.openBrowser ?? openBrowser)(pageURL);\n browser = opened ? \"opened\" : \"failed\";\n } catch {\n browser = \"failed\";\n }\n if (closed) return;\n if (useScreen) draw();\n else output.write(browser === \"opened\"\n ? `QR opened in your browser.\\n${instruction}\\n${nextStep}\\n`\n : `Open this local QR page in a browser:\\n${pageURL ?? `Page unavailable. Run ${command} --no-qr for a link.`}\\n\\n${waiting}\\n`);\n })();\n return browserAttempt;\n };\n const resize = () => {\n draw();\n if (!closed && mode === \"auto\" && !fits()) void ensureBrowser();\n };\n const close = () => {\n if (closed) return;\n closed = true;\n output.off(\"resize\", resize);\n process.off(\"exit\", close);\n process.off(\"SIGINT\", interrupt);\n process.off(\"SIGTERM\", terminate);\n process.off(\"SIGHUP\", hangup);\n if (useScreen) output.write(leaveScreen);\n if (pageDirectory) {\n try { rmSync(pageDirectory, { recursive: true, force: true }); } catch { /* Best effort on process exit. */ }\n }\n };\n const interrupt = () => { close(); process.exit(130); };\n const terminate = () => { close(); process.exit(143); };\n const hangup = () => { close(); process.exit(129); };\n process.once(\"exit\", close);\n process.once(\"SIGINT\", interrupt);\n process.once(\"SIGTERM\", terminate);\n process.once(\"SIGHUP\", hangup);\n if (useScreen) {\n output.write(enterScreen);\n output.on(\"resize\", resize);\n draw();\n }\n try {\n if (mode === \"browser\" || (mode === \"auto\" && !fits())) await ensureBrowser();\n return { close };\n } catch (error) {\n close();\n throw error;\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport * as fs from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport * as path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { ensureComputer, readJSON, writeJSON, type ControllerState } from \"./lifecycle.js\";\nimport { currentProcessIdentity, processStateAlive, type ProcessState } from \"./process.js\";\nimport { acquireProcessLock } from \"./lock.js\";\n\nconst execute = promisify(execFile);\ntype Command = [string, ...string[]];\nexport interface StartupPlan {\n kind: \"launchd\" | \"systemd\" | \"task-scheduler\";\n name: string; file: string; content: string;\n query: Command; enable: Command[]; disable: Command[];\n}\nexport interface StartupState { enabled: boolean; running?: boolean; kind?: StartupPlan[\"kind\"]; name?: string; file?: string }\nconst xml = (value: string) => value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\").replace(/'/g, \"&apos;\");\nconst systemd = (value: string, expandEnvironment = false) => '\"' + value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/%/g, \"%%\")\n .replace(/\\$/g, () => expandEnvironment ? \"$$\" : \"$\") + '\"';\nconst windowsArg = (value: string) => '\"' + value.replace(/(\\\\*)\"/g, '$1$1\\\\\"').replace(/(\\\\+)$/g, \"$1$1\") + '\"';\n\n/** Per-user startup, with no root service, password, or copied pairing secret. */\nexport function startupPlan(options: {\n directory: string; cliPath: string; executable?: string; platform?: NodeJS.Platform;\n home?: string; uid?: number; user?: string; environmentPath?: string;\n}): StartupPlan {\n const { directory, cliPath } = options;\n const executable = options.executable ?? process.execPath, home = options.home ?? homedir();\n const platform = options.platform ?? process.platform;\n const environmentPath = options.environmentPath ?? process.env.PATH ?? path.dirname(executable);\n for (const value of [directory, cliPath, executable, home, environmentPath]) {\n if (/[\\r\\n\\x00]/.test(value)) throw new Error(\"Startup paths cannot contain control characters.\");\n }\n const id = createHash(\"sha256\").update(directory).digest(\"hex\").slice(0, 12);\n const name = `sh.mindwire.computer.${id}`;\n const args = [cliPath, \"_watch\", \"--state-dir\", directory];\n if (platform === \"darwin\") {\n const domain = `gui/${options.uid ?? process.getuid?.()}`;\n const file = path.join(home, \"Library\", \"LaunchAgents\", name + \".plist\");\n return { kind: \"launchd\", name, file,\n content: `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\"><dict>\n<key>Label</key><string>${name}</string>\n<key>ProgramArguments</key><array>${[executable, ...args].map(v => `<string>${xml(v)}</string>`).join(\"\")}</array>\n<key>WorkingDirectory</key><string>${xml(home)}</string>\n<key>EnvironmentVariables</key><dict><key>PATH</key><string>${xml(environmentPath)}</string></dict>\n<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>\n<key>ThrottleInterval</key><integer>10</integer>\n<key>StandardOutPath</key><string>${xml(path.join(directory, \"startup.log\"))}</string>\n<key>StandardErrorPath</key><string>${xml(path.join(directory, \"startup.log\"))}</string>\n</dict></plist>\n`, query: [\"launchctl\", \"print\", `${domain}/${name}`],\n enable: [[\"launchctl\", \"enable\", `${domain}/${name}`], [\"launchctl\", \"bootstrap\", domain, file]],\n disable: [[\"launchctl\", \"bootout\", `${domain}/${name}`]] };\n }\n if (platform === \"linux\") {\n const file = path.join(home, \".config\", \"systemd\", \"user\", name + \".service\");\n return { kind: \"systemd\", name, file,\n content: `[Unit]\nDescription=Mindwire computer connection\nAfter=network-online.target\n[Service]\nType=simple\nExecStart=${[executable, ...args].map(value => systemd(value, true)).join(\" \")}\nWorkingDirectory=${systemd(home)}\nEnvironment=${systemd(\"PATH=\" + environmentPath)}\nRestart=always\nRestartSec=10\nKillMode=process\n[Install]\nWantedBy=default.target\n`, query: [\"systemctl\", \"--user\", \"is-active\", name + \".service\"],\n enable: [[\"systemctl\", \"--user\", \"daemon-reload\"], [\"systemctl\", \"--user\", \"enable\", \"--now\", name + \".service\"]],\n disable: [[\"systemctl\", \"--user\", \"disable\", \"--now\", name + \".service\"], [\"systemctl\", \"--user\", \"daemon-reload\"]] };\n }\n if (platform === \"win32\") {\n if (!options.user) throw new Error(\"Couldn't determine the Windows user for startup.\");\n const file = path.join(directory, \"startup-task.xml\");\n return { kind: \"task-scheduler\", name, file,\n content: `<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<Task version=\"1.2\" xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n<Triggers><LogonTrigger><Enabled>true</Enabled><UserId>${xml(options.user)}</UserId></LogonTrigger></Triggers>\n<Principals><Principal id=\"Owner\"><UserId>${xml(options.user)}</UserId><LogonType>InteractiveToken</LogonType><RunLevel>LeastPrivilege</RunLevel></Principal></Principals>\n<Settings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><StartWhenAvailable>true</StartWhenAvailable><ExecutionTimeLimit>PT0S</ExecutionTimeLimit><RestartOnFailure><Interval>PT1M</Interval><Count>999</Count></RestartOnFailure></Settings>\n<Actions Context=\"Owner\"><Exec><Command>${xml(executable)}</Command><Arguments>${xml(args.map(windowsArg).join(\" \"))}</Arguments><WorkingDirectory>${xml(home)}</WorkingDirectory></Exec></Actions>\n</Task>\n`, query: [\"schtasks.exe\", \"/Query\", \"/TN\", name],\n enable: [[\"schtasks.exe\", \"/Create\", \"/TN\", name, \"/XML\", file, \"/F\"], [\"schtasks.exe\", \"/Run\", \"/TN\", name]],\n disable: [[\"schtasks.exe\", \"/End\", \"/TN\", name], [\"schtasks.exe\", \"/Delete\", \"/TN\", name, \"/F\"]] };\n }\n throw new Error(\"Automatic startup supports macOS, Linux with systemd, and Windows. Run mindwire start on this system.\");\n}\n\nconst run = async ([command, ...args]: Command) => { await execute(command, args, { timeout: 15_000, windowsHide: true }); };\nexport async function startupStatus(directory: string): Promise<StartupState> {\n const state = await readJSON<StartupState>(path.join(directory, \"computer-startup.json\")) ?? { enabled: false };\n const guardian = await readJSON<ProcessState>(path.join(directory, \"computer-guardian.json\"));\n return { ...state, running: state.enabled && await processStateAlive(guardian) };\n}\n\nexport async function configureStartup(directory: string, cliPath: string, enabled: boolean, runtime: {\n plan?: StartupPlan; run?: (command: Command) => Promise<void>; verify?: () => Promise<void>;\n} = {}): Promise<StartupState> {\n await fs.mkdir(directory, { recursive: true, mode: 0o700 });\n const lockPath = path.join(directory, \"startup.lock\");\n const lock = await acquireProcessLock(lockPath);\n if (!lock) throw new Error(\"Startup is already being configured. Try again shortly.\");\n try {\n const user = process.platform === \"win32\" && !runtime.plan\n ? (await execute(\"whoami.exe\", [], { timeout: 3000, windowsHide: true })).stdout.trim() : undefined;\n const plan = runtime.plan ?? startupPlan({ directory, cliPath, user });\n const command = runtime.run ?? run;\n let loaded = false;\n try { await command(plan.query); loaded = true; } catch { /* Not installed/loaded. */ }\n if (enabled) {\n const previous = await fs.readFile(plan.file, plan.kind === \"task-scheduler\" ? \"utf16le\" : \"utf8\").catch(() => \"\");\n const changed = previous !== plan.content;\n if (changed) {\n await fs.mkdir(path.dirname(plan.file), { recursive: true, mode: 0o700 });\n const temporary = plan.file + `.tmp-${process.pid}`;\n try {\n await fs.writeFile(temporary, plan.content, { mode: 0o600, encoding: plan.kind === \"task-scheduler\" ? \"utf16le\" : \"utf8\" });\n await fs.rename(temporary, plan.file);\n } finally { await fs.rm(temporary, { force: true }); }\n }\n // Never restart the controller to update its login registration. The\n // currently running service and its terminal processes remain untouched.\n if (!loaded || changed && plan.kind !== \"launchd\") {\n for (const action of plan.enable) await command(action);\n }\n await command(plan.query); // Report success only after native registration.\n if (runtime.verify) await runtime.verify();\n else {\n let running = false;\n for (let attempt = 0; attempt < 60; attempt++) {\n const guardian = await readJSON<ProcessState>(path.join(directory, \"computer-guardian.json\"));\n if (await processStateAlive(guardian)) { running = true; break; }\n await delay(250);\n }\n if (!running) throw new Error(`Automatic startup was registered but its guardian didn't start. Inspect ${path.join(directory, \"startup.log\")}.`);\n }\n } else {\n if (loaded || await fs.stat(plan.file).then(() => true, () => false)) {\n for (const action of plan.disable) {\n try { await command(action); }\n catch (error) { if (action.includes(\"/End\") || action.includes(\"bootout\") && !loaded) continue; throw error; }\n }\n }\n await fs.rm(plan.file, { force: true });\n }\n const state: StartupState = { enabled, kind: plan.kind, name: plan.name, file: plan.file };\n await writeJSON(path.join(directory, \"computer-startup.json\"), state);\n return { ...state, running: enabled };\n } finally { await lock.close(); }\n}\n\n/** Native startup managers supervise this small guardian. It adopts an existing\n * controller and honours an explicit stop; it never owns or kills user work. */\nexport async function watchComputer(directory: string, cliPath: string): Promise<void> {\n let stopping = false;\n const abort = new AbortController();\n const stop = () => { stopping = true; abort.abort(); };\n process.on(\"SIGTERM\", stop); process.on(\"SIGINT\", stop);\n let reportedError = \"\";\n const guardianPath = path.join(directory, \"computer-guardian.json\");\n try {\n await writeJSON(guardianPath, await currentProcessIdentity());\n while (!stopping) {\n const paused = await readJSON<{ stopped: boolean }>(path.join(directory, \"computer-stopped.json\"));\n const controller = await readJSON<ControllerState>(path.join(directory, \"computer-controller.json\"));\n if (!paused?.stopped && !await processStateAlive(controller)) {\n try { await ensureComputer(directory, cliPath, {}, undefined, { resume: false, signal: abort.signal }); reportedError = \"\"; }\n catch (error) {\n if (stopping) break;\n const message = error instanceof Error ? error.message : \"Computer recovery failed.\";\n if (message !== reportedError) { process.stderr.write(`Mindwire recovery: ${message}\\n`); reportedError = message; }\n }\n }\n // A user stop is durable; a reboot or repeated guardian launch won't undo it.\n for (let tick = 0; tick < 10 && !stopping; tick++) await delay(500);\n }\n } finally {\n if ((await readJSON<{ pid: number }>(guardianPath))?.pid === process.pid) await writeJSON(guardianPath, { pid: 0 });\n process.off(\"SIGTERM\", stop); process.off(\"SIGINT\", stop);\n }\n}\n","import type { ComputerReconnectCode, ComputerDevice, ComputerInfo } from \"../computer.js\";\n\nexport type ConnectionAction = \"resume\" | \"reconnect\" | \"pair\";\n\nexport function connectionAction(value: string | undefined): ConnectionAction | undefined {\n if (value === undefined) return undefined;\n if (value === \"resume\" || value === \"reconnect\" || value === \"pair\") return value;\n throw new Error(\"Use mindwire connect, mindwire connect resume, mindwire reconnect, or mindwire connect pair.\");\n}\n\n/** Safe to copy into either a Unix shell or PowerShell, even when an ID starts\n * with a dash. Validate old daemons too; these values originated on a phone. */\nexport function approvalCommand(pairingId: string, requestId: string): string {\n if (![pairingId, requestId].every(id => /^[A-Za-z0-9_-]{8,128}$/.test(id))) {\n throw new Error(\"Invalid phone pairing request. Run mindwire connect to create a new code.\");\n }\n return `mindwire approve -- ${pairingId} ${requestId}`;\n}\n\n/** Saved approvals do not prove that the phone still has its key or address.\n * Every disconnected phone uses the same QR; the signed handshake chooses resume\n * or fresh approval. The old commands remain aliases, not separate UX paths. */\nexport async function chooseConnectionAction(options: {\n requested?: ConnectionAction;\n devices: ComputerDevice[];\n}): Promise<ConnectionAction> {\n if (options.requested === \"pair\" || options.requested === \"reconnect\") return \"pair\";\n return options.devices.some(device => !device.revoked && device.connected) ? \"resume\" : \"pair\";\n}\n\n/** A fresh key is never merged by name. Replacement requires the owner's explicit\n * choice of the exact approvals shown here; a different same-name phone can be added. */\nexport async function choosePairingDecision(options: {\n replacements: ComputerDevice[];\n question: (prompt: string) => Promise<string>;\n}): Promise<{ approve: boolean; replaceDeviceIds?: string[] }> {\n const replacements = options.replacements.filter(device => !device.revoked);\n const prompt = replacements.length\n ? `\\nPrevious approvals with this name:\\n${deviceSummary(replacements, true)}\\n\\nAllow this phone? [r = replace these approvals, a = add a different phone, N = deny]: `\n : \"Allow this phone to access this computer? [y/N] \";\n for (;;) {\n const answer = (await options.question(prompt)).trim().toLowerCase();\n if ([\"\", \"n\", \"no\"].includes(answer)) return { approve: false };\n if (replacements.length) {\n if ([\"r\", \"replace\"].includes(answer)) return { approve: true, replaceDeviceIds: replacements.map(device => device.id) };\n if ([\"a\", \"add\"].includes(answer)) return { approve: true };\n } else if ([\"y\", \"yes\"].includes(answer)) return { approve: true };\n }\n}\n\n/** Ask once; preserve existing opt-outs. Scripts must opt in with --startup. */\nexport async function chooseStartupAction(options: {\n state: { enabled: boolean; running?: boolean; kind?: string };\n startup?: boolean;\n noStartup?: boolean;\n question?: (prompt: string) => Promise<string>;\n}): Promise<boolean | undefined> {\n if (options.startup && options.noStartup) throw new Error(\"Choose either --startup or --no-startup.\");\n if (options.startup) return !options.state.enabled || !options.state.running ? true : undefined;\n if (options.noStartup) return options.state.kind ? undefined : false;\n if (options.state.kind) return options.state.enabled && !options.state.running ? true : undefined;\n if (!options.question) return undefined;\n for (;;) {\n const answer = (await options.question(\n \"\\nStart Mindwire automatically after you sign in to this computer? [Y/n] \")).trim().toLowerCase();\n if ([\"\", \"y\", \"yes\"].includes(answer)) return true;\n if ([\"n\", \"no\"].includes(answer)) return false;\n }\n}\n\nexport function reconnectCode(info: ComputerInfo, name: string, now = new Date()): ComputerReconnectCode {\n if (info.routes.length === 0) throw new Error(\"No connection address is ready. Run mindwire status and retry once the tunnel is online.\");\n return { version: 1, mode: \"reconnect\", computerId: info.computerId, registryId: info.registryId,\n fingerprint: info.fingerprint, name, routes: info.routes,\n expiresAt: new Date(now.getTime() + 5 * 60_000).toISOString() };\n}\n\nexport function deviceSummary(devices: ComputerDevice[], showKeys = false): string {\n const saved = devices.filter(device => !device.revoked);\n const names = new Map<string, number>();\n const safeName = (device: ComputerDevice) => device.name.replace(/[\\x00-\\x1f\\x7f-\\x9f]/g, \"\");\n for (const device of saved) names.set(safeName(device), (names.get(safeName(device)) ?? 0) + 1);\n return saved\n .sort((a, b) => a.name.localeCompare(b.name) || a.id.localeCompare(b.id))\n .map(device => {\n const name = safeName(device);\n const status = device.connected === true ? \"connected\" : \"paired\";\n const identity = showKeys || (names.get(name) ?? 0) > 1 ? ` · key ${device.id.slice(0, 8)}` : \"\";\n return ` ${name} · ${status}${identity}`;\n }).join(\"\\n\");\n}\n","import { clearLine, cursorTo } from \"node:readline\";\n\n/** One terminal line for one connection attempt. JSON and redirected output\n * keep their normal events; interactive retries don't accumulate a wall of logs. */\nexport class ConnectionProgress {\n private readonly startedAt = Date.now();\n private readonly timer: ReturnType<typeof setInterval>;\n private message = \"Starting Mindwire…\";\n private closed = false;\n private readonly exiting = () => this.close();\n\n constructor(private readonly stream: NodeJS.WriteStream) {\n this.render();\n this.timer = setInterval(() => this.render(), 1000);\n this.timer.unref();\n process.once(\"exit\", this.exiting);\n }\n\n update(message: string): void { this.message = message; this.render(); }\n\n close(): void {\n if (this.closed) return;\n this.closed = true;\n clearInterval(this.timer);\n process.off(\"exit\", this.exiting);\n cursorTo(this.stream, 0);\n clearLine(this.stream, 0);\n }\n\n private render(): void {\n const seconds = Math.floor((Date.now() - this.startedAt) / 1000);\n const elapsed = seconds > 0 ? ` · ${seconds}s` : \"\";\n const width = Math.max(1, (this.stream.columns || 80) - elapsed.length - 1);\n const message = this.message.replace(/[\\x00-\\x1f\\x7f-\\x9f]/g, \"\");\n const text = message.length > width ? message.slice(0, width - 1) + \"…\" : message;\n cursorTo(this.stream, 0);\n clearLine(this.stream, 0);\n this.stream.write(text + elapsed);\n }\n}\n","#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { fileURLToPath } from \"node:url\";\nimport { realpathSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { createInterface } from \"node:readline/promises\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { computerPairingURI, type ComputerUpdate } from \"./computer.js\";\nimport { SDK_VERSION } from \"./version.js\";\nimport { computerClient, defaultStateDirectory, ensureComputer, readJSON, stopComputer, superviseComputer, type ComputerConfig } from \"./computer/lifecycle.js\";\nimport type { RelayOptions } from \"./computer/relay.js\";\nimport { showPairingInvitation, type PairingQRMode } from \"./computer/pairing-display.js\";\nimport { configureStartup, startupStatus, watchComputer } from \"./computer/startup.js\";\nimport { approvalCommand, chooseConnectionAction, choosePairingDecision, chooseStartupAction, connectionAction, deviceSummary } from \"./computer/connection-flow.js\";\nimport { ConnectionProgress } from \"./computer/connection-progress.js\";\n\nconst help = `Mindwire — connect this computer to your phone\n\n npm install -g mindwire\n mindwire connect Connect your phone; saved keys reconnect automatically\n mindwire reconnect Show a connection QR again (also repairs a missing pairing)\n mindwire connect pair Pair another phone with this computer\n mindwire connect --relay none --host laptop.tailnet Use your existing VPN\n mindwire connect --relay none Direct SSH only (reachable network required)\n mindwire connect --relay cloudflare Cloudflare quick tunnel\n mindwire connect --relay ngrok ngrok (uses its configured account)\n mindwire connect --relay custom --relay-url wss://computer.example/ssh\n\n mindwire start Start the saved connection in the background\n mindwire startup enable|disable Manage automatic startup after computer login\n mindwire startup status Check automatic startup\n mindwire status Show connection and running service\n mindwire devices List paired phones\n mindwire revoke DEVICE_ID Disconnect and revoke one phone\n mindwire update [--version VERSION] Download a verified release; wait until idle\n mindwire stop Stop when no work or terminals are running\n\nOptions:\n --directory PATH Initial workspace directory (default: home)\n --host HOST Reachable LAN, public or VPN hostname\n --relay none|cloudflare|ngrok|custom Provider (default: Cloudflare internet tunnel)\n --relay-url URL Stable configured WebSocket hostname\n --cloudflare-token-file PATH Named Cloudflare tunnel token file\n --state-dir PATH Private state directory\n --json Structured output (QR invitation includes a secret)\n --qr auto|terminal|browser Fit the QR to your terminal or open a local page\n --no-qr Print only the pairing link\n --startup Enable automatic startup without a prompt\n --no-startup Skip automatic startup setup\n --replace-device DEVICE_ID With approve: replace a lost phone key (repeatable)\n\nThe default works across Wi-Fi and mobile networks. Mindwire privately downloads\na verified Cloudflare helper when needed. Relays carry encrypted SSH.\nQuick tunnel addresses change on restart; use a stable hostname/VPN for regular use.\nngrok needs its installed CLI and account. Direct SSH needs no relay when reachable.\nNothing changes your system SSH login.\n`;\n\nfunction safeName(text: string): string { return text.replace(/[\\x00-\\x1f\\x7f-\\x9f]/g, \"\"); }\n\nexport async function main(args = process.argv.slice(2)): Promise<void> {\n const { values, positionals } = parseArgs({ args, allowPositionals: true, options: {\n help: { type: \"boolean\", short: \"h\" }, json: { type: \"boolean\" }, \"no-qr\": { type: \"boolean\" }, qr: { type: \"string\" },\n \"state-dir\": { type: \"string\" }, directory: { type: \"string\" }, host: { type: \"string\" },\n relay: { type: \"string\" }, \"relay-url\": { type: \"string\" }, \"cloudflare-token-file\": { type: \"string\" },\n \"daemon-bin\": { type: \"string\" }, bind: { type: \"string\" }, port: { type: \"string\" }, \"websocket-port\": { type: \"string\" },\n version: { type: \"string\" }, force: { type: \"boolean\" }, startup: { type: \"boolean\" }, \"no-startup\": { type: \"boolean\" },\n \"replace-device\": { type: \"string\", multiple: true },\n } });\n const command = positionals[0] ?? \"help\";\n if (values.help || command === \"help\") { process.stdout.write(help); return; }\n if (values.qr && ![\"auto\", \"terminal\", \"browser\"].includes(values.qr)) throw new Error(\"Choose --qr auto, terminal or browser.\");\n if (values.startup && values[\"no-startup\"]) throw new Error(\"Choose either --startup or --no-startup.\");\n const directory = path.resolve(values[\"state-dir\"] ?? defaultStateDirectory());\n const emit = (event: string, data: object = {}, text?: string) => {\n if (values.json) process.stdout.write(JSON.stringify({ event, ...data }) + \"\\n\");\n else if (text) process.stdout.write(text + \"\\n\");\n };\n if (command === \"_serve\") { await superviseComputer(directory); return; }\n if (command === \"_watch\") { await watchComputer(directory, fileURLToPath(import.meta.url)); return; }\n if (command === \"startup\") {\n const action = positionals[1] ?? \"status\";\n if (![\"enable\", \"disable\", \"status\"].includes(action)) throw new Error(\"Use mindwire startup enable, disable or status.\");\n const state = action === \"status\" ? await startupStatus(directory)\n : await configureStartup(directory, fileURLToPath(import.meta.url), action === \"enable\");\n emit(\"startup\", state, state.enabled ? \"Mindwire starts after you sign in to this computer and recovers automatically.\"\n : \"Automatic startup is off. Use mindwire start to run the service.\");\n return;\n }\n if ([\"connect\", \"start\", \"reconnect\"].includes(command)) {\n const requestedAction = command === \"reconnect\" ? \"reconnect\" : command === \"connect\" ? connectionAction(positionals[1]) : undefined;\n const patch: Partial<ComputerConfig> = {};\n if (values.directory) patch.directory = path.resolve(values.directory);\n if (values.host) patch.host = values.host;\n if (values.bind) patch.bind = values.bind;\n for (const [flag, field] of [[\"port\", \"sshPort\"], [\"websocket-port\", \"websocketPort\"]] as const) {\n if (values[flag] !== undefined) {\n const n = Number(values[flag]);\n if (!Number.isInteger(n) || n < 0 || n > 65535) throw new Error(`Invalid --${flag}.`);\n patch[field] = n;\n }\n }\n if (values[\"daemon-bin\"] || process.env.MINDWIRE_DAEMON) patch.daemonBin = path.resolve(values[\"daemon-bin\"] ?? process.env.MINDWIRE_DAEMON!);\n if (values.version) patch.version = values.version.replace(/^v/, \"\");\n if (values.relay || values[\"relay-url\"] || values[\"cloudflare-token-file\"]) {\n const kind = values.relay ?? \"custom\";\n if (![\"none\", \"cloudflare\", \"ngrok\", \"custom\"].includes(kind)) throw new Error(\"Choose relay none, cloudflare, ngrok or custom.\");\n patch.relay = { kind: kind as RelayOptions[\"kind\"], url: values[\"relay-url\"],\n cloudflareTokenFile: values[\"cloudflare-token-file\"] ? path.resolve(values[\"cloudflare-token-file\"]) : undefined };\n }\n const progress = !values.json && process.stderr.isTTY && process.env.TERM !== \"dumb\" ? new ConnectionProgress(process.stderr) : undefined;\n emit(\"starting\", {}, progress ? undefined : \"Starting Mindwire…\");\n const client = await ensureComputer(directory, fileURLToPath(import.meta.url), patch, phase => {\n if (progress) progress.update(phase);\n else emit(\"progress\", { message: phase }, phase);\n }).finally(() => progress?.close());\n const info = await client.computer.info();\n emit(\"ready\", { computerId: info.computerId, routes: info.routes }, \"Mindwire is running in the background.\");\n if (command === \"start\") return;\n if (info.routes.some(route => route.kind === \"websocket\")) {\n emit(\"secure_connection\", {}, \"Your phone connects over end-to-end encrypted SSH. The tunnel carries encrypted traffic; only phones you approve can connect.\");\n }\n const devices = await client.computer.devices();\n const saved = devices.filter(device => !device.revoked);\n if (saved.length) emit(\"saved_devices\", { devices: saved }, `\\nSaved approvals on this computer\\n${deviceSummary(saved)}`);\n const question = !values.json && process.stdin.isTTY ? async (prompt: string): Promise<string> => {\n const input = createInterface({ input: process.stdin, output: process.stderr });\n try { return await input.question(prompt); } finally { input.close(); }\n } : undefined;\n const action = await chooseConnectionAction({ requested: requestedAction, devices });\n const startupPreference = await startupStatus(directory);\n const startupAction = await chooseStartupAction({ state: startupPreference,\n startup: values.startup, noStartup: values[\"no-startup\"],\n question: action === \"pair\" && saved.length === 0 ? question : undefined });\n if (startupAction !== undefined) {\n try {\n const startup = await configureStartup(directory, fileURLToPath(import.meta.url), startupAction);\n emit(\"startup\", startup, startup.enabled\n ? \"Automatic startup enabled. Saved phones can reconnect after you sign in to this computer.\"\n : \"Automatic startup is off. Run mindwire connect after restarting, or mindwire startup enable to change this.\");\n } catch {\n emit(\"startup_unavailable\", {}, \"Mindwire is running, but startup setup didn't complete. Run mindwire startup enable to check your system's startup service.\");\n }\n } else {\n emit(\"startup\", startupPreference, startupPreference.enabled\n ? \"Automatic startup is on. Change it with mindwire startup disable.\"\n : \"Automatic startup is off. Enable it with mindwire startup enable.\");\n }\n if (action === \"resume\") {\n const connected = saved.filter(device => device.connected);\n emit(\"connected\", { computerId: info.computerId, devices: connected }, `\\nConnected:\\n${deviceSummary(connected)}\\nMindwire continues running in the background.`);\n emit(\"connect_hint\", {}, \"To scan again or add a phone, run mindwire reconnect.\");\n return;\n }\n const invitation = await client.computer.invite((await client.computer.info()).routes);\n const uri = computerPairingURI(invitation);\n emit(\"invitation\", { invitation, uri });\n const display = values.json ? undefined : await showPairingInvitation(invitation, {\n mode: values[\"no-qr\"] ? \"none\" : (values.qr ?? \"auto\") as PairingQRMode,\n });\n try {\n let shownRequest: string | undefined;\n let authorized = false;\n while (Date.now() < Date.parse(invitation.expiresAt)) {\n const pairing = await client.computer.pairing(invitation.pairingId);\n if (pairing.status === \"waiting\" && requestedAction !== \"pair\" && requestedAction !== \"reconnect\") {\n const connected = (await client.computer.devices()).filter(device => !device.revoked && device.connected);\n if (connected.length && ((info.pairingVersion ?? 0) < 2 || (await client.computer.closeUnusedPairing(invitation.pairingId)).cancelled)) {\n display?.close();\n emit(\"connected\", { computerId: info.computerId, devices: connected }, `Connected:\\n${deviceSummary(connected)}\\nMindwire continues running in the background.`);\n return;\n }\n }\n if (pairing.status === \"approved\") {\n display?.close();\n if (pairing.completed) {\n emit(\"paired\", { computerId: info.computerId, completed: true }, \"Phone connected and saved. You can close this terminal; Mindwire keeps running.\");\n return;\n }\n if (!authorized) {\n authorized = true;\n emit(\"authorized\", {}, \"Phone approved. Keep Mindwire open on your phone while it saves the connection…\");\n }\n await delay(750);\n continue;\n }\n if (pairing.status === \"rejected\") { display?.close(); emit(\"rejected\", {}, \"Pairing declined.\"); return; }\n if (pairing.request && shownRequest !== pairing.request.id) {\n display?.close();\n shownRequest = pairing.request.id;\n const key = Buffer.from(pairing.request.publicKey.split(\" \")[1] ?? \"\", \"base64\");\n const fingerprint = \"SHA256:\" + createHash(\"sha256\").update(key).digest(\"base64\").replace(/=+$/, \"\");\n const deviceId = createHash(\"sha256\").update(key).digest(\"base64url\");\n const replacements = (info.pairingVersion ?? 0) >= 2 ? (await client.computer.devices()).filter(device =>\n !device.revoked && device.id !== deviceId && device.name === pairing.request!.name) : [];\n emit(\"approval_required\", { pairingId: invitation.pairingId, request: pairing.request, fingerprint, replacements },\n `\\n${safeName(pairing.request.name)} wants to connect.\\nDevice key: ${fingerprint}\\nAccess: files and commands as your computer account.`);\n if (!question) {\n const command = approvalCommand(invitation.pairingId, pairing.request.id);\n emit(\"approval_command\", { command }, `Review this device, then run:\\n${command}`);\n } else {\n const decision = await choosePairingDecision({ replacements, question });\n await client.computer.decide(invitation.pairingId, pairing.request.id, decision.approve,\n decision.replaceDeviceIds ? { replaceDeviceIds: decision.replaceDeviceIds } : {});\n }\n }\n await delay(750);\n }\n throw new Error(authorized\n ? \"The phone was approved but did not finish saving. Run mindwire connect and scan again; its saved key will be reused.\"\n : \"Connection code expired. Run mindwire connect to show a new QR code.\");\n } finally { display?.close(); }\n }\n if (command === \"stop\") { await stopComputer(directory, values.force === true); emit(\"stopped\", {}, \"Mindwire stopped.\"); return; }\n const client = await computerClient(directory);\n switch (command) {\n case \"status\": {\n const [info, health, work, controller, startup] = await Promise.all([client.computer.info(), client.health(), client.service.updateStatus(),\n readJSON<{ error?: string; errorCode?: string; phase?: string; recovering?: boolean }>(path.join(directory, \"computer-controller.json\")), startupStatus(directory)]);\n emit(\"status\", { ...info, daemonVersion: health.version, ...work, startup, recovering: controller?.recovering, relayError: controller?.error, relayErrorCode: controller?.errorCode },\n `Mindwire ${health.version} · ${work.idle ? \"idle\" : \"working\"}\\nStartup: ${startup.enabled ? \"on\" : \"off\"}\\n${info.routes.map(route => route.kind === \"ssh\" ? `SSH ${route.host}:${route.port}` : route.url).join(\"\\n\")}${controller?.error ? `\\n${controller.error}` : \"\"}`);\n break;\n }\n case \"devices\": {\n const devices = await client.computer.devices();\n emit(\"devices\", { devices }, devices.length ? devices.map(d => `${safeName(d.name)} ${d.id}${d.revoked ? \" (revoked)\" : \"\"}`).join(\"\\n\") : \"No paired phones yet. Run mindwire connect.\");\n break;\n }\n case \"revoke\": {\n if (!positionals[1]) throw new Error(\"Use mindwire revoke DEVICE_ID (from mindwire devices).\");\n await client.computer.revoke(positionals[1]); emit(\"revoked\", {}, \"Device revoked and disconnected.\"); break;\n }\n case \"approve\": case \"reject\": {\n if (!positionals[1] || !positionals[2]) throw new Error(`Use mindwire ${command} PAIRING_ID REQUEST_ID.`);\n await client.computer.decide(positionals[1], positionals[2], command === \"approve\",\n values[\"replace-device\"] ? { replaceDeviceIds: values[\"replace-device\"] } : {});\n emit(command, {}, command === \"approve\" ? \"Phone approved. Waiting for it to save the connection.\" : \"Phone declined.\"); break;\n }\n case \"update\": {\n const version = (values.version ?? SDK_VERSION).replace(/^v/, \"\");\n const health = await client.health();\n if (health.version.replace(/^v/, \"\") === version) { emit(\"updated\", { version }, `Mindwire ${version} is already installed.`); return; }\n const requested = await client.computer.requestUpdate(version);\n emit(\"update_queued\", requested, \"Update queued. It will wait until all work and terminals are finished.\");\n let last = \"\";\n for (;;) {\n const update = await readJSON<ComputerUpdate>(path.join(directory, \"computer-update.json\"));\n if (update?.id !== requested.id) throw new Error(\"The update request changed. Run mindwire status.\");\n if (update.status !== last) { last = update.status; emit(\"update\", update, `Update: ${update.status}`); }\n if (update.status === \"complete\") return;\n if (update.status === \"failed\") throw new Error(update.error ?? \"Update failed.\");\n await delay(750);\n }\n }\n default: throw new Error(`Unknown command ${command}. Run mindwire --help.`);\n }\n}\n\nfunction isCLIEntry(): boolean {\n if (!process.argv[1]) return false;\n try {\n // npm links its bin command: argv keeps the link, while ESM resolves the module.\n return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url));\n } catch {\n // Importing the CLI from an eval or another program must not start a service.\n return false;\n }\n}\n\nif (isCLIEntry()) {\n void main().catch(error => {\n const message = error instanceof Error ? error.message : String(error);\n if (process.argv.includes(\"--json\")) process.stderr.write(JSON.stringify({ event: \"error\", message }) + \"\\n\");\n else process.stderr.write(`Mindwire: ${message}\\n`);\n process.exitCode = 1;\n });\n}\n"]}
@@ -0,0 +1,14 @@
1
+ /** One terminal line for one connection attempt. JSON and redirected output
2
+ * keep their normal events; interactive retries don't accumulate a wall of logs. */
3
+ export declare class ConnectionProgress {
4
+ private readonly stream;
5
+ private readonly startedAt;
6
+ private readonly timer;
7
+ private message;
8
+ private closed;
9
+ private readonly exiting;
10
+ constructor(stream: NodeJS.WriteStream);
11
+ update(message: string): void;
12
+ close(): void;
13
+ private render;
14
+ }
@@ -19,6 +19,7 @@ export interface ControllerState extends ProcessState {
19
19
  ready: boolean;
20
20
  phase?: string;
21
21
  error?: string;
22
+ errorCode?: string;
22
23
  recovering?: boolean;
23
24
  routes?: ComputerRoute[];
24
25
  checkedAt?: number;
@@ -1,10 +1,20 @@
1
+ import type { LookupFunction } from "node:net";
1
2
  import type { ComputerRoute } from "../computer.js";
2
3
  import type { RelayOptions } from "./relay.js";
4
+ export declare class RelayCheckError extends Error {
5
+ readonly code: "dns" | "timeout" | "proxy" | "connection" | "response";
6
+ constructor(code: "dns" | "timeout" | "proxy" | "connection" | "response", message: string, cause?: Error);
7
+ }
8
+ /** A resolver's negative cache says nothing about the helper's connection.
9
+ * Rotating a live tunnel for NXDOMAIN creates another hostname to cache and
10
+ * strands phones with the previous address. Process exits are handled separately. */
11
+ export declare function relayNeedsRestart(error: unknown, failures: number, failedForMs: number): boolean;
3
12
  /** Check the actual WebSocket byte path, not just the helper's PID or its logs.
4
13
  * The phone still authenticates and pins the SSH host before sending secrets. */
5
14
  export declare function checkRelay(route: ComputerRoute, options?: {
6
15
  signal?: AbortSignal;
7
16
  timeoutMs?: number;
17
+ lookup?: LookupFunction;
8
18
  }): Promise<void>;
9
19
  /** Don't rotate a quick-tunnel address during an ordinary internet outage.
10
20
  * Let the provider reconnect with the same address until it is reachable again. */
@@ -0,0 +1,19 @@
1
+ /** A provider must not inherit pipes whose reader dies during a controller
2
+ * upgrade. Use a private append-only file descriptor, consume startup output,
3
+ * then discard it. A successor can adopt the same file without touching the
4
+ * provider or its address. Raw provider output is never copied to our logs. */
5
+ export declare class RelayOutput {
6
+ readonly file: string;
7
+ private readonly handle;
8
+ private position;
9
+ private timer?;
10
+ private pending;
11
+ private closing?;
12
+ private constructor();
13
+ static create(directory?: string): Promise<RelayOutput>;
14
+ static adopt(directory: string, file: string): Promise<RelayOutput | undefined>;
15
+ get fd(): number;
16
+ read(): Promise<Buffer>;
17
+ discard(): void;
18
+ close(): Promise<void>;
19
+ }
@@ -11,13 +11,16 @@ export interface RelayHandle {
11
11
  route?: ComputerRoute;
12
12
  process?: ChildProcess;
13
13
  owner?: OwnedProcess;
14
+ outputFile?: string;
14
15
  close(): void | Promise<void>;
15
16
  }
17
+ export declare function adoptRelay(owner: OwnedProcess, route: ComputerRoute | undefined, directory: string, outputFile?: string): Promise<RelayHandle>;
16
18
  export declare function websocketURL(value: string): string;
17
19
  /** Both providers forward encrypted SSH bytes to one loopback WebSocket bridge. */
18
20
  export declare function startRelay(options: RelayOptions, port: number, runtime?: {
19
21
  cacheDir?: string;
22
+ outputDirectory?: string;
20
23
  onProgress?: (message: string) => void | Promise<void>;
21
24
  signal?: AbortSignal;
22
- onSpawn?: (owner: OwnedProcess) => Promise<void>;
25
+ onSpawn?: (owner: OwnedProcess, outputFile: string) => Promise<void>;
23
26
  }): Promise<RelayHandle>;