@miraland-labs/conduit-bridge 0.16.19 → 0.16.20

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Local Bridge CLI for [Conduit](https://github.com/miralandlabs/conduit). Connects a computer to one organization, claims work, and drives a local agent.
4
4
 
5
- **Package version:** `0.16.19` — `ops.env` is enrollment/bootstrap defaults only: an explicit workspace does not inherit an old repository, and project switches do not rewrite global project state. `ops enroll` exchanges a single-use token, registers the machine, binds project affinity, provisions fuel keys, brings detected drivers online, and starts the runner in one command. On Linux, `ops install` refuses any effective systemd drop-in. A switch intent remains queued until the target runner heartbeat proves Bound. After every Bridge publish, operators must re-run `ops install` (LaunchAgent pins an absolute `cli.js`).
5
+ **Package version:** `0.16.20` — `ops disconnect` now asks before it removes the runner service and clears credentials; pass `--yes` to skip the question. `ops.env` is enrollment/bootstrap defaults only: an explicit workspace does not inherit an old repository, and project switches do not rewrite global project state. `ops enroll` exchanges a single-use token, registers the machine, binds project affinity, provisions fuel keys, brings detected drivers online, and starts the runner in one command. On Linux, `ops install` refuses any effective systemd drop-in. A switch intent remains queued until the target runner heartbeat proves Bound. After every Bridge publish, operators must re-run `ops install` (LaunchAgent pins an absolute `cli.js`).
6
6
 
7
7
  ## Prerequisites
8
8
 
package/dist/cli.js CHANGED
@@ -371,7 +371,7 @@ async function initOps() {
371
371
  console.log(`Config file (separate): ${envPath}`);
372
372
  console.log("");
373
373
  console.log("Works the same on macOS, Linux, and Windows via:");
374
- console.log(` ${bridgeUsage("ops", "<connect|install|switch|online|offline|status|disconnect|uninstall>")}`);
374
+ console.log(` ${bridgeUsage("ops", "<connect|install|switch|online|offline|status|doctor|disconnect|uninstall>")}`);
375
375
  console.log("");
376
376
  console.log("1. Set enrollment/bootstrap defaults once:");
377
377
  console.log(` Create folder: ${configDir}`);
package/dist/ops.js CHANGED
@@ -6,6 +6,8 @@ import { spawnSync } from "node:child_process";
6
6
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
7
  import { homedir } from "node:os";
8
8
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
9
+ import { stdin as input, stdout as output } from "node:process";
10
+ import { createInterface } from "node:readline/promises";
9
11
  import { parseArgs } from "node:util";
10
12
  import { ConduitClient } from "./client.js";
11
13
  import { loadConfig } from "./config.js";
@@ -51,7 +53,7 @@ export function expandOpsValue(value, home = homedir()) {
51
53
  }
52
54
  next = next.replace(/%USERPROFILE%/gi, home).replace(/%HOME%/gi, home);
53
55
  next = next.replace(/\$HOME\b/g, home).replace(/\$\{HOME\}/g, home);
54
- if (next.startsWith("~/") || next === "~")
56
+ if (next.startsWith("~/") || next.startsWith("~\\") || next === "~")
55
57
  next = join(home, next.slice(2));
56
58
  return next;
57
59
  }
@@ -67,7 +69,12 @@ export function parseOpsEnvFile(text, home = homedir()) {
67
69
  const key = line.slice(0, eq).trim();
68
70
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
69
71
  continue;
70
- out[key] = expandOpsValue(line.slice(eq + 1), home);
72
+ // Drop a trailing annotation such as `CONDUIT_WORKSPACE=$HOME/repo # laptop`, so it does not
73
+ // become part of the path. A quoted value keeps everything inside its quotes, and a `#` with no
74
+ // space before it stays in the value.
75
+ const rawValue = line.slice(eq + 1).trim();
76
+ const quoted = rawValue.startsWith('"') || rawValue.startsWith("'");
77
+ out[key] = expandOpsValue(quoted ? rawValue : rawValue.replace(/\s+#.*$/, ""), home);
71
78
  }
72
79
  return out;
73
80
  }
@@ -185,6 +192,20 @@ export function shellQuoteArgs(args) {
185
192
  return `"${arg.replaceAll('"', '\\"')}"`;
186
193
  }).join(" ");
187
194
  }
195
+ /** Ask the operator to approve a step that cannot be undone. Non-interactive shells must pass --yes. */
196
+ async function confirmOps(question) {
197
+ if (!input.isTTY || !output.isTTY) {
198
+ throw new Error("This step needs confirmation. Re-run with --yes to approve it without a prompt.");
199
+ }
200
+ const rl = createInterface({ input, output });
201
+ try {
202
+ const answer = (await rl.question(question)).trim().toLowerCase();
203
+ return answer === "y" || answer === "yes";
204
+ }
205
+ finally {
206
+ rl.close();
207
+ }
208
+ }
188
209
  function defaultRunBridge(args, options = {}) {
189
210
  // Re-enter this package's CLI in a child so ops stays a thin orchestrator.
190
211
  const cli = process.argv[1];
@@ -205,6 +226,13 @@ export async function runOps(verb, argv = [], deps = {}) {
205
226
  const runBridge = deps.runBridge ?? defaultRunBridge;
206
227
  const env = deps.env ?? loadOpsEnv();
207
228
  if (verb === "disconnect") {
229
+ // Ask here, not in the child command: this verb also removes the runner service, and the
230
+ // child's own prompt would come too late to stop that.
231
+ const approved = argv.includes("--yes") || argv.includes("-y") || await (deps.confirm ?? confirmOps)("Disengage this computer from the organization, remove the runner service, and clear local credentials? [y/N] ");
232
+ if (!approved) {
233
+ console.log("Cancelled.");
234
+ return;
235
+ }
208
236
  runBridge(["uninstall-service"], { allowFail: true });
209
237
  runBridge(["disconnect", "--yes"]);
210
238
  console.log("Disconnected. Run: npx @miraland-labs/conduit-bridge@latest ops connect");
@@ -4,5 +4,5 @@ if "%~1"=="" (
4
4
  echo Usage: %~nx0 ^<connect^|install^|online^|offline^|status^|doctor^|disconnect^|uninstall^> [args…]
5
5
  exit /b 1
6
6
  )
7
- npx --yes @miraland-labs/conduit-bridge@latest ops %*
7
+ call npx --yes @miraland-labs/conduit-bridge@latest ops %*
8
8
  if errorlevel 1 exit /b %errorlevel%
package/ops/connect.cmd CHANGED
@@ -1,4 +1,4 @@
1
1
  @echo off
2
2
  REM Windows launcher. macOS/Linux: use connect.sh
3
- npx --yes @miraland-labs/conduit-bridge@latest ops connect %*
3
+ call npx --yes @miraland-labs/conduit-bridge@latest ops connect %*
4
4
  if errorlevel 1 exit /b %errorlevel%
@@ -1,4 +1,4 @@
1
1
  @echo off
2
2
  REM Windows launcher. macOS/Linux: use disconnect.sh
3
- npx --yes @miraland-labs/conduit-bridge@latest ops disconnect %*
3
+ call npx --yes @miraland-labs/conduit-bridge@latest ops disconnect %*
4
4
  if errorlevel 1 exit /b %errorlevel%
package/ops/doctor.cmd CHANGED
@@ -1,3 +1,3 @@
1
1
  @echo off
2
- npx --yes @miraland-labs/conduit-bridge@latest ops doctor %*
2
+ call npx --yes @miraland-labs/conduit-bridge@latest ops doctor %*
3
3
  if errorlevel 1 exit /b %errorlevel%
package/ops/install.cmd CHANGED
@@ -1,4 +1,4 @@
1
1
  @echo off
2
2
  REM Windows launcher. macOS/Linux: use install.sh
3
- npx --yes @miraland-labs/conduit-bridge@latest ops install %*
3
+ call npx --yes @miraland-labs/conduit-bridge@latest ops install %*
4
4
  if errorlevel 1 exit /b %errorlevel%
package/ops/offline.cmd CHANGED
@@ -1,4 +1,4 @@
1
1
  @echo off
2
2
  REM Windows launcher. macOS/Linux: use offline.sh
3
- npx --yes @miraland-labs/conduit-bridge@latest ops offline %*
3
+ call npx --yes @miraland-labs/conduit-bridge@latest ops offline %*
4
4
  if errorlevel 1 exit /b %errorlevel%
package/ops/online.cmd CHANGED
@@ -1,4 +1,4 @@
1
1
  @echo off
2
2
  REM Windows launcher. macOS/Linux: use online.sh
3
- npx --yes @miraland-labs/conduit-bridge@latest ops online %*
3
+ call npx --yes @miraland-labs/conduit-bridge@latest ops online %*
4
4
  if errorlevel 1 exit /b %errorlevel%
package/ops/status.cmd CHANGED
@@ -1,4 +1,4 @@
1
1
  @echo off
2
2
  REM Windows launcher. macOS/Linux: use status.sh
3
- npx --yes @miraland-labs/conduit-bridge@latest ops status %*
3
+ call npx --yes @miraland-labs/conduit-bridge@latest ops status %*
4
4
  if errorlevel 1 exit /b %errorlevel%
package/ops/uninstall.cmd CHANGED
@@ -1,4 +1,4 @@
1
1
  @echo off
2
2
  REM Windows launcher. macOS/Linux: use uninstall.sh
3
- npx --yes @miraland-labs/conduit-bridge@latest ops uninstall %*
3
+ call npx --yes @miraland-labs/conduit-bridge@latest ops uninstall %*
4
4
  if errorlevel 1 exit /b %errorlevel%
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miraland-labs/conduit-bridge",
3
- "version": "0.16.19",
3
+ "version": "0.16.20",
4
4
  "description": "Conduit Bridge CLI — join, connect, disconnect, multi-driver lanes, and run Claude Code / Codex / Cursor / OpenCode / Pi / Kiro / Antigravity / Grok Build agents for a Conduit organization",
5
5
  "type": "module",
6
6
  "bin": {