@appchy/jarvis 0.1.109 → 0.1.110

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/bin.js CHANGED
@@ -1387,10 +1387,78 @@ async function ensureGraphify(options = {}) {
1387
1387
  );
1388
1388
  }
1389
1389
 
1390
+ // src/graph/hook.ts
1391
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync, chmodSync } from "fs";
1392
+ import path7 from "path";
1393
+ var SIGNATURE = "# managed by jarvis";
1394
+ var SCRIPT = `#!/bin/sh
1395
+ ${SIGNATURE} \u2014 keeps this repo's map current, so what an agent plans against is what is here.
1396
+ # Detached and silenced: git waits for a hook's output streams to close, so a build left on stdout
1397
+ # would hold up every commit by the length of a build. Never fails a commit.
1398
+ #
1399
+ # Run at the lowest priority the machine offers. A code commit still costs a real extract, and one
1400
+ # arriving at normal priority the instant you commit is felt as the machine going away for half a
1401
+ # minute \u2014 which is how a background job becomes something people turn off. Borrowed from the
1402
+ # docdoc-era hook in crispy, which had this right first.
1403
+ command -v jarvis >/dev/null 2>&1 || exit 0
1404
+ NICE=""
1405
+ command -v nice >/dev/null 2>&1 && NICE="nice -n 19"
1406
+ command -v taskpolicy >/dev/null 2>&1 && NICE="taskpolicy -b $NICE"
1407
+ ( $NICE jarvis build graph >/dev/null 2>&1 & ) >/dev/null 2>&1
1408
+ exit 0
1409
+ `;
1410
+ function findRepoRoot(from) {
1411
+ let dir = path7.resolve(from);
1412
+ for (; ; ) {
1413
+ if (existsSync(path7.join(dir, ".git"))) return dir;
1414
+ const parent = path7.dirname(dir);
1415
+ if (parent === dir) return null;
1416
+ dir = parent;
1417
+ }
1418
+ }
1419
+ function installCommitHook(repoRoot) {
1420
+ const git4 = path7.join(repoRoot, ".git");
1421
+ const dir = path7.join(git4, "hooks");
1422
+ const file = path7.join(dir, "post-commit");
1423
+ if (!existsSync(git4)) return { installed: false, reason: "not-a-repo" };
1424
+ if (!statSync(git4).isDirectory()) return { installed: false, reason: "worktree" };
1425
+ if (!existsSync(path7.join(git4, "HEAD"))) return { installed: false, reason: "not-a-repo" };
1426
+ if (existsSync(file)) {
1427
+ try {
1428
+ if (!readFileSync(file, "utf8").includes(SIGNATURE))
1429
+ return { installed: false, reason: "foreign-hook", path: file };
1430
+ } catch {
1431
+ return { installed: false, reason: "unwritable", path: file };
1432
+ }
1433
+ }
1434
+ try {
1435
+ mkdirSync(dir, { recursive: true });
1436
+ writeFileSync(file, SCRIPT, "utf8");
1437
+ chmodSync(file, 493);
1438
+ return { installed: true, path: file };
1439
+ } catch {
1440
+ return { installed: false, reason: "unwritable", path: file };
1441
+ }
1442
+ }
1443
+ function describeCommitHook(outcome, repoRoot) {
1444
+ if (outcome.installed)
1445
+ return ` the map rebuilds itself on every commit here \u2713 (${path7.relative(repoRoot, outcome.path) || outcome.path})`;
1446
+ if (outcome.reason === "not-a-repo")
1447
+ return ` not a git repo, so there is no commit to rebuild on.
1448
+ Run this inside one, or rebuild by hand with 'jarvis build graph'.`;
1449
+ if (outcome.reason === "worktree")
1450
+ return ` this is a worktree or a submodule, and it shares the hooks of the checkout it
1451
+ was made from. Wire that one instead, or rebuild by hand with 'jarvis build graph'.`;
1452
+ if (outcome.reason === "foreign-hook")
1453
+ return ` a post-commit hook is already here and it is not ours \u2014 left untouched.
1454
+ Add this line to it to keep the map current: jarvis build graph >/dev/null 2>&1 &`;
1455
+ return ` could not write the hook \u2014 the map still builds, by hand, with 'jarvis build graph'.`;
1456
+ }
1457
+
1390
1458
  // src/machine.ts
1391
1459
  import crypto2 from "crypto";
1392
1460
  import fs8 from "fs";
1393
- import path7 from "path";
1461
+ import path8 from "path";
1394
1462
  var cached = null;
1395
1463
  function getMachine() {
1396
1464
  if (cached) return cached;
@@ -1405,7 +1473,7 @@ function getMachine() {
1405
1473
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1406
1474
  schemaVersion: 1
1407
1475
  };
1408
- fs8.mkdirSync(path7.dirname(file), { recursive: true });
1476
+ fs8.mkdirSync(path8.dirname(file), { recursive: true });
1409
1477
  fs8.writeFileSync(file, JSON.stringify(fresh, null, 2));
1410
1478
  return cached = fresh;
1411
1479
  }
@@ -1413,13 +1481,13 @@ function getMachine() {
1413
1481
  // src/service.ts
1414
1482
  import { execSync as execSync3, spawn } from "child_process";
1415
1483
  import fs9 from "fs";
1416
- import path8 from "path";
1484
+ import path9 from "path";
1417
1485
  import os4 from "os";
1418
1486
  function serviceSuffix() {
1419
1487
  const dir = getConfigDir();
1420
- const base = path8.join(os4.homedir(), ".jarvis");
1488
+ const base = path9.join(os4.homedir(), ".jarvis");
1421
1489
  if (dir === base) return "";
1422
- const name = dir.startsWith(base + path8.sep) ? dir.slice(base.length + 1) : path8.basename(dir);
1490
+ const name = dir.startsWith(base + path9.sep) ? dir.slice(base.length + 1) : path9.basename(dir);
1423
1491
  return name.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-|-$/g, "");
1424
1492
  }
1425
1493
  var SERVICE_SUFFIX = serviceSuffix();
@@ -1430,8 +1498,8 @@ function createServiceManager() {
1430
1498
  return new FallbackService();
1431
1499
  }
1432
1500
  var PLIST_LABEL = `com.appchy.jarvis${SERVICE_SUFFIX ? `.${SERVICE_SUFFIX}` : ""}`;
1433
- var PLIST_DIR = path8.join(os4.homedir(), "Library", "LaunchAgents");
1434
- var PLIST_PATH = path8.join(PLIST_DIR, `${PLIST_LABEL}.plist`);
1501
+ var PLIST_DIR = path9.join(os4.homedir(), "Library", "LaunchAgents");
1502
+ var PLIST_PATH = path9.join(PLIST_DIR, `${PLIST_LABEL}.plist`);
1435
1503
  function escapeXml(s) {
1436
1504
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
1437
1505
  }
@@ -1585,7 +1653,7 @@ ${Object.entries(opts.env ?? {}).map(([k, v]) => ` <key>${escapeXml(k)}</key>
1585
1653
  </plist>
1586
1654
  `;
1587
1655
  fs9.mkdirSync(PLIST_DIR, { recursive: true });
1588
- fs9.mkdirSync(path8.dirname(logFile), { recursive: true });
1656
+ fs9.mkdirSync(path9.dirname(logFile), { recursive: true });
1589
1657
  unloadAgent();
1590
1658
  fs9.writeFileSync(PLIST_PATH, plist);
1591
1659
  loadAgent();
@@ -1687,7 +1755,7 @@ var WindowsService = class {
1687
1755
  </Task>
1688
1756
  `;
1689
1757
  const tmpDir = os4.tmpdir();
1690
- const tmpFile = path8.join(tmpDir, `jarvis-task-${Date.now()}.xml`);
1758
+ const tmpFile = path9.join(tmpDir, `jarvis-task-${Date.now()}.xml`);
1691
1759
  fs9.writeFileSync(tmpFile, xml, { encoding: "utf-16le" });
1692
1760
  try {
1693
1761
  execSync3(`schtasks /Create /TN "${TASK_NAME}" /XML "${tmpFile}" /F`, {
@@ -1733,9 +1801,9 @@ var WindowsService = class {
1733
1801
  }
1734
1802
  }
1735
1803
  };
1736
- var SYSTEMD_DIR = path8.join(os4.homedir(), ".config", "systemd", "user");
1804
+ var SYSTEMD_DIR = path9.join(os4.homedir(), ".config", "systemd", "user");
1737
1805
  var UNIT_NAME = `jarvis${SERVICE_SUFFIX ? `-${SERVICE_SUFFIX}` : ""}.service`;
1738
- var UNIT_PATH = path8.join(SYSTEMD_DIR, UNIT_NAME);
1806
+ var UNIT_PATH = path9.join(SYSTEMD_DIR, UNIT_NAME);
1739
1807
  var LinuxService = class {
1740
1808
  install(opts) {
1741
1809
  const args = [opts.entryPath, "start", "--foreground", "--workspace", opts.workspacePath];
@@ -1764,7 +1832,7 @@ StandardError=append:${logFile}
1764
1832
  WantedBy=default.target
1765
1833
  `;
1766
1834
  fs9.mkdirSync(SYSTEMD_DIR, { recursive: true });
1767
- fs9.mkdirSync(path8.dirname(logFile), { recursive: true });
1835
+ fs9.mkdirSync(path9.dirname(logFile), { recursive: true });
1768
1836
  if (this.isInstalled()) {
1769
1837
  try {
1770
1838
  execSync3(`systemctl --user stop ${UNIT_NAME}`, { stdio: "ignore" });
@@ -1844,9 +1912,9 @@ WantedBy=default.target
1844
1912
  };
1845
1913
  var FallbackService = class {
1846
1914
  baseDir = getJarvisDir();
1847
- pidFile = path8.join(this.baseDir, "agent.pid");
1848
- logFile = path8.join(this.baseDir, "agent.log");
1849
- markerFile = path8.join(this.baseDir, "service-installed");
1915
+ pidFile = path9.join(this.baseDir, "agent.pid");
1916
+ logFile = path9.join(this.baseDir, "agent.log");
1917
+ markerFile = path9.join(this.baseDir, "service-installed");
1850
1918
  install(opts) {
1851
1919
  fs9.mkdirSync(this.baseDir, { recursive: true });
1852
1920
  this.stop();
@@ -1921,11 +1989,11 @@ var FallbackService = class {
1921
1989
  };
1922
1990
 
1923
1991
  // src/hooks/install.ts
1924
- import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "fs";
1992
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, realpathSync, writeFileSync as writeFileSync2 } from "fs";
1925
1993
  import os5 from "os";
1926
- import path9 from "path";
1927
- var SETTINGS_DIR = path9.join(os5.homedir(), ".claude");
1928
- var SETTINGS_FILE = path9.join(SETTINGS_DIR, "settings.json");
1994
+ import path10 from "path";
1995
+ var SETTINGS_DIR = path10.join(os5.homedir(), ".claude");
1996
+ var SETTINGS_FILE = path10.join(SETTINGS_DIR, "settings.json");
1929
1997
  var HOOK_STEMS = [
1930
1998
  "pre-tool-use",
1931
1999
  "session-start",
@@ -1943,7 +2011,7 @@ function jarvisHooks() {
1943
2011
  ];
1944
2012
  }
1945
2013
  function isJarvisCommand(command) {
1946
- const name = path9.basename(command);
2014
+ const name = path10.basename(command);
1947
2015
  return HOOK_STEMS.some((stem) => name === `${stem}.mjs` || name === `${stem}.dev.mjs`);
1948
2016
  }
1949
2017
  function getCliRoot() {
@@ -1956,22 +2024,22 @@ function getCliRoot() {
1956
2024
  entry = realpathSync(binPath);
1957
2025
  } catch {
1958
2026
  }
1959
- return path9.resolve(path9.dirname(entry), "..");
2027
+ return path10.resolve(path10.dirname(entry), "..");
1960
2028
  }
1961
2029
  function resolveHooks() {
1962
2030
  const cliRoot = getCliRoot();
1963
2031
  return jarvisHooks().map((h) => ({
1964
2032
  ...h,
1965
- binAbsPath: path9.join(cliRoot, "bin", h.binBasename)
2033
+ binAbsPath: path10.join(cliRoot, "bin", h.binBasename)
1966
2034
  }));
1967
2035
  }
1968
2036
  function ownsClaudeCode() {
1969
- return getConfigDir() === path9.join(os5.homedir(), ".jarvis");
2037
+ return getConfigDir() === path10.join(os5.homedir(), ".jarvis");
1970
2038
  }
1971
2039
  function readSettings() {
1972
- if (!existsSync(SETTINGS_FILE)) return {};
2040
+ if (!existsSync2(SETTINGS_FILE)) return {};
1973
2041
  try {
1974
- const raw = readFileSync(SETTINGS_FILE, "utf-8");
2042
+ const raw = readFileSync2(SETTINGS_FILE, "utf-8");
1975
2043
  return raw.trim() ? JSON.parse(raw) : {};
1976
2044
  } catch (err) {
1977
2045
  logger.sys.warn("[hooks.install] settings.json unreadable", {
@@ -1982,8 +2050,8 @@ function readSettings() {
1982
2050
  }
1983
2051
  function writeSettings(s) {
1984
2052
  try {
1985
- mkdirSync(SETTINGS_DIR, { recursive: true });
1986
- writeFileSync(SETTINGS_FILE, JSON.stringify(s, null, 2) + "\n");
2053
+ mkdirSync2(SETTINGS_DIR, { recursive: true });
2054
+ writeFileSync2(SETTINGS_FILE, JSON.stringify(s, null, 2) + "\n");
1987
2055
  return true;
1988
2056
  } catch (err) {
1989
2057
  logger.sys.warn("[hooks.install] settings.json unwritable", {
@@ -2028,7 +2096,7 @@ function claudeCodeHooksState() {
2028
2096
  return {
2029
2097
  type: hook.type,
2030
2098
  bin: hook.binAbsPath,
2031
- exists: existsSync(hook.binAbsPath),
2099
+ exists: existsSync2(hook.binAbsPath),
2032
2100
  ...command ? { command } : {}
2033
2101
  };
2034
2102
  });
@@ -2050,10 +2118,10 @@ function installClaudeCodeHooks() {
2050
2118
  expected: resolved.map((h) => ({
2051
2119
  type: h.type,
2052
2120
  bin: h.binAbsPath,
2053
- exists: existsSync(h.binAbsPath)
2121
+ exists: existsSync2(h.binAbsPath)
2054
2122
  }))
2055
2123
  });
2056
- const missing = resolved.filter((h) => !existsSync(h.binAbsPath));
2124
+ const missing = resolved.filter((h) => !existsSync2(h.binAbsPath));
2057
2125
  if (missing.length === resolved.length) {
2058
2126
  logger.sys.warn("[hooks.install] no bin shims found, skipping", {
2059
2127
  configDir: configDir2,
@@ -2064,7 +2132,7 @@ function installClaudeCodeHooks() {
2064
2132
  let settings = readSettings();
2065
2133
  const installed = [];
2066
2134
  for (const hook of resolved) {
2067
- if (!existsSync(hook.binAbsPath)) {
2135
+ if (!existsSync2(hook.binAbsPath)) {
2068
2136
  logger.sys.warn("[hooks.install] bin shim missing, skipping hook", {
2069
2137
  configDir: configDir2,
2070
2138
  type: hook.type,
@@ -2232,93 +2300,8 @@ Open Claude Code in a repo that has a work/ tree to see them.`);
2232
2300
  });
2233
2301
  }
2234
2302
 
2235
- // src/graph/hook.ts
2236
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, statSync, writeFileSync as writeFileSync2, chmodSync } from "fs";
2237
- import path10 from "path";
2238
- var SIGNATURE = "# managed by jarvis";
2239
- var SCRIPT = `#!/bin/sh
2240
- ${SIGNATURE} \u2014 keeps this repo's map current, so what an agent plans against is what is here.
2241
- # Detached and silenced: git waits for a hook's output streams to close, so a build left on stdout
2242
- # would hold up every commit by the length of a build. Never fails a commit.
2243
- #
2244
- # Run at the lowest priority the machine offers. A code commit still costs a real extract, and one
2245
- # arriving at normal priority the instant you commit is felt as the machine going away for half a
2246
- # minute \u2014 which is how a background job becomes something people turn off. Borrowed from the
2247
- # docdoc-era hook in crispy, which had this right first.
2248
- command -v jarvis >/dev/null 2>&1 || exit 0
2249
- NICE=""
2250
- command -v nice >/dev/null 2>&1 && NICE="nice -n 19"
2251
- command -v taskpolicy >/dev/null 2>&1 && NICE="taskpolicy -b $NICE"
2252
- ( $NICE jarvis build graph >/dev/null 2>&1 & ) >/dev/null 2>&1
2253
- exit 0
2254
- `;
2255
- function findRepoRoot(from) {
2256
- let dir = path10.resolve(from);
2257
- for (; ; ) {
2258
- if (existsSync2(path10.join(dir, ".git"))) return dir;
2259
- const parent = path10.dirname(dir);
2260
- if (parent === dir) return null;
2261
- dir = parent;
2262
- }
2263
- }
2264
- function installCommitHook(repoRoot) {
2265
- const git4 = path10.join(repoRoot, ".git");
2266
- const dir = path10.join(git4, "hooks");
2267
- const file = path10.join(dir, "post-commit");
2268
- if (!existsSync2(git4)) return { installed: false, reason: "not-a-repo" };
2269
- if (!statSync(git4).isDirectory()) return { installed: false, reason: "worktree" };
2270
- if (!existsSync2(path10.join(git4, "HEAD"))) return { installed: false, reason: "not-a-repo" };
2271
- if (existsSync2(file)) {
2272
- try {
2273
- if (!readFileSync2(file, "utf8").includes(SIGNATURE))
2274
- return { installed: false, reason: "foreign-hook", path: file };
2275
- } catch {
2276
- return { installed: false, reason: "unwritable", path: file };
2277
- }
2278
- }
2279
- try {
2280
- mkdirSync2(dir, { recursive: true });
2281
- writeFileSync2(file, SCRIPT, "utf8");
2282
- chmodSync(file, 493);
2283
- return { installed: true, path: file };
2284
- } catch {
2285
- return { installed: false, reason: "unwritable", path: file };
2286
- }
2287
- }
2288
- function describeCommitHook(outcome, repoRoot) {
2289
- if (outcome.installed)
2290
- return ` the map rebuilds itself on every commit here \u2713 (${path10.relative(repoRoot, outcome.path) || outcome.path})`;
2291
- if (outcome.reason === "not-a-repo")
2292
- return ` not a git repo, so there is no commit to rebuild on.
2293
- Run this inside one, or rebuild by hand with 'jarvis build graph'.`;
2294
- if (outcome.reason === "worktree")
2295
- return ` this is a worktree or a submodule, and it shares the hooks of the checkout it
2296
- was made from. Wire that one instead, or rebuild by hand with 'jarvis build graph'.`;
2297
- if (outcome.reason === "foreign-hook")
2298
- return ` a post-commit hook is already here and it is not ours \u2014 left untouched.
2299
- Add this line to it to keep the map current: jarvis build graph >/dev/null 2>&1 &`;
2300
- return ` could not write the hook \u2014 the map still builds, by hand, with 'jarvis build graph'.`;
2301
- }
2302
-
2303
- // src/commands/repo.ts
2304
- function register3(program) {
2305
- const repo = program.command("repo").description("Set up the repo you are standing in \u2014 no pairing, no daemon, no network");
2306
- repo.command("init").description("Keep this repo's map current by rebuilding it on every commit").action(() => {
2307
- if (!setUpThisRepo()) process.exit(1);
2308
- console.log(" It rebuilds from your next commit. To build one now: jarvis build graph\n");
2309
- });
2310
- }
2311
- function setUpThisRepo() {
2312
- const root = findRepoRoot(process.cwd()) ?? process.cwd();
2313
- console.log(" \u25B8 Keeping this repo's map current");
2314
- const outcome = installCommitHook(root);
2315
- console.log(`${describeCommitHook(outcome, root)}
2316
- `);
2317
- return outcome.installed;
2318
- }
2319
-
2320
2303
  // src/commands/init.ts
2321
- function register4(program) {
2304
+ function register3(program) {
2322
2305
  program.command("init").description("Set this machine up to work in repos, and join an instance if you name one").option("--url <url>", "Also join the jarvis instance at this address").option("--skip-daemon", "Skip the background daemon install step").option("--force", "Re-ask all prompts even when config already has answers").action(async (opts) => {
2323
2306
  const ok = await runInit({
2324
2307
  url: opts.url,
@@ -2414,6 +2397,14 @@ async function setUpThisMachine(prompts) {
2414
2397
  `
2415
2398
  );
2416
2399
  }
2400
+ function setUpThisRepo() {
2401
+ const root = findRepoRoot(process.cwd()) ?? process.cwd();
2402
+ console.log(" \u25B8 Keeping this repo's map current");
2403
+ const outcome = installCommitHook(root);
2404
+ console.log(`${describeCommitHook(outcome, root)}
2405
+ `);
2406
+ return outcome.installed;
2407
+ }
2417
2408
  async function setUpMapTool(prompts) {
2418
2409
  console.log(" \u25B8 The tool the map's code half is built from");
2419
2410
  const state2 = resolveGraphify();
@@ -2476,7 +2467,7 @@ function reportSetUp(joined) {
2476
2467
  console.log(" \u2714 Done. This machine works in any repo that has a work/ tree:");
2477
2468
  console.log(" the board, the map, the session block, the rules that arrive on edit,");
2478
2469
  console.log(" and 'jarvis serve' for any agent that speaks MCP.\n");
2479
- console.log(" In a repo you have cloned: jarvis repo init");
2470
+ console.log(" In a repo you have cloned: jarvis init");
2480
2471
  console.log(" jarvis build graph");
2481
2472
  console.log(" jarvis work list\n");
2482
2473
  if (joined) {
@@ -2695,7 +2686,7 @@ async function promptList(question, fallback) {
2695
2686
  }
2696
2687
 
2697
2688
  // src/commands/pair.ts
2698
- function register5(program) {
2689
+ function register4(program) {
2699
2690
  program.command("pair").description("Re-pair this machine (when token expired)").action(async () => {
2700
2691
  try {
2701
2692
  await runPair();
@@ -2809,7 +2800,7 @@ async function unpair() {
2809
2800
  clearConfig();
2810
2801
  return { attempted: true, serverStatus };
2811
2802
  }
2812
- function register6(program) {
2803
+ function register5(program) {
2813
2804
  program.command("unpair").description("Unregister this env from cloud and wipe local config").option("-y, --yes", "Skip confirmation prompt").action(async (opts) => {
2814
2805
  try {
2815
2806
  const config2 = loadConfig();
@@ -2864,7 +2855,7 @@ function getRoots() {
2864
2855
  const cfg = readConfig();
2865
2856
  return Array.isArray(cfg.roots) ? cfg.roots : [];
2866
2857
  }
2867
- function register7(program) {
2858
+ function register6(program) {
2868
2859
  const cmd = program.command("roots").description("Manage code-root directories");
2869
2860
  cmd.command("list", { isDefault: true }).description("List current roots").action(() => {
2870
2861
  const roots = getRoots();
@@ -2909,7 +2900,7 @@ function readLocalConfig() {
2909
2900
  return {};
2910
2901
  }
2911
2902
  }
2912
- function register8(program) {
2903
+ function register7(program) {
2913
2904
  program.command("settings").description("Show this env's settings (roots, repos map)").action(async () => {
2914
2905
  try {
2915
2906
  const config2 = loadConfig();
@@ -10291,7 +10282,7 @@ import { createRequire as createRequire2 } from "module";
10291
10282
  var _require = createRequire2(import.meta.url);
10292
10283
  var VERSION2 = _require("../package.json").version ?? "0.0.0";
10293
10284
  var IS_DEV = String(_require("../package.json").name ?? "").endsWith("-dev");
10294
- var SHA = "fd09a8d";
10285
+ var SHA = "497a5e2";
10295
10286
  var BUILT = "2026-09-12";
10296
10287
  var BUILD = SHA ?? "source";
10297
10288
  var BUILD_LABEL = `${SHA ? `${VERSION2} (${SHA}${BUILT ? ` ${BUILT}` : ""})` : `${VERSION2} (source)`}${IS_DEV ? " \u2014 development build" : ""}`;
@@ -10810,7 +10801,7 @@ async function fetchRoots(hubUrl, envId, token) {
10810
10801
  }
10811
10802
 
10812
10803
  // src/commands/start.ts
10813
- function register9(program) {
10804
+ function register8(program) {
10814
10805
  program.command("start").description("Start the local agent (authenticates, cleans up stale processes, starts fresh)").option("-w, --workspace <path>", "Workspace root path").option("--api-key <key>", "Anthropic API key (for local-only use)").option("--no-upstream", "Don't connect to cloud (local-only mode)").option("--foreground", "Run in foreground (don't daemonize)").option("--force", "Re-ask all prompts even when config has them").action(async (opts) => {
10815
10806
  if (refuseWithoutInstance()) process.exit(1);
10816
10807
  const config2 = loadConfig();
@@ -10947,7 +10938,7 @@ function buildUpstreamConfig(req) {
10947
10938
  }
10948
10939
 
10949
10940
  // src/commands/stop.ts
10950
- function register10(program) {
10941
+ function register9(program) {
10951
10942
  program.command("stop").description("Stop the running agent").action(() => {
10952
10943
  uninstallClaudeCodeHooks();
10953
10944
  const service = createServiceManager();
@@ -10974,7 +10965,7 @@ function register10(program) {
10974
10965
  }
10975
10966
 
10976
10967
  // src/commands/restart.ts
10977
- function register11(program) {
10968
+ function register10(program) {
10978
10969
  program.command("restart").description("Restart the agent (alias for start \u2014 start always does a clean restart)").action(async () => {
10979
10970
  await program.parseAsync(["node", "jarvis", "start"]);
10980
10971
  });
@@ -10983,7 +10974,7 @@ function register11(program) {
10983
10974
  // src/commands/logs.ts
10984
10975
  import { spawn as spawn2, execSync as execSync6 } from "child_process";
10985
10976
  import fs16 from "fs";
10986
- function register12(program) {
10977
+ function register11(program) {
10987
10978
  program.command("logs").description("View agent logs").option("-f, --follow", "Follow log output (like tail -f)", true).option("-n, --lines <n>", "Number of lines to show", "50").action((opts) => {
10988
10979
  const logFile = getLogFile();
10989
10980
  if (!fs16.existsSync(logFile)) {
@@ -11058,7 +11049,7 @@ function portOf(url) {
11058
11049
  // src/commands/status.ts
11059
11050
  var GREEN2 = (text) => `\x1B[32m${text}\x1B[0m`;
11060
11051
  var RED2 = (text) => `\x1B[31m${text}\x1B[0m`;
11061
- function register13(program) {
11052
+ function register12(program) {
11062
11053
  program.command("status").description("Show agent configuration and connection status").action(async () => {
11063
11054
  const config2 = loadConfig();
11064
11055
  const health = await getHealth();
@@ -11097,7 +11088,7 @@ function endpoint(probed) {
11097
11088
  }
11098
11089
 
11099
11090
  // src/commands/install.ts
11100
- function register14(program) {
11091
+ function register13(program) {
11101
11092
  program.command("install").description("Install as OS service for auto-start on login and crash recovery").option("-w, --workspace <path>", "Workspace root path").option("--no-upstream", "Don't connect to cloud").action(async (opts) => {
11102
11093
  if (refuseWithoutInstance()) process.exit(1);
11103
11094
  const config2 = loadConfig();
@@ -11146,7 +11137,7 @@ function register14(program) {
11146
11137
  import fs17 from "fs";
11147
11138
  import path19 from "path";
11148
11139
  import { createInterface as createInterface5 } from "readline";
11149
- function register15(program) {
11140
+ function register14(program) {
11150
11141
  program.command("uninstall").description("Stop the agent, remove the OS service, and wipe local config + identity").option("--keep-data", "Skip the data-wipe prompt; preserve skills/prompts/cache/settings").option("--purge", "Skip the prompt and wipe ALL local data (skills, prompts, cache, settings)").action(async (opts) => {
11151
11142
  try {
11152
11143
  await runUninstall(opts);
@@ -11208,7 +11199,7 @@ function confirm2(prompt) {
11208
11199
  }
11209
11200
 
11210
11201
  // src/commands/logout.ts
11211
- function register16(program) {
11202
+ function register15(program) {
11212
11203
  program.command("logout").description("Clear saved configuration").action(() => {
11213
11204
  clearConfig();
11214
11205
  console.log("Configuration cleared.");
@@ -11239,7 +11230,7 @@ async function call(path23, method, body) {
11239
11230
  }
11240
11231
  return await resp.json();
11241
11232
  }
11242
- function register17(program) {
11233
+ function register16(program) {
11243
11234
  const mcp = program.command("mcp").description("Connect an agent to this workspace's board");
11244
11235
  mcp.command("token").description("Mint a personal token for the Jarvis MCP server").option("--name <name>", "Which machine this token is for, e.g. 'laptop'").option("--scopes <list>", "read | write | read,write", "read,write").option("--show", "Show the current token's details instead of minting").option("--revoke", "Revoke the current token").action(async (opts) => {
11245
11236
  try {
@@ -11293,7 +11284,7 @@ function register17(program) {
11293
11284
  }
11294
11285
 
11295
11286
  // src/commands/model.ts
11296
- function register18(program) {
11287
+ function register17(program) {
11297
11288
  const model = program.command("model").description("Model access for the map's semantic search, on this machine");
11298
11289
  model.command("key").argument("[key]", "The OpenAI key to store. Omit it to see what is set.").option("--show", "Say whether a key is set, without printing it").option("--clear", "Forget the stored key").description("Set the OpenAI key the map embeds with").action((key, opts) => {
11299
11290
  const config2 = loadConfig();
@@ -11552,7 +11543,7 @@ function isStale(lockPath, staleMs) {
11552
11543
  }
11553
11544
 
11554
11545
  // src/commands/build.ts
11555
- function register19(program) {
11546
+ function register18(program) {
11556
11547
  const build2 = program.command("build").description("Build an artifact from this repo");
11557
11548
  build2.command("graph").description("Read the repo's jarvis.config.ts, build the graph, and say what is wrong with it").option("--repo <path>", "The repo to map. Default: the working directory").option("--rebuild", "LAST RESORT: throw the graph away and re-extract from scratch").option("--label", "Re-name the detected communities through the configured labeler").option("--gate", "Fail when a governance class has more findings than this repo carries").action(async (opts) => {
11558
11549
  const argv = [
@@ -11612,7 +11603,7 @@ function isRedirected(req) {
11612
11603
  }
11613
11604
 
11614
11605
  // src/commands/dev.ts
11615
- function register20(program) {
11606
+ function register19(program) {
11616
11607
  const dev = program.command("dev").description("Run a development build in a repo, without replacing the installed jarvis");
11617
11608
  dev.command("use").argument("[where]", "'here' for the working directory, 'all' for every repo", "here").option("--root <path>", "The checkout to run. Default: the one already recorded").description("Point a repo at the development build").action((where, opts) => {
11618
11609
  const current = readDevRedirect();
@@ -12329,7 +12320,7 @@ async function brief2(repo) {
12329
12320
  }
12330
12321
 
12331
12322
  // src/commands/serve.ts
12332
- function register21(program) {
12323
+ function register20(program) {
12333
12324
  program.command("serve").description("Serve this repo to an agent over stdio \u2014 what an .mcp.json launches").option("--repo <path>", "The repo to serve. Default: the working directory").action(async (opts) => {
12334
12325
  const repo = resolveRepo(opts.repo);
12335
12326
  const problem = harnessProblem();
@@ -12634,7 +12625,7 @@ function whenRebuilt(dir, reload) {
12634
12625
  }
12635
12626
 
12636
12627
  // src/commands/ui.ts
12637
- function register22(program) {
12628
+ function register21(program) {
12638
12629
  program.command("ui").description("Open this repo's board in a browser \u2014 nothing to configure, nothing to join").option("--repo <path>", "The repo to show. Default: the working directory").option("--port <number>", "The port to listen on. Default: 3402").option("--no-open", "Print the address instead of opening a browser").option("--packaged", "Serve the page this build shipped with, never a checkout's").action(async (opts) => {
12639
12630
  const repo = resolveRepo(opts.repo);
12640
12631
  const port = opts.port ? Number.parseInt(opts.port, 10) : 3402;
@@ -12704,7 +12695,7 @@ async function openWhenUp(port) {
12704
12695
 
12705
12696
  // src/commands/work.ts
12706
12697
  import { spawnSync as spawnSync3 } from "child_process";
12707
- function register23(program) {
12698
+ function register22(program) {
12708
12699
  program.command("work").description("The board \u2014 take work, prove it, finish it").argument("[args...]", "Passed to the harness untouched").allowUnknownOption().passThroughOptions().helpOption(false).action((passed) => {
12709
12700
  const problem = harnessProblem();
12710
12701
  if (problem) {
@@ -12727,11 +12718,11 @@ function register23(program) {
12727
12718
  // src/cli.ts
12728
12719
  function createCli() {
12729
12720
  const program = new Command().enablePositionalOptions().name("jarvis").description("Jarvis local agent \u2014 watches Claude Code sessions on your machine").version(BUILD_LABEL);
12730
- register4(program);
12731
12721
  register3(program);
12722
+ register4(program);
12732
12723
  register5(program);
12733
- register6(program);
12734
12724
  register(program);
12725
+ register6(program);
12735
12726
  register7(program);
12736
12727
  register8(program);
12737
12728
  register9(program);
@@ -12746,10 +12737,9 @@ function createCli() {
12746
12737
  register18(program);
12747
12738
  register19(program);
12748
12739
  register20(program);
12749
- register21(program);
12750
12740
  register2(program);
12741
+ register21(program);
12751
12742
  register22(program);
12752
- register23(program);
12753
12743
  return program;
12754
12744
  }
12755
12745