@rosthq/cli 0.7.13 → 0.7.14

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/index.js CHANGED
@@ -44296,7 +44296,7 @@ External connectors are being rolled out provider by provider, conservatively (r
44296
44296
  order: 48,
44297
44297
  title: "CLI and MCP installation guide",
44298
44298
  summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
44299
- version: "2026-07-03.12",
44299
+ version: "2026-07-03.13",
44300
44300
  public: true,
44301
44301
  audiences: ["human", "cli", "mcp", "in_app_agent"],
44302
44302
  stages: ["company_setup", "staffing"],
@@ -44755,7 +44755,7 @@ The signed-in app exposes the same Skill command surface under **Skills** in the
44755
44755
  | \`{{cli}} error list|resolve|supersede\` | \`error_log.list\`, \`error_log.resolve\`, \`error_log.supersede\` | List active, acknowledged, resolved, or superseded product error logs and let a human acknowledge, resolve, or supersede stale errors with evidence links. | Tenant | \`{{cli}} error list --resolved active --json\`; \`{{cli}} error resolve --error-log-id <id> --reason "Fixed in PR #123"\` |
44756
44756
  | \`{{cli}} sync brief|compile|complete\` | \`sync.brief.get\`, \`sync.brief.compile\`, \`sync.run.complete\` | Compile, read, and complete a weekly Sync. | Tenant | \`{{cli}} sync brief --json\` |
44757
44757
  | \`{{cli}} runner list|status|diagnose|repair|work-orders|revoke|serve\` | \`runner.list\`, \`runner.status\`, \`runner.diagnose\`, \`runner.repair\`, \`work_order.list\`, \`runner.revoke\`, runner endpoint APIs | Inspect heartbeat and execute-readiness evidence, inspect work orders, diagnose offline runners, get repair guidance, revoke a runner, or run the headless local runner loop. | Tenant | \`{{cli}} runner diagnose --runner-id <id> --json\`; \`{{cli}} runner serve --once\` |
44758
- | \`{{cli}} runner install-service|start|stop|restart|status|logs|uninstall --name <name>\` | launchd/service manager (macOS today) + \`{{cli}} runner serve\` | Install and manage an always-on local runner service that keeps the runner online across reboots; the service shells out to \`{{cli}} runner serve --execute\` and stores no secret in the service definition, its arguments, or logs. Non-macOS emits an explicit unsupported message. | Tenant (local machine) | \`{{cli}} runner install-service --name mac-mini --execute\`; \`{{cli}} runner logs --name mac-mini\` |
44758
+ | \`{{cli}} runner install-service|start|stop|restart|status|logs|uninstall --name <name> [--user-code <code>]\` | launchd/service manager (macOS today) + \`{{cli}} runner serve\` | Install and manage an always-on local runner service that keeps the runner online across reboots. The service runs the runner under the absolute Node binary with an explicit PATH (so it works under nvm/Homebrew) and bootstraps into whichever launchd domain the session supports. Pass \`--user-code\` to pair the service at install; otherwise install prints the exact command to pair it. No secret is stored in the service definition, its arguments, or logs. Non-macOS emits an explicit unsupported message. | Tenant (local machine) | \`{{cli}} runner install-service --name mac-mini --execute --user-code ABCD-EFGH\`; \`{{cli}} runner logs --name mac-mini\` |
44759
44759
  | \`{{cli}} notification settings|test|errors\` | \`notification.settings.get\`, \`notification.test\`, \`notification.list_errors\` | Read notification settings, send a test, and list failed deliveries with linked product error source, seat id, and run id when available. | Tenant | \`{{cli}} notification errors --limit 10 --json\` |
44760
44760
  | \`{{cli}} integration list|readiness|status|test\` / credential flow for Baserow REST connect | \`integration.connect_rest\`, \`integration.list\`, \`integration.readiness\`, \`integration.status\`, \`integration.test\` | Create a vault-backed Baserow REST integration through the credential flow, list connector metadata, read setup-readiness, read one connector's health, and run provider-specific tests without exposing credentials. | Tenant-admin for connect; tenant for reads/tests | \`{{cli}} integration readiness --provider google --json\` |
44761
44761
  | \`{{cli}} system health\` | \`system.health\` | Read the scoped system-health snapshot across agent runs, unresolved errors, Signals, Cascade setup, work loop, integrations, runners, notifications, and Sync Brief readiness. | Tenant, member, or seat token | \`{{cli}} system health --json\`; \`{{cli}} system health --seat <id> --json\` |
@@ -51151,6 +51151,7 @@ function runnerServicePaths(homeDir, runnerName) {
51151
51151
  }
51152
51152
  function renderLaunchdPlist(config2) {
51153
51153
  const programArgs = [
51154
+ config2.nodePath,
51154
51155
  config2.binPath,
51155
51156
  "runner",
51156
51157
  "serve",
@@ -51175,9 +51176,13 @@ ${programArgsXml}
51175
51176
  <dict>
51176
51177
  <key>${cliBrand.envPrefix}_APP_URL</key>
51177
51178
  <string>${escapePlist(config2.appUrl)}</string>
51179
+ <key>PATH</key>
51180
+ <string>${escapePlist(config2.servicePath)}</string>
51178
51181
  </dict>
51179
51182
  <key>KeepAlive</key>
51180
51183
  <true/>
51184
+ <key>ThrottleInterval</key>
51185
+ <integer>30</integer>
51181
51186
  <key>RunAtLoad</key>
51182
51187
  <true/>
51183
51188
  <key>StandardOutPath</key>
@@ -51215,6 +51220,8 @@ ${serviceUsage()}
51215
51220
  runnerName: parsed.runnerName,
51216
51221
  appUrl: options.appUrl,
51217
51222
  execute: parsed.execute,
51223
+ userCode: parsed.userCode,
51224
+ nodePath: options.nodePath ?? resolveNodePath(),
51218
51225
  binPath: options.binPath ?? resolveBinPath(),
51219
51226
  homeDir: options.homeDir ?? homedir2(),
51220
51227
  platform: options.platform ?? process.platform,
@@ -51250,12 +51257,20 @@ async function installService(options) {
51250
51257
  await mkdir3(paths.logDir, { recursive: true });
51251
51258
  await mkdir3(path4.dirname(paths.stateFile), { recursive: true });
51252
51259
  await mkdir3(path4.dirname(paths.launchAgentPath), { recursive: true });
51260
+ if (options.userCode !== void 0) {
51261
+ const paired = await pairRunnerOnce(options, safeName, paths.stateFile, options.userCode);
51262
+ if (!paired) {
51263
+ return 1;
51264
+ }
51265
+ }
51253
51266
  const plist = renderLaunchdPlist({
51267
+ nodePath: options.nodePath,
51254
51268
  binPath: options.binPath,
51255
51269
  runnerName: safeName,
51256
51270
  stateFile: paths.stateFile,
51257
51271
  logDir: paths.logDir,
51258
51272
  appUrl: options.appUrl,
51273
+ servicePath: buildServicePath(options.nodePath, options.homeDir),
51259
51274
  execute: options.execute
51260
51275
  });
51261
51276
  await writeFile3(paths.launchAgentPath, plist, { mode: 420 });
@@ -51274,6 +51289,7 @@ async function installService(options) {
51274
51289
  );
51275
51290
  return 1;
51276
51291
  }
51292
+ const pairingLine = options.userCode !== void 0 ? `Paired with the supplied user code; the bearer secret is stored locally and never printed.` : `Pair it once so it can claim work: \`${cliBrand.binName} runner serve --once --user-code <code> --name ${safeName} --state-file "${paths.stateFile}"\` (get a code from Settings > Runners), or re-run install-service with --user-code <code>. The bearer secret is stored locally and never printed.`;
51277
51293
  options.io.stdout.write(
51278
51294
  `${[
51279
51295
  `Installed runner service ${label}.`,
@@ -51281,7 +51297,7 @@ async function installService(options) {
51281
51297
  `state file: ${paths.stateFile}`,
51282
51298
  `logs: ${paths.logDir}`,
51283
51299
  `execute: ${options.execute ? "on (claims and runs work orders)" : "off (heartbeat only)"}`,
51284
- `The runner pairs on first run; its bearer secret is stored locally and never printed.`
51300
+ pairingLine
51285
51301
  ].join("\n")}
51286
51302
  `
51287
51303
  );
@@ -51472,6 +51488,7 @@ async function uninstallService(options) {
51472
51488
  function parseServiceArgs(args) {
51473
51489
  let runnerName;
51474
51490
  let execute2 = false;
51491
+ let userCode;
51475
51492
  for (let index = 0; index < args.length; index += 1) {
51476
51493
  const token = args[index];
51477
51494
  if (token === "--name") {
@@ -51481,6 +51498,13 @@ function parseServiceArgs(args) {
51481
51498
  }
51482
51499
  runnerName = value;
51483
51500
  index += 1;
51501
+ } else if (token === "--user-code") {
51502
+ const value = args[index + 1];
51503
+ if (value === void 0 || value.startsWith("--")) {
51504
+ throw new Error("--user-code requires a value.");
51505
+ }
51506
+ userCode = value;
51507
+ index += 1;
51484
51508
  } else if (token === "--execute") {
51485
51509
  execute2 = true;
51486
51510
  } else {
@@ -51490,13 +51514,13 @@ function parseServiceArgs(args) {
51490
51514
  if (runnerName === void 0 || runnerName.trim().length === 0) {
51491
51515
  throw new Error("--name <runner-name> is required.");
51492
51516
  }
51493
- return { runnerName, execute: execute2 };
51517
+ return { runnerName, execute: execute2, ...userCode !== void 0 ? { userCode } : {} };
51494
51518
  }
51495
51519
  function serviceUsage() {
51496
51520
  const bin = cliBrand.binName;
51497
51521
  return [
51498
51522
  `Usage:`,
51499
- ` ${bin} runner install-service --name <name> [--execute]`,
51523
+ ` ${bin} runner install-service --name <name> [--execute] [--user-code <code>]`,
51500
51524
  ` ${bin} runner start|stop|restart|status|logs|uninstall --name <name>`
51501
51525
  ].join("\n");
51502
51526
  }
@@ -51581,6 +51605,54 @@ function unsupportedPlatform(io, platform2) {
51581
51605
  );
51582
51606
  return 1;
51583
51607
  }
51608
+ function resolveNodePath() {
51609
+ return process.execPath;
51610
+ }
51611
+ function buildServicePath(nodePath, homeDir) {
51612
+ const entries = [
51613
+ path4.dirname(nodePath),
51614
+ "/opt/homebrew/bin",
51615
+ "/usr/local/bin",
51616
+ path4.join(homeDir, ".local", "bin"),
51617
+ path4.join(homeDir, "bin"),
51618
+ "/usr/bin",
51619
+ "/bin",
51620
+ "/usr/sbin",
51621
+ "/sbin"
51622
+ ];
51623
+ return Array.from(new Set(entries)).join(":");
51624
+ }
51625
+ async function pairRunnerOnce(options, safeName, stateFile, userCode) {
51626
+ const serveArgs = [
51627
+ options.binPath,
51628
+ "runner",
51629
+ "serve",
51630
+ "--once",
51631
+ "--user-code",
51632
+ userCode,
51633
+ "--name",
51634
+ safeName,
51635
+ "--state-file",
51636
+ stateFile
51637
+ ];
51638
+ try {
51639
+ await options.exec(options.nodePath, serveArgs, {
51640
+ env: { ...process.env, [`${cliBrand.envPrefix}_APP_URL`]: options.appUrl }
51641
+ });
51642
+ options.io.stdout.write(`Paired runner ${safeName}.
51643
+ `);
51644
+ return true;
51645
+ } catch (error51) {
51646
+ const raw = error51 instanceof Error ? error51.message : String(error51);
51647
+ const scrubbed = redactForLog(raw.split(userCode).join("<user-code>"));
51648
+ options.io.stderr.write(
51649
+ `Failed to pair the runner with --user-code: ${scrubbed}
51650
+ The plist is installed but not loaded. Fix pairing, then run \`${cliBrand.binName} runner start --name ${safeName}\`.
51651
+ `
51652
+ );
51653
+ return false;
51654
+ }
51655
+ }
51584
51656
  function resolveBinPath() {
51585
51657
  const entry = process.argv[1];
51586
51658
  if (entry === void 0 || entry.length === 0) {
@@ -51615,8 +51687,8 @@ async function readTail(file2, maxBytes) {
51615
51687
  function escapePlist(value) {
51616
51688
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
51617
51689
  }
51618
- var defaultExec = async (file2, args) => {
51619
- const result = await execFile4(file2, args);
51690
+ var defaultExec = async (file2, args, options) => {
51691
+ const result = await execFile4(file2, args, options?.env ? { env: options.env } : {});
51620
51692
  return { stdout: String(result.stdout), stderr: String(result.stderr) };
51621
51693
  };
51622
51694
  function assertNever2(value) {