@appchy/jarvis 0.1.106 → 0.1.107

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,65 +1387,10 @@ async function ensureGraphify(options = {}) {
1387
1387
  );
1388
1388
  }
1389
1389
 
1390
- // src/graph/hook.ts
1391
- import { existsSync, mkdirSync, readFileSync, 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 installCommitHook(repoRoot) {
1411
- const dir = path7.join(repoRoot, ".git", "hooks");
1412
- const file = path7.join(dir, "post-commit");
1413
- if (!existsSync(path7.join(repoRoot, ".git")) || !existsSync(path7.join(repoRoot, ".git", "HEAD"))) {
1414
- return { installed: false, reason: "not-a-repo" };
1415
- }
1416
- if (existsSync(file)) {
1417
- try {
1418
- if (!readFileSync(file, "utf8").includes(SIGNATURE))
1419
- return { installed: false, reason: "foreign-hook", path: file };
1420
- } catch {
1421
- return { installed: false, reason: "unwritable", path: file };
1422
- }
1423
- }
1424
- try {
1425
- mkdirSync(dir, { recursive: true });
1426
- writeFileSync(file, SCRIPT, "utf8");
1427
- chmodSync(file, 493);
1428
- return { installed: true, path: file };
1429
- } catch {
1430
- return { installed: false, reason: "unwritable", path: file };
1431
- }
1432
- }
1433
- function describeCommitHook(outcome, repoRoot) {
1434
- if (outcome.installed)
1435
- return ` the map rebuilds itself on every commit here \u2713 (${path7.relative(repoRoot, outcome.path) || outcome.path})`;
1436
- if (outcome.reason === "not-a-repo")
1437
- return ` not a git repo, so there is no commit to rebuild on.
1438
- Run 'jarvis init' inside one, or rebuild by hand with 'jarvis build graph'.`;
1439
- if (outcome.reason === "foreign-hook")
1440
- return ` a post-commit hook is already here and it is not ours \u2014 left untouched.
1441
- Add this line to it to keep the map current: jarvis build graph >/dev/null 2>&1 &`;
1442
- return ` could not write the hook \u2014 the map still builds, by hand, with 'jarvis build graph'.`;
1443
- }
1444
-
1445
1390
  // src/machine.ts
1446
1391
  import crypto2 from "crypto";
1447
1392
  import fs8 from "fs";
1448
- import path8 from "path";
1393
+ import path7 from "path";
1449
1394
  var cached = null;
1450
1395
  function getMachine() {
1451
1396
  if (cached) return cached;
@@ -1460,7 +1405,7 @@ function getMachine() {
1460
1405
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1461
1406
  schemaVersion: 1
1462
1407
  };
1463
- fs8.mkdirSync(path8.dirname(file), { recursive: true });
1408
+ fs8.mkdirSync(path7.dirname(file), { recursive: true });
1464
1409
  fs8.writeFileSync(file, JSON.stringify(fresh, null, 2));
1465
1410
  return cached = fresh;
1466
1411
  }
@@ -1468,13 +1413,13 @@ function getMachine() {
1468
1413
  // src/service.ts
1469
1414
  import { execSync as execSync3, spawn } from "child_process";
1470
1415
  import fs9 from "fs";
1471
- import path9 from "path";
1416
+ import path8 from "path";
1472
1417
  import os4 from "os";
1473
1418
  function serviceSuffix() {
1474
1419
  const dir = getConfigDir();
1475
- const base = path9.join(os4.homedir(), ".jarvis");
1420
+ const base = path8.join(os4.homedir(), ".jarvis");
1476
1421
  if (dir === base) return "";
1477
- const name = dir.startsWith(base + path9.sep) ? dir.slice(base.length + 1) : path9.basename(dir);
1422
+ const name = dir.startsWith(base + path8.sep) ? dir.slice(base.length + 1) : path8.basename(dir);
1478
1423
  return name.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-|-$/g, "");
1479
1424
  }
1480
1425
  var SERVICE_SUFFIX = serviceSuffix();
@@ -1485,8 +1430,8 @@ function createServiceManager() {
1485
1430
  return new FallbackService();
1486
1431
  }
1487
1432
  var PLIST_LABEL = `com.appchy.jarvis${SERVICE_SUFFIX ? `.${SERVICE_SUFFIX}` : ""}`;
1488
- var PLIST_DIR = path9.join(os4.homedir(), "Library", "LaunchAgents");
1489
- var PLIST_PATH = path9.join(PLIST_DIR, `${PLIST_LABEL}.plist`);
1433
+ var PLIST_DIR = path8.join(os4.homedir(), "Library", "LaunchAgents");
1434
+ var PLIST_PATH = path8.join(PLIST_DIR, `${PLIST_LABEL}.plist`);
1490
1435
  function escapeXml(s) {
1491
1436
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
1492
1437
  }
@@ -1640,7 +1585,7 @@ ${Object.entries(opts.env ?? {}).map(([k, v]) => ` <key>${escapeXml(k)}</key>
1640
1585
  </plist>
1641
1586
  `;
1642
1587
  fs9.mkdirSync(PLIST_DIR, { recursive: true });
1643
- fs9.mkdirSync(path9.dirname(logFile), { recursive: true });
1588
+ fs9.mkdirSync(path8.dirname(logFile), { recursive: true });
1644
1589
  unloadAgent();
1645
1590
  fs9.writeFileSync(PLIST_PATH, plist);
1646
1591
  loadAgent();
@@ -1742,7 +1687,7 @@ var WindowsService = class {
1742
1687
  </Task>
1743
1688
  `;
1744
1689
  const tmpDir = os4.tmpdir();
1745
- const tmpFile = path9.join(tmpDir, `jarvis-task-${Date.now()}.xml`);
1690
+ const tmpFile = path8.join(tmpDir, `jarvis-task-${Date.now()}.xml`);
1746
1691
  fs9.writeFileSync(tmpFile, xml, { encoding: "utf-16le" });
1747
1692
  try {
1748
1693
  execSync3(`schtasks /Create /TN "${TASK_NAME}" /XML "${tmpFile}" /F`, {
@@ -1788,9 +1733,9 @@ var WindowsService = class {
1788
1733
  }
1789
1734
  }
1790
1735
  };
1791
- var SYSTEMD_DIR = path9.join(os4.homedir(), ".config", "systemd", "user");
1736
+ var SYSTEMD_DIR = path8.join(os4.homedir(), ".config", "systemd", "user");
1792
1737
  var UNIT_NAME = `jarvis${SERVICE_SUFFIX ? `-${SERVICE_SUFFIX}` : ""}.service`;
1793
- var UNIT_PATH = path9.join(SYSTEMD_DIR, UNIT_NAME);
1738
+ var UNIT_PATH = path8.join(SYSTEMD_DIR, UNIT_NAME);
1794
1739
  var LinuxService = class {
1795
1740
  install(opts) {
1796
1741
  const args = [opts.entryPath, "start", "--foreground", "--workspace", opts.workspacePath];
@@ -1819,7 +1764,7 @@ StandardError=append:${logFile}
1819
1764
  WantedBy=default.target
1820
1765
  `;
1821
1766
  fs9.mkdirSync(SYSTEMD_DIR, { recursive: true });
1822
- fs9.mkdirSync(path9.dirname(logFile), { recursive: true });
1767
+ fs9.mkdirSync(path8.dirname(logFile), { recursive: true });
1823
1768
  if (this.isInstalled()) {
1824
1769
  try {
1825
1770
  execSync3(`systemctl --user stop ${UNIT_NAME}`, { stdio: "ignore" });
@@ -1899,9 +1844,9 @@ WantedBy=default.target
1899
1844
  };
1900
1845
  var FallbackService = class {
1901
1846
  baseDir = getJarvisDir();
1902
- pidFile = path9.join(this.baseDir, "agent.pid");
1903
- logFile = path9.join(this.baseDir, "agent.log");
1904
- markerFile = path9.join(this.baseDir, "service-installed");
1847
+ pidFile = path8.join(this.baseDir, "agent.pid");
1848
+ logFile = path8.join(this.baseDir, "agent.log");
1849
+ markerFile = path8.join(this.baseDir, "service-installed");
1905
1850
  install(opts) {
1906
1851
  fs9.mkdirSync(this.baseDir, { recursive: true });
1907
1852
  this.stop();
@@ -1976,11 +1921,11 @@ var FallbackService = class {
1976
1921
  };
1977
1922
 
1978
1923
  // src/hooks/install.ts
1979
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, realpathSync, writeFileSync as writeFileSync2 } from "fs";
1924
+ import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "fs";
1980
1925
  import os5 from "os";
1981
- import path10 from "path";
1982
- var SETTINGS_DIR = path10.join(os5.homedir(), ".claude");
1983
- var SETTINGS_FILE = path10.join(SETTINGS_DIR, "settings.json");
1926
+ import path9 from "path";
1927
+ var SETTINGS_DIR = path9.join(os5.homedir(), ".claude");
1928
+ var SETTINGS_FILE = path9.join(SETTINGS_DIR, "settings.json");
1984
1929
  var HOOK_STEMS = [
1985
1930
  "pre-tool-use",
1986
1931
  "session-start",
@@ -1998,7 +1943,7 @@ function jarvisHooks() {
1998
1943
  ];
1999
1944
  }
2000
1945
  function isJarvisCommand(command) {
2001
- const name = path10.basename(command);
1946
+ const name = path9.basename(command);
2002
1947
  return HOOK_STEMS.some((stem) => name === `${stem}.mjs` || name === `${stem}.dev.mjs`);
2003
1948
  }
2004
1949
  function getCliRoot() {
@@ -2011,22 +1956,22 @@ function getCliRoot() {
2011
1956
  entry = realpathSync(binPath);
2012
1957
  } catch {
2013
1958
  }
2014
- return path10.resolve(path10.dirname(entry), "..");
1959
+ return path9.resolve(path9.dirname(entry), "..");
2015
1960
  }
2016
1961
  function resolveHooks() {
2017
1962
  const cliRoot = getCliRoot();
2018
1963
  return jarvisHooks().map((h) => ({
2019
1964
  ...h,
2020
- binAbsPath: path10.join(cliRoot, "bin", h.binBasename)
1965
+ binAbsPath: path9.join(cliRoot, "bin", h.binBasename)
2021
1966
  }));
2022
1967
  }
2023
1968
  function ownsClaudeCode() {
2024
- return getConfigDir() === path10.join(os5.homedir(), ".jarvis");
1969
+ return getConfigDir() === path9.join(os5.homedir(), ".jarvis");
2025
1970
  }
2026
1971
  function readSettings() {
2027
- if (!existsSync2(SETTINGS_FILE)) return {};
1972
+ if (!existsSync(SETTINGS_FILE)) return {};
2028
1973
  try {
2029
- const raw = readFileSync2(SETTINGS_FILE, "utf-8");
1974
+ const raw = readFileSync(SETTINGS_FILE, "utf-8");
2030
1975
  return raw.trim() ? JSON.parse(raw) : {};
2031
1976
  } catch (err) {
2032
1977
  logger.sys.warn("[hooks.install] settings.json unreadable", {
@@ -2037,8 +1982,8 @@ function readSettings() {
2037
1982
  }
2038
1983
  function writeSettings(s) {
2039
1984
  try {
2040
- mkdirSync2(SETTINGS_DIR, { recursive: true });
2041
- writeFileSync2(SETTINGS_FILE, JSON.stringify(s, null, 2) + "\n");
1985
+ mkdirSync(SETTINGS_DIR, { recursive: true });
1986
+ writeFileSync(SETTINGS_FILE, JSON.stringify(s, null, 2) + "\n");
2042
1987
  return true;
2043
1988
  } catch (err) {
2044
1989
  logger.sys.warn("[hooks.install] settings.json unwritable", {
@@ -2083,7 +2028,7 @@ function claudeCodeHooksState() {
2083
2028
  return {
2084
2029
  type: hook.type,
2085
2030
  bin: hook.binAbsPath,
2086
- exists: existsSync2(hook.binAbsPath),
2031
+ exists: existsSync(hook.binAbsPath),
2087
2032
  ...command ? { command } : {}
2088
2033
  };
2089
2034
  });
@@ -2105,10 +2050,10 @@ function installClaudeCodeHooks() {
2105
2050
  expected: resolved.map((h) => ({
2106
2051
  type: h.type,
2107
2052
  bin: h.binAbsPath,
2108
- exists: existsSync2(h.binAbsPath)
2053
+ exists: existsSync(h.binAbsPath)
2109
2054
  }))
2110
2055
  });
2111
- const missing = resolved.filter((h) => !existsSync2(h.binAbsPath));
2056
+ const missing = resolved.filter((h) => !existsSync(h.binAbsPath));
2112
2057
  if (missing.length === resolved.length) {
2113
2058
  logger.sys.warn("[hooks.install] no bin shims found, skipping", {
2114
2059
  configDir: configDir2,
@@ -2119,7 +2064,7 @@ function installClaudeCodeHooks() {
2119
2064
  let settings = readSettings();
2120
2065
  const installed = [];
2121
2066
  for (const hook of resolved) {
2122
- if (!existsSync2(hook.binAbsPath)) {
2067
+ if (!existsSync(hook.binAbsPath)) {
2123
2068
  logger.sys.warn("[hooks.install] bin shim missing, skipping hook", {
2124
2069
  configDir: configDir2,
2125
2070
  type: hook.type,
@@ -2287,8 +2232,89 @@ Open Claude Code in a repo that has a work/ tree to see them.`);
2287
2232
  });
2288
2233
  }
2289
2234
 
2290
- // src/commands/init.ts
2235
+ // src/graph/hook.ts
2236
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, 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 dir = path10.join(repoRoot, ".git", "hooks");
2266
+ const file = path10.join(dir, "post-commit");
2267
+ if (!existsSync2(path10.join(repoRoot, ".git")) || !existsSync2(path10.join(repoRoot, ".git", "HEAD"))) {
2268
+ return { installed: false, reason: "not-a-repo" };
2269
+ }
2270
+ if (existsSync2(file)) {
2271
+ try {
2272
+ if (!readFileSync2(file, "utf8").includes(SIGNATURE))
2273
+ return { installed: false, reason: "foreign-hook", path: file };
2274
+ } catch {
2275
+ return { installed: false, reason: "unwritable", path: file };
2276
+ }
2277
+ }
2278
+ try {
2279
+ mkdirSync2(dir, { recursive: true });
2280
+ writeFileSync2(file, SCRIPT, "utf8");
2281
+ chmodSync(file, 493);
2282
+ return { installed: true, path: file };
2283
+ } catch {
2284
+ return { installed: false, reason: "unwritable", path: file };
2285
+ }
2286
+ }
2287
+ function describeCommitHook(outcome, repoRoot) {
2288
+ if (outcome.installed)
2289
+ return ` the map rebuilds itself on every commit here \u2713 (${path10.relative(repoRoot, outcome.path) || outcome.path})`;
2290
+ if (outcome.reason === "not-a-repo")
2291
+ return ` not a git repo, so there is no commit to rebuild on.
2292
+ Run this inside one, or rebuild by hand with 'jarvis build graph'.`;
2293
+ if (outcome.reason === "foreign-hook")
2294
+ return ` a post-commit hook is already here and it is not ours \u2014 left untouched.
2295
+ Add this line to it to keep the map current: jarvis build graph >/dev/null 2>&1 &`;
2296
+ return ` could not write the hook \u2014 the map still builds, by hand, with 'jarvis build graph'.`;
2297
+ }
2298
+
2299
+ // src/commands/repo.ts
2291
2300
  function register3(program) {
2301
+ const repo = program.command("repo").description("Set up the repo you are standing in \u2014 no pairing, no daemon, no network");
2302
+ repo.command("init").description("Keep this repo's map current by rebuilding it on every commit").action(() => {
2303
+ if (!setUpThisRepo()) process.exit(1);
2304
+ console.log(" It rebuilds from your next commit. To build one now: jarvis build graph\n");
2305
+ });
2306
+ }
2307
+ function setUpThisRepo() {
2308
+ const root = findRepoRoot(process.cwd()) ?? process.cwd();
2309
+ console.log(" \u25B8 Keeping this repo's map current");
2310
+ const outcome = installCommitHook(root);
2311
+ console.log(`${describeCommitHook(outcome, root)}
2312
+ `);
2313
+ return outcome.installed;
2314
+ }
2315
+
2316
+ // src/commands/init.ts
2317
+ function register4(program) {
2292
2318
  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) => {
2293
2319
  const ok = await runInit({
2294
2320
  url: opts.url,
@@ -2373,7 +2399,7 @@ async function setUpThisMachine(prompts) {
2373
2399
  console.log(" \u25B8 Wiring this machine's Claude Code to jarvis");
2374
2400
  installHooks();
2375
2401
  console.log();
2376
- setUpMapRebuild();
2402
+ setUpThisRepo();
2377
2403
  await setUpMapTool(prompts);
2378
2404
  console.log(" \u25B8 The model key the map embeds with");
2379
2405
  const key = loadConfig()?.openaiApiKey;
@@ -2384,12 +2410,6 @@ async function setUpThisMachine(prompts) {
2384
2410
  `
2385
2411
  );
2386
2412
  }
2387
- function setUpMapRebuild() {
2388
- const repoRoot = process.cwd();
2389
- console.log(" \u25B8 Keeping this repo's map current");
2390
- console.log(`${describeCommitHook(installCommitHook(repoRoot), repoRoot)}
2391
- `);
2392
- }
2393
2413
  async function setUpMapTool(prompts) {
2394
2414
  console.log(" \u25B8 The tool the map's code half is built from");
2395
2415
  const state2 = resolveGraphify();
@@ -2452,7 +2472,8 @@ function reportLocalOnly() {
2452
2472
  console.log(" \u2714 Done. This machine works in any repo that has a work/ tree:");
2453
2473
  console.log(" the board, the map, the session block, the rules that arrive on edit,");
2454
2474
  console.log(" and 'jarvis serve' for any agent that speaks MCP.\n");
2455
- console.log(" In a repo you have cloned: jarvis build graph");
2475
+ console.log(" In a repo you have cloned: jarvis repo init");
2476
+ console.log(" jarvis build graph");
2456
2477
  console.log(" jarvis work list\n");
2457
2478
  console.log(" It has joined no jarvis instance, so it has no web surface and cannot");
2458
2479
  console.log(" start sessions on other machines. Both need one:");
@@ -2664,7 +2685,7 @@ async function promptList(question, fallback) {
2664
2685
  }
2665
2686
 
2666
2687
  // src/commands/pair.ts
2667
- function register4(program) {
2688
+ function register5(program) {
2668
2689
  program.command("pair").description("Re-pair this machine (when token expired)").action(async () => {
2669
2690
  try {
2670
2691
  await runPair();
@@ -2778,7 +2799,7 @@ async function unpair() {
2778
2799
  clearConfig();
2779
2800
  return { attempted: true, serverStatus };
2780
2801
  }
2781
- function register5(program) {
2802
+ function register6(program) {
2782
2803
  program.command("unpair").description("Unregister this env from cloud and wipe local config").option("-y, --yes", "Skip confirmation prompt").action(async (opts) => {
2783
2804
  try {
2784
2805
  const config2 = loadConfig();
@@ -2833,7 +2854,7 @@ function getRoots() {
2833
2854
  const cfg = readConfig();
2834
2855
  return Array.isArray(cfg.roots) ? cfg.roots : [];
2835
2856
  }
2836
- function register6(program) {
2857
+ function register7(program) {
2837
2858
  const cmd = program.command("roots").description("Manage code-root directories");
2838
2859
  cmd.command("list", { isDefault: true }).description("List current roots").action(() => {
2839
2860
  const roots = getRoots();
@@ -2878,7 +2899,7 @@ function readLocalConfig() {
2878
2899
  return {};
2879
2900
  }
2880
2901
  }
2881
- function register7(program) {
2902
+ function register8(program) {
2882
2903
  program.command("settings").description("Show this env's settings (roots, repos map)").action(async () => {
2883
2904
  try {
2884
2905
  const config2 = loadConfig();
@@ -10260,7 +10281,7 @@ import { createRequire as createRequire2 } from "module";
10260
10281
  var _require = createRequire2(import.meta.url);
10261
10282
  var VERSION2 = _require("../package.json").version ?? "0.0.0";
10262
10283
  var IS_DEV = String(_require("../package.json").name ?? "").endsWith("-dev");
10263
- var SHA = "c471483";
10284
+ var SHA = "3992b72";
10264
10285
  var BUILT = "2026-09-11";
10265
10286
  var BUILD = SHA ?? "source";
10266
10287
  var BUILD_LABEL = `${SHA ? `${VERSION2} (${SHA}${BUILT ? ` ${BUILT}` : ""})` : `${VERSION2} (source)`}${IS_DEV ? " \u2014 development build" : ""}`;
@@ -10779,7 +10800,7 @@ async function fetchRoots(hubUrl, envId, token) {
10779
10800
  }
10780
10801
 
10781
10802
  // src/commands/start.ts
10782
- function register8(program) {
10803
+ function register9(program) {
10783
10804
  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) => {
10784
10805
  if (refuseWithoutInstance()) process.exit(1);
10785
10806
  const config2 = loadConfig();
@@ -10916,7 +10937,7 @@ function buildUpstreamConfig(req) {
10916
10937
  }
10917
10938
 
10918
10939
  // src/commands/stop.ts
10919
- function register9(program) {
10940
+ function register10(program) {
10920
10941
  program.command("stop").description("Stop the running agent").action(() => {
10921
10942
  uninstallClaudeCodeHooks();
10922
10943
  const service = createServiceManager();
@@ -10943,7 +10964,7 @@ function register9(program) {
10943
10964
  }
10944
10965
 
10945
10966
  // src/commands/restart.ts
10946
- function register10(program) {
10967
+ function register11(program) {
10947
10968
  program.command("restart").description("Restart the agent (alias for start \u2014 start always does a clean restart)").action(async () => {
10948
10969
  await program.parseAsync(["node", "jarvis", "start"]);
10949
10970
  });
@@ -10952,7 +10973,7 @@ function register10(program) {
10952
10973
  // src/commands/logs.ts
10953
10974
  import { spawn as spawn2, execSync as execSync6 } from "child_process";
10954
10975
  import fs16 from "fs";
10955
- function register11(program) {
10976
+ function register12(program) {
10956
10977
  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) => {
10957
10978
  const logFile = getLogFile();
10958
10979
  if (!fs16.existsSync(logFile)) {
@@ -11027,7 +11048,7 @@ function portOf(url) {
11027
11048
  // src/commands/status.ts
11028
11049
  var GREEN2 = (text) => `\x1B[32m${text}\x1B[0m`;
11029
11050
  var RED2 = (text) => `\x1B[31m${text}\x1B[0m`;
11030
- function register12(program) {
11051
+ function register13(program) {
11031
11052
  program.command("status").description("Show agent configuration and connection status").action(async () => {
11032
11053
  const config2 = loadConfig();
11033
11054
  const health = await getHealth();
@@ -11066,7 +11087,7 @@ function endpoint(probed) {
11066
11087
  }
11067
11088
 
11068
11089
  // src/commands/install.ts
11069
- function register13(program) {
11090
+ function register14(program) {
11070
11091
  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) => {
11071
11092
  if (refuseWithoutInstance()) process.exit(1);
11072
11093
  const config2 = loadConfig();
@@ -11115,7 +11136,7 @@ function register13(program) {
11115
11136
  import fs17 from "fs";
11116
11137
  import path19 from "path";
11117
11138
  import { createInterface as createInterface5 } from "readline";
11118
- function register14(program) {
11139
+ function register15(program) {
11119
11140
  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) => {
11120
11141
  try {
11121
11142
  await runUninstall(opts);
@@ -11177,7 +11198,7 @@ function confirm2(prompt) {
11177
11198
  }
11178
11199
 
11179
11200
  // src/commands/logout.ts
11180
- function register15(program) {
11201
+ function register16(program) {
11181
11202
  program.command("logout").description("Clear saved configuration").action(() => {
11182
11203
  clearConfig();
11183
11204
  console.log("Configuration cleared.");
@@ -11208,7 +11229,7 @@ async function call(path23, method, body) {
11208
11229
  }
11209
11230
  return await resp.json();
11210
11231
  }
11211
- function register16(program) {
11232
+ function register17(program) {
11212
11233
  const mcp = program.command("mcp").description("Connect an agent to this workspace's board");
11213
11234
  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) => {
11214
11235
  try {
@@ -11262,7 +11283,7 @@ function register16(program) {
11262
11283
  }
11263
11284
 
11264
11285
  // src/commands/model.ts
11265
- function register17(program) {
11286
+ function register18(program) {
11266
11287
  const model = program.command("model").description("Model access for the map's semantic search, on this machine");
11267
11288
  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) => {
11268
11289
  const config2 = loadConfig();
@@ -11521,7 +11542,7 @@ function isStale(lockPath, staleMs) {
11521
11542
  }
11522
11543
 
11523
11544
  // src/commands/build.ts
11524
- function register18(program) {
11545
+ function register19(program) {
11525
11546
  const build2 = program.command("build").description("Build an artifact from this repo");
11526
11547
  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) => {
11527
11548
  const argv = [
@@ -11581,7 +11602,7 @@ function isRedirected(req) {
11581
11602
  }
11582
11603
 
11583
11604
  // src/commands/dev.ts
11584
- function register19(program) {
11605
+ function register20(program) {
11585
11606
  const dev = program.command("dev").description("Run a development build in a repo, without replacing the installed jarvis");
11586
11607
  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) => {
11587
11608
  const current = readDevRedirect();
@@ -12298,7 +12319,7 @@ async function brief2(repo) {
12298
12319
  }
12299
12320
 
12300
12321
  // src/commands/serve.ts
12301
- function register20(program) {
12322
+ function register21(program) {
12302
12323
  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) => {
12303
12324
  const repo = resolveRepo(opts.repo);
12304
12325
  const problem = harnessProblem();
@@ -12603,7 +12624,7 @@ function whenRebuilt(dir, reload) {
12603
12624
  }
12604
12625
 
12605
12626
  // src/commands/ui.ts
12606
- function register21(program) {
12627
+ function register22(program) {
12607
12628
  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) => {
12608
12629
  const repo = resolveRepo(opts.repo);
12609
12630
  const port = opts.port ? Number.parseInt(opts.port, 10) : 3402;
@@ -12673,7 +12694,7 @@ async function openWhenUp(port) {
12673
12694
 
12674
12695
  // src/commands/work.ts
12675
12696
  import { spawnSync as spawnSync3 } from "child_process";
12676
- function register22(program) {
12697
+ function register23(program) {
12677
12698
  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) => {
12678
12699
  const problem = harnessProblem();
12679
12700
  if (problem) {
@@ -12696,11 +12717,11 @@ function register22(program) {
12696
12717
  // src/cli.ts
12697
12718
  function createCli() {
12698
12719
  const program = new Command().enablePositionalOptions().name("jarvis").description("Jarvis local agent \u2014 watches Claude Code sessions on your machine").version(BUILD_LABEL);
12699
- register3(program);
12700
12720
  register4(program);
12721
+ register3(program);
12701
12722
  register5(program);
12702
- register(program);
12703
12723
  register6(program);
12724
+ register(program);
12704
12725
  register7(program);
12705
12726
  register8(program);
12706
12727
  register9(program);
@@ -12715,9 +12736,10 @@ function createCli() {
12715
12736
  register18(program);
12716
12737
  register19(program);
12717
12738
  register20(program);
12718
- register2(program);
12719
12739
  register21(program);
12740
+ register2(program);
12720
12741
  register22(program);
12742
+ register23(program);
12721
12743
  return program;
12722
12744
  }
12723
12745