@appchy/jarvis 0.1.109 → 0.1.111

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,94 +2300,11 @@ 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) {
2322
- 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) => {
2304
+ function register3(program) {
2305
+ program.command("init").description(
2306
+ "Set up this machine and the repo you are standing in; join an instance only if you name one"
2307
+ ).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
2308
  const ok = await runInit({
2324
2309
  url: opts.url,
2325
2310
  skipDaemonInstall: opts.skipDaemon,
@@ -2414,6 +2399,14 @@ async function setUpThisMachine(prompts) {
2414
2399
  `
2415
2400
  );
2416
2401
  }
2402
+ function setUpThisRepo() {
2403
+ const root = findRepoRoot(process.cwd()) ?? process.cwd();
2404
+ console.log(" \u25B8 Keeping this repo's map current");
2405
+ const outcome = installCommitHook(root);
2406
+ console.log(`${describeCommitHook(outcome, root)}
2407
+ `);
2408
+ return outcome.installed;
2409
+ }
2417
2410
  async function setUpMapTool(prompts) {
2418
2411
  console.log(" \u25B8 The tool the map's code half is built from");
2419
2412
  const state2 = resolveGraphify();
@@ -2476,7 +2469,7 @@ function reportSetUp(joined) {
2476
2469
  console.log(" \u2714 Done. This machine works in any repo that has a work/ tree:");
2477
2470
  console.log(" the board, the map, the session block, the rules that arrive on edit,");
2478
2471
  console.log(" and 'jarvis serve' for any agent that speaks MCP.\n");
2479
- console.log(" In a repo you have cloned: jarvis repo init");
2472
+ console.log(" In a repo you have cloned: jarvis init");
2480
2473
  console.log(" jarvis build graph");
2481
2474
  console.log(" jarvis work list\n");
2482
2475
  if (joined) {
@@ -2695,7 +2688,7 @@ async function promptList(question, fallback) {
2695
2688
  }
2696
2689
 
2697
2690
  // src/commands/pair.ts
2698
- function register5(program) {
2691
+ function register4(program) {
2699
2692
  program.command("pair").description("Re-pair this machine (when token expired)").action(async () => {
2700
2693
  try {
2701
2694
  await runPair();
@@ -2809,7 +2802,7 @@ async function unpair() {
2809
2802
  clearConfig();
2810
2803
  return { attempted: true, serverStatus };
2811
2804
  }
2812
- function register6(program) {
2805
+ function register5(program) {
2813
2806
  program.command("unpair").description("Unregister this env from cloud and wipe local config").option("-y, --yes", "Skip confirmation prompt").action(async (opts) => {
2814
2807
  try {
2815
2808
  const config2 = loadConfig();
@@ -2864,7 +2857,7 @@ function getRoots() {
2864
2857
  const cfg = readConfig();
2865
2858
  return Array.isArray(cfg.roots) ? cfg.roots : [];
2866
2859
  }
2867
- function register7(program) {
2860
+ function register6(program) {
2868
2861
  const cmd = program.command("roots").description("Manage code-root directories");
2869
2862
  cmd.command("list", { isDefault: true }).description("List current roots").action(() => {
2870
2863
  const roots = getRoots();
@@ -2909,7 +2902,7 @@ function readLocalConfig() {
2909
2902
  return {};
2910
2903
  }
2911
2904
  }
2912
- function register8(program) {
2905
+ function register7(program) {
2913
2906
  program.command("settings").description("Show this env's settings (roots, repos map)").action(async () => {
2914
2907
  try {
2915
2908
  const config2 = loadConfig();
@@ -10291,7 +10284,7 @@ import { createRequire as createRequire2 } from "module";
10291
10284
  var _require = createRequire2(import.meta.url);
10292
10285
  var VERSION2 = _require("../package.json").version ?? "0.0.0";
10293
10286
  var IS_DEV = String(_require("../package.json").name ?? "").endsWith("-dev");
10294
- var SHA = "fd09a8d";
10287
+ var SHA = "c1c24cf";
10295
10288
  var BUILT = "2026-09-12";
10296
10289
  var BUILD = SHA ?? "source";
10297
10290
  var BUILD_LABEL = `${SHA ? `${VERSION2} (${SHA}${BUILT ? ` ${BUILT}` : ""})` : `${VERSION2} (source)`}${IS_DEV ? " \u2014 development build" : ""}`;
@@ -10810,7 +10803,7 @@ async function fetchRoots(hubUrl, envId, token) {
10810
10803
  }
10811
10804
 
10812
10805
  // src/commands/start.ts
10813
- function register9(program) {
10806
+ function register8(program) {
10814
10807
  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
10808
  if (refuseWithoutInstance()) process.exit(1);
10816
10809
  const config2 = loadConfig();
@@ -10947,7 +10940,7 @@ function buildUpstreamConfig(req) {
10947
10940
  }
10948
10941
 
10949
10942
  // src/commands/stop.ts
10950
- function register10(program) {
10943
+ function register9(program) {
10951
10944
  program.command("stop").description("Stop the running agent").action(() => {
10952
10945
  uninstallClaudeCodeHooks();
10953
10946
  const service = createServiceManager();
@@ -10974,7 +10967,7 @@ function register10(program) {
10974
10967
  }
10975
10968
 
10976
10969
  // src/commands/restart.ts
10977
- function register11(program) {
10970
+ function register10(program) {
10978
10971
  program.command("restart").description("Restart the agent (alias for start \u2014 start always does a clean restart)").action(async () => {
10979
10972
  await program.parseAsync(["node", "jarvis", "start"]);
10980
10973
  });
@@ -10983,7 +10976,7 @@ function register11(program) {
10983
10976
  // src/commands/logs.ts
10984
10977
  import { spawn as spawn2, execSync as execSync6 } from "child_process";
10985
10978
  import fs16 from "fs";
10986
- function register12(program) {
10979
+ function register11(program) {
10987
10980
  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
10981
  const logFile = getLogFile();
10989
10982
  if (!fs16.existsSync(logFile)) {
@@ -11058,7 +11051,7 @@ function portOf(url) {
11058
11051
  // src/commands/status.ts
11059
11052
  var GREEN2 = (text) => `\x1B[32m${text}\x1B[0m`;
11060
11053
  var RED2 = (text) => `\x1B[31m${text}\x1B[0m`;
11061
- function register13(program) {
11054
+ function register12(program) {
11062
11055
  program.command("status").description("Show agent configuration and connection status").action(async () => {
11063
11056
  const config2 = loadConfig();
11064
11057
  const health = await getHealth();
@@ -11097,7 +11090,7 @@ function endpoint(probed) {
11097
11090
  }
11098
11091
 
11099
11092
  // src/commands/install.ts
11100
- function register14(program) {
11093
+ function register13(program) {
11101
11094
  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
11095
  if (refuseWithoutInstance()) process.exit(1);
11103
11096
  const config2 = loadConfig();
@@ -11146,7 +11139,7 @@ function register14(program) {
11146
11139
  import fs17 from "fs";
11147
11140
  import path19 from "path";
11148
11141
  import { createInterface as createInterface5 } from "readline";
11149
- function register15(program) {
11142
+ function register14(program) {
11150
11143
  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
11144
  try {
11152
11145
  await runUninstall(opts);
@@ -11208,7 +11201,7 @@ function confirm2(prompt) {
11208
11201
  }
11209
11202
 
11210
11203
  // src/commands/logout.ts
11211
- function register16(program) {
11204
+ function register15(program) {
11212
11205
  program.command("logout").description("Clear saved configuration").action(() => {
11213
11206
  clearConfig();
11214
11207
  console.log("Configuration cleared.");
@@ -11239,7 +11232,7 @@ async function call(path23, method, body) {
11239
11232
  }
11240
11233
  return await resp.json();
11241
11234
  }
11242
- function register17(program) {
11235
+ function register16(program) {
11243
11236
  const mcp = program.command("mcp").description("Connect an agent to this workspace's board");
11244
11237
  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
11238
  try {
@@ -11293,7 +11286,7 @@ function register17(program) {
11293
11286
  }
11294
11287
 
11295
11288
  // src/commands/model.ts
11296
- function register18(program) {
11289
+ function register17(program) {
11297
11290
  const model = program.command("model").description("Model access for the map's semantic search, on this machine");
11298
11291
  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
11292
  const config2 = loadConfig();
@@ -11552,7 +11545,7 @@ function isStale(lockPath, staleMs) {
11552
11545
  }
11553
11546
 
11554
11547
  // src/commands/build.ts
11555
- function register19(program) {
11548
+ function register18(program) {
11556
11549
  const build2 = program.command("build").description("Build an artifact from this repo");
11557
11550
  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
11551
  const argv = [
@@ -11612,7 +11605,7 @@ function isRedirected(req) {
11612
11605
  }
11613
11606
 
11614
11607
  // src/commands/dev.ts
11615
- function register20(program) {
11608
+ function register19(program) {
11616
11609
  const dev = program.command("dev").description("Run a development build in a repo, without replacing the installed jarvis");
11617
11610
  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
11611
  const current = readDevRedirect();
@@ -12329,7 +12322,7 @@ async function brief2(repo) {
12329
12322
  }
12330
12323
 
12331
12324
  // src/commands/serve.ts
12332
- function register21(program) {
12325
+ function register20(program) {
12333
12326
  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
12327
  const repo = resolveRepo(opts.repo);
12335
12328
  const problem = harnessProblem();
@@ -12634,7 +12627,7 @@ function whenRebuilt(dir, reload) {
12634
12627
  }
12635
12628
 
12636
12629
  // src/commands/ui.ts
12637
- function register22(program) {
12630
+ function register21(program) {
12638
12631
  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
12632
  const repo = resolveRepo(opts.repo);
12640
12633
  const port = opts.port ? Number.parseInt(opts.port, 10) : 3402;
@@ -12704,7 +12697,7 @@ async function openWhenUp(port) {
12704
12697
 
12705
12698
  // src/commands/work.ts
12706
12699
  import { spawnSync as spawnSync3 } from "child_process";
12707
- function register23(program) {
12700
+ function register22(program) {
12708
12701
  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
12702
  const problem = harnessProblem();
12710
12703
  if (problem) {
@@ -12727,11 +12720,11 @@ function register23(program) {
12727
12720
  // src/cli.ts
12728
12721
  function createCli() {
12729
12722
  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
12723
  register3(program);
12724
+ register4(program);
12732
12725
  register5(program);
12733
- register6(program);
12734
12726
  register(program);
12727
+ register6(program);
12735
12728
  register7(program);
12736
12729
  register8(program);
12737
12730
  register9(program);
@@ -12746,10 +12739,9 @@ function createCli() {
12746
12739
  register18(program);
12747
12740
  register19(program);
12748
12741
  register20(program);
12749
- register21(program);
12750
12742
  register2(program);
12743
+ register21(program);
12751
12744
  register22(program);
12752
- register23(program);
12753
12745
  return program;
12754
12746
  }
12755
12747