@appchy/jarvis 0.1.122 → 0.1.124

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
@@ -4514,7 +4514,15 @@ function toHolders(commits) {
4514
4514
  // Only a person's own machine reports an actor today; an unattended shift is
4515
4515
  // the thing `next` records, and it commits the same way.
4516
4516
  actor: /\bactor=automation\b/.test(commit.message) ? "automation" : "person",
4517
- quiet: isQuiet(commit)
4517
+ quiet: isQuiet(commit),
4518
+ // Knowing nothing is the DEFAULT, and only a reader standing on the machine a
4519
+ // take was made on replaces it. The hosted app reads this same history out of
4520
+ // GitHub with no machine underneath it, so it keeps these and reports that it
4521
+ // cannot tell — which is the honest answer, where "nobody is running it" would
4522
+ // be a confident wrong one.
4523
+ live: "unknown",
4524
+ addresses: [],
4525
+ processes: 0
4518
4526
  });
4519
4527
  }
4520
4528
  const bySession = /* @__PURE__ */ new Map();
@@ -4546,10 +4554,22 @@ function warning(holders, mine) {
4546
4554
  const said = others.map((holder) => {
4547
4555
  const ago = describeAge(holder.takenAt);
4548
4556
  const quiet = holder.quiet ? ", and has made no commits for over eight hours" : "";
4549
- return `${holder.by || holder.session} on ${holder.envId || "an unnamed machine"}, branch ${holder.branch || "unknown"}, ${ago}${quiet}`;
4557
+ return `${holder.by || holder.session} on ${holder.envId || "an unnamed machine"}, branch ${holder.branch || "unknown"}, ${ago}${quiet}${describeReach(holder)}`;
4550
4558
  });
4551
4559
  const took = others.some((holder) => holder.tookOverFrom) ? " Somebody has already taken over once." : "";
4552
- return `Somebody else is on this: ${said.join("; ")}.${took} Nothing is stopping you \u2014 decide whether to go ahead, and your take is recorded beside theirs.`;
4560
+ const anyone = others.some((holder) => holder.live !== "ended");
4561
+ const opener = anyone ? `Somebody else is on this: ${said.join("; ")}.` : `This was taken and abandoned rather than held \u2014 ${said.join("; ")}.`;
4562
+ return `${opener}${took} Nothing is stopping you \u2014 decide whether to go ahead, and your take is recorded beside theirs.`;
4563
+ }
4564
+ function describeReach(holder) {
4565
+ if (holder.live === "ended") return ", whose run has since ENDED";
4566
+ if (holder.live === "unknown") return "";
4567
+ if (holder.live === "forked") {
4568
+ const names = holder.addresses.map((each) => `\`${each.name}\``).join(" and ");
4569
+ return `, running as ${holder.processes} processes on one session` + (names ? ` \u2014 ${names}, either of which reaches it` : "");
4570
+ }
4571
+ const name = holder.addresses[0]?.name;
4572
+ return name ? `, still running as \`${name}\`` : ", still running";
4553
4573
  }
4554
4574
  function isQuiet(commit) {
4555
4575
  const at = Date.parse(commit.branchLastCommitAt || commit.when);
@@ -4560,7 +4580,7 @@ function readTrailers(message) {
4560
4580
  const events = [];
4561
4581
  const items = [];
4562
4582
  let session = "";
4563
- let machine = "";
4583
+ let machine2 = "";
4564
4584
  for (const raw of message.split("\n")) {
4565
4585
  const line = raw.trim();
4566
4586
  const m = /^(Work-[A-Za-z]+):\s*(.*)$/.exec(line);
@@ -4568,9 +4588,9 @@ function readTrailers(message) {
4568
4588
  if (m[1] === "Work-Event" && m[2]) events.push(m[2]);
4569
4589
  if (m[1] === "Work-Item" && m[2]) items.push(m[2]);
4570
4590
  if (m[1] === "Work-Session") session = m[2] ?? "";
4571
- if (m[1] === "Work-Machine") machine = m[2] ?? "";
4591
+ if (m[1] === "Work-Machine") machine2 = m[2] ?? "";
4572
4592
  }
4573
- return { session, machine, events, items };
4593
+ return { session, machine: machine2, events, items };
4574
4594
  }
4575
4595
  function describeAge(when) {
4576
4596
  const at = Date.parse(when);
@@ -4582,6 +4602,77 @@ function describeAge(when) {
4582
4602
  return `${Math.round(hours / 24)} day(s) ago`;
4583
4603
  }
4584
4604
 
4605
+ // ../../packages/board/src/peers.ts
4606
+ import { readdirSync as readdirSync4, readFileSync as readFileSync5, statSync as statSync3 } from "fs";
4607
+ import { hostname } from "os";
4608
+ import { homedir as homedir5 } from "os";
4609
+ import { join as join4 } from "path";
4610
+ var SESSIONS_DIR = "WORK_SESSIONS_DIR";
4611
+ var DOORS = { cli: "a terminal", "claude-vscode": "an editor" };
4612
+ function findPeers() {
4613
+ const where = process.env[SESSIONS_DIR] || join4(homedir5(), ".claude", "sessions");
4614
+ let files2;
4615
+ try {
4616
+ if (!statSync3(where).isDirectory()) return null;
4617
+ files2 = readdirSync4(where).filter((each) => each.endsWith(".json"));
4618
+ } catch {
4619
+ return null;
4620
+ }
4621
+ const live3 = /* @__PURE__ */ new Map();
4622
+ for (const file of files2.sort()) {
4623
+ let entry;
4624
+ try {
4625
+ entry = JSON.parse(readFileSync5(join4(where, file), "utf8"));
4626
+ } catch {
4627
+ continue;
4628
+ }
4629
+ if (!entry || typeof entry !== "object") continue;
4630
+ const session = String(entry.sessionId ?? "");
4631
+ const pid = Number(entry.pid);
4632
+ if (!session || !isAlive(pid)) continue;
4633
+ const peer = {
4634
+ session,
4635
+ name: String(entry.name ?? "").trim(),
4636
+ cwd: String(entry.cwd ?? ""),
4637
+ pid,
4638
+ from: String(entry.entrypoint ?? "").trim()
4639
+ };
4640
+ const already = live3.get(session);
4641
+ if (already) already.push(peer);
4642
+ else live3.set(session, [peer]);
4643
+ }
4644
+ return live3;
4645
+ }
4646
+ function toReach(holder, peers) {
4647
+ const away = Boolean(holder.envId) && Boolean(machine()) && holder.envId !== machine();
4648
+ const live3 = away ? null : peers;
4649
+ if (live3 === null || !holder.session) return { live: "unknown", addresses: [], processes: 0 };
4650
+ const running = live3.get(holder.session);
4651
+ if (!running || running.length === 0) return { live: "ended", addresses: [], processes: 0 };
4652
+ return {
4653
+ live: running.length > 1 ? "forked" : "running",
4654
+ // Counted from the processes, never from the addresses: one of them publishing
4655
+ // no name would otherwise make a fork report as though it were a single run.
4656
+ processes: running.length,
4657
+ addresses: toAddresses(running)
4658
+ };
4659
+ }
4660
+ function toAddresses(running) {
4661
+ return running.filter((each) => each.name).map((each) => ({ name: each.name, from: DOORS[each.from] ?? each.from })).sort((left, right) => left.name.localeCompare(right.name));
4662
+ }
4663
+ function machine() {
4664
+ return (process.env.WORK_MACHINE || hostname() || "").trim();
4665
+ }
4666
+ function isAlive(pid) {
4667
+ if (!Number.isInteger(pid) || pid <= 0) return false;
4668
+ try {
4669
+ process.kill(pid, 0);
4670
+ return true;
4671
+ } catch (error) {
4672
+ return error?.code === "EPERM";
4673
+ }
4674
+ }
4675
+
4585
4676
  // ../../packages/board/src/board.git.ts
4586
4677
  var run3 = promisify4(execFile4);
4587
4678
  var SOURCED = "%x1e%H%x1f%S%x1f%aI%x1f%an%x1f%B";
@@ -4648,7 +4739,15 @@ function shorten(ref) {
4648
4739
  return ref.replace(/^refs\/(heads|remotes)\//, "");
4649
4740
  }
4650
4741
  async function listHoldersByItem(root) {
4651
- return toHoldersByItem(await boardHistory(root));
4742
+ const byItem = toHoldersByItem(await boardHistory(root));
4743
+ const peers = findPeers();
4744
+ for (const [id, holders] of byItem) {
4745
+ byItem.set(
4746
+ id,
4747
+ holders.map((holder) => ({ ...holder, ...toReach(holder, peers) }))
4748
+ );
4749
+ }
4750
+ return byItem;
4652
4751
  }
4653
4752
  async function listHolders(root, id) {
4654
4753
  const byItem = await listHoldersByItem(root);
@@ -4658,7 +4757,7 @@ async function listHolders(root, id) {
4658
4757
  // ../../packages/board/src/board.tree.ts
4659
4758
  import { execFile as execFile5 } from "child_process";
4660
4759
  import { readdir, readFile, stat } from "fs/promises";
4661
- import { join as join4, relative, sep } from "path";
4760
+ import { join as join5, relative, sep } from "path";
4662
4761
  import { promisify as promisify5 } from "util";
4663
4762
 
4664
4763
  // ../../packages/errors/src/errors.ts
@@ -4819,8 +4918,8 @@ async function listWorkItems(_ctx, req, options) {
4819
4918
  return toPage(await scanTree(options.root), req);
4820
4919
  }
4821
4920
  async function findWorkItem(_ctx, req, options) {
4822
- const work = join4(options.root, "work");
4823
- for (const file of await walk(join4(work, "versions"))) {
4921
+ const work = join5(options.root, "work");
4922
+ for (const file of await walk(join5(work, "versions"))) {
4824
4923
  const path23 = pathIn(work, file);
4825
4924
  if (path23.split("/").at(-2) === req.id) return readItem(work, file);
4826
4925
  }
@@ -4833,7 +4932,7 @@ async function getWorkItem(ctx, req, options) {
4833
4932
  }
4834
4933
  async function getBrief(_ctx, req, options) {
4835
4934
  try {
4836
- return await readFile(join4(options.root, "work", req.path), "utf-8");
4935
+ return await readFile(join5(options.root, "work", req.path), "utf-8");
4837
4936
  } catch {
4838
4937
  return null;
4839
4938
  }
@@ -4968,9 +5067,9 @@ function scanTree(root) {
4968
5067
  var scanning = /* @__PURE__ */ new Map();
4969
5068
  var LEFT_THE_BOARD = ["complete", "archive"];
4970
5069
  async function readTree(root) {
4971
- const work = join4(root, "work");
5070
+ const work = join5(root, "work");
4972
5071
  const items = [];
4973
- for (const file of await walk(join4(work, "versions"))) {
5072
+ for (const file of await walk(join5(work, "versions"))) {
4974
5073
  const path23 = pathIn(work, file);
4975
5074
  if (LEFT_THE_BOARD.some((home) => path23.startsWith(`versions/${home}/`))) continue;
4976
5075
  const item2 = await readItem(work, file);
@@ -4996,7 +5095,7 @@ async function walk(dir, depth = 0) {
4996
5095
  }
4997
5096
  const found = [];
4998
5097
  for (const entry of entries) {
4999
- const full = join4(dir, entry.name);
5098
+ const full = join5(dir, entry.name);
5000
5099
  if (entry.isDirectory()) found.push(...await walk(full, depth + 1));
5001
5100
  else if (entry.name === ITEM_FILE) found.push(full);
5002
5101
  }
@@ -5114,16 +5213,16 @@ async function createWorkItem2(ctx, req, options) {
5114
5213
  // src/harness.ts
5115
5214
  import { spawnSync as spawnSync2 } from "child_process";
5116
5215
  import { existsSync as existsSync5 } from "fs";
5117
- import { dirname as dirname3, join as join5 } from "path";
5216
+ import { dirname as dirname3, join as join6 } from "path";
5118
5217
  import { fileURLToPath as fileURLToPath2 } from "url";
5119
- var ENTRY = join5("harness", "work.py");
5218
+ var ENTRY = join6("harness", "work.py");
5120
5219
  var INTERPRETERS = ["python3", "python"];
5121
5220
  var OLDEST = [3, 9];
5122
5221
  var INSTALLED = ["jarvis", "work"];
5123
5222
  function payload() {
5124
5223
  let dir = dirname3(fileURLToPath2(import.meta.url));
5125
5224
  for (let up = 0; up < 6; up++) {
5126
- if (existsSync5(join5(dir, ENTRY))) return join5(dir, ENTRY);
5225
+ if (existsSync5(join6(dir, ENTRY))) return join6(dir, ENTRY);
5127
5226
  const parent = dirname3(dir);
5128
5227
  if (parent === dir) break;
5129
5228
  dir = parent;
@@ -5642,7 +5741,7 @@ async function runEntries(req) {
5642
5741
  await Promise.all(scopes.map((scope2) => shape(run6, scope2)));
5643
5742
  for (const scope2 of scopes) await mint(run6, scope2);
5644
5743
  for (const scope2 of scopes) link(run6, scope2);
5645
- for (const spec of connects) await join6(run6, spec);
5744
+ for (const spec of connects) await join7(run6, spec);
5646
5745
  for (const diagnostic of silence(scopes)) run6.report(diagnostic);
5647
5746
  return scopes.map((scope2) => scope2.ledger);
5648
5747
  }
@@ -5884,7 +5983,7 @@ function emit(run6, scope2, request) {
5884
5983
  );
5885
5984
  scope2.ledger.edges[request.rel] = (scope2.ledger.edges[request.rel] ?? 0) + 1;
5886
5985
  }
5887
- async function join6(run6, spec) {
5986
+ async function join7(run6, spec) {
5888
5987
  const ctx = finderContext(run6, spec.name);
5889
5988
  const graph2 = {
5890
5989
  nodes: (type) => run6.graph.nodes(type),
@@ -6214,7 +6313,7 @@ function edgeMatchesConfidence(edge, backendName, confidence) {
6214
6313
  }
6215
6314
 
6216
6315
  // ../../packages/data/src/config.ts
6217
- import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
6316
+ import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
6218
6317
  import { readFile as readFile4 } from "fs/promises";
6219
6318
  import { dirname as dirname5, resolve as resolve4 } from "path";
6220
6319
  import { fileURLToPath as fileURLToPath3 } from "url";
@@ -6222,7 +6321,7 @@ import { createJiti } from "jiti";
6222
6321
 
6223
6322
  // ../../packages/data/src/persistences/local.ts
6224
6323
  import { mkdir, readFile as readFile3, writeFile } from "fs/promises";
6225
- import { dirname as dirname4, join as join7, resolve as resolve3 } from "path";
6324
+ import { dirname as dirname4, join as join8, resolve as resolve3 } from "path";
6226
6325
  function localFiles(options = {}) {
6227
6326
  const root = options.root ?? ".data";
6228
6327
  const rel = {
@@ -6235,7 +6334,7 @@ function localFiles(options = {}) {
6235
6334
  const pathOf = (ctx, key) => resolve3(
6236
6335
  ctx.repoRoot,
6237
6336
  root,
6238
- key.startsWith("plugin:") ? join7("plugins", `${key.slice(7)}.json`) : rel[key]
6337
+ key.startsWith("plugin:") ? join8("plugins", `${key.slice(7)}.json`) : rel[key]
6239
6338
  );
6240
6339
  return persistence({
6241
6340
  name: "local-files",
@@ -6304,7 +6403,7 @@ function packageRoot() {
6304
6403
  }
6305
6404
  function selfAlias() {
6306
6405
  const root = packageRoot();
6307
- const pkg = JSON.parse(readFileSync5(resolve4(root, "package.json"), "utf8"));
6406
+ const pkg = JSON.parse(readFileSync6(resolve4(root, "package.json"), "utf8"));
6308
6407
  if (pkg.name !== PACKAGE_NAME) {
6309
6408
  const vendored = process.env[VENDOR_ENV];
6310
6409
  if (!vendored) {
@@ -7595,7 +7694,7 @@ function leavesOf(ladder) {
7595
7694
  }
7596
7695
 
7597
7696
  // ../../packages/data/src/mcp/tools/cache.ts
7598
- import { statSync as statSync3 } from "fs";
7697
+ import { statSync as statSync4 } from "fs";
7599
7698
  import { resolve as resolve6 } from "path";
7600
7699
  var cache = /* @__PURE__ */ new WeakMap();
7601
7700
  async function cachedEnforcerDiags(ctx, freshPaths) {
@@ -7616,7 +7715,7 @@ function isFresh(snapshot, repoRoot, freshPaths) {
7616
7715
  for (const path23 of freshPaths) {
7617
7716
  let mtimeMs;
7618
7717
  try {
7619
- mtimeMs = statSync3(resolve6(repoRoot, path23)).mtimeMs;
7718
+ mtimeMs = statSync4(resolve6(repoRoot, path23)).mtimeMs;
7620
7719
  } catch {
7621
7720
  return false;
7622
7721
  }
@@ -10286,7 +10385,7 @@ import { createRequire as createRequire2 } from "module";
10286
10385
  var _require = createRequire2(import.meta.url);
10287
10386
  var VERSION2 = _require("../package.json").version ?? "0.0.0";
10288
10387
  var IS_DEV = String(_require("../package.json").name ?? "").endsWith("-dev");
10289
- var SHA = "63c9236";
10388
+ var SHA = "03f6896";
10290
10389
  var BUILT = "2026-09-12";
10291
10390
  var BUILD = SHA ?? "source";
10292
10391
  var BUILD_LABEL = `${SHA ? `${VERSION2} (${SHA}${BUILT ? ` ${BUILT}` : ""})` : `${VERSION2} (source)`}${IS_DEV ? " \u2014 development build" : ""}`;
@@ -11315,14 +11414,14 @@ function register17(program) {
11315
11414
  }
11316
11415
 
11317
11416
  // src/graph/build.ts
11318
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync7, rmSync, statSync as statSync4, writeFileSync as writeFileSync4 } from "fs";
11417
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync8, rmSync, statSync as statSync5, writeFileSync as writeFileSync4 } from "fs";
11319
11418
  import { dirname as dirname6, resolve as resolve8 } from "path";
11320
11419
 
11321
11420
  // src/graph/ratchet.ts
11322
11421
  import { execFileSync as execFileSync3 } from "child_process";
11323
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
11324
- import { join as join8 } from "path";
11325
- var BASELINE = join8(".claude", "governance.baseline.json");
11422
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
11423
+ import { join as join9 } from "path";
11424
+ var BASELINE = join9(".claude", "governance.baseline.json");
11326
11425
  var GOVERNS = (finding) => finding.severity === "warn";
11327
11426
  var REPORTED = (finding) => finding.severity === "info";
11328
11427
  function countByRule(findings) {
@@ -11334,7 +11433,7 @@ function countByRule(findings) {
11334
11433
  }
11335
11434
  function readBaseline(repo) {
11336
11435
  try {
11337
- const parsed = JSON.parse(readFileSync6(join8(repo, BASELINE), "utf-8"));
11436
+ const parsed = JSON.parse(readFileSync7(join9(repo, BASELINE), "utf-8"));
11338
11437
  const allowed = parsed?.allowed;
11339
11438
  return { allowed: allowed && typeof allowed === "object" ? allowed : {}, adopted: true };
11340
11439
  } catch {
@@ -11375,7 +11474,7 @@ function writeBaseline(repo, baseline) {
11375
11474
  const ordered = Object.fromEntries(
11376
11475
  Object.entries(baseline.allowed).filter(([, count2]) => count2 > 0).sort(([left], [right]) => left.localeCompare(right))
11377
11476
  );
11378
- writeFileSync3(join8(repo, BASELINE), `${JSON.stringify({ allowed: ordered }, null, 2)}
11477
+ writeFileSync3(join9(repo, BASELINE), `${JSON.stringify({ allowed: ordered }, null, 2)}
11379
11478
  `);
11380
11479
  }
11381
11480
  var NAMED = 5;
@@ -11543,7 +11642,7 @@ function acquireBuildLock(repoRoot, options = {}) {
11543
11642
  if (released) return;
11544
11643
  released = true;
11545
11644
  try {
11546
- if (readFileSync7(lockPath, "utf8").trim() !== String(process.pid)) return;
11645
+ if (readFileSync8(lockPath, "utf8").trim() !== String(process.pid)) return;
11547
11646
  } catch {
11548
11647
  return;
11549
11648
  }
@@ -11553,7 +11652,7 @@ function acquireBuildLock(repoRoot, options = {}) {
11553
11652
  }
11554
11653
  function isStale(lockPath, staleMs) {
11555
11654
  try {
11556
- return Math.max(0, Date.now() - statSync4(lockPath).mtimeMs) >= staleMs;
11655
+ return Math.max(0, Date.now() - statSync5(lockPath).mtimeMs) >= staleMs;
11557
11656
  } catch {
11558
11657
  return true;
11559
11658
  }
@@ -12056,10 +12155,20 @@ function createTool(handlers) {
12056
12155
  };
12057
12156
  }
12058
12157
  function describeItem(item2) {
12059
- const held = item2.holders && item2.holders.length > 0 ? ` \xB7 held by ${item2.holders.map((holder) => holder.by || holder.session).join(", ")}` : "";
12158
+ const held = item2.holders && item2.holders.length > 0 ? ` \xB7 ${item2.holders.map(describeHolder).join(", ")}` : "";
12060
12159
  const priority = item2.priority ? ` ${item2.priority}` : "";
12061
12160
  return `${item2.id} \xB7 ${item2.status}${priority}${held} \u2014 ${item2.title}`;
12062
12161
  }
12162
+ function describeHolder(holder) {
12163
+ const who = holder.by || holder.session;
12164
+ const names = (holder.addresses ?? []).map((each) => `\`${each.name}\``).join(", ");
12165
+ if (holder.live === "ended") return `ABANDONED by ${who}, whose run has ended`;
12166
+ if (holder.live === "forked") {
12167
+ return names ? `held by ${who} \xB7 ${holder.processes} runs on one session, ${names} \u2014 either reaches it` : `held by ${who} \xB7 ${holder.processes} runs on one session, none addressable`;
12168
+ }
12169
+ if (holder.live === "running") return names ? `held by ${who} ${names}` : `held by ${who}, running`;
12170
+ return `held by ${who} (cannot tell if still running)`;
12171
+ }
12063
12172
  function describeList(response) {
12064
12173
  if (response.items.length === 0) return "No work items match.";
12065
12174
  if (!response.hasMore) {
@@ -12211,7 +12320,7 @@ function describeStart(response) {
12211
12320
  }
12212
12321
 
12213
12322
  // src/serve/approvals.ts
12214
- import { readFileSync as readFileSync8 } from "fs";
12323
+ import { readFileSync as readFileSync9 } from "fs";
12215
12324
  import os10 from "os";
12216
12325
  import path22 from "path";
12217
12326
  function pendingApproval(cwd) {
@@ -12242,7 +12351,7 @@ function unapprovedServers(cwd) {
12242
12351
  }
12243
12352
  function readJson2(file) {
12244
12353
  try {
12245
- return JSON.parse(readFileSync8(file, "utf-8"));
12354
+ return JSON.parse(readFileSync9(file, "utf-8"));
12246
12355
  } catch {
12247
12356
  return null;
12248
12357
  }
@@ -12361,7 +12470,7 @@ import { basename as basename3 } from "path";
12361
12470
  // src/ui/server.ts
12362
12471
  import { createServer as createServer2 } from "http";
12363
12472
  import { readFile as readFile7 } from "fs/promises";
12364
- import { basename as basename2, dirname as dirname7, extname, join as join9, resolve as resolve9 } from "path";
12473
+ import { basename as basename2, dirname as dirname7, extname, join as join10, resolve as resolve9 } from "path";
12365
12474
  import { fileURLToPath as fileURLToPath4 } from "url";
12366
12475
 
12367
12476
  // src/ui/machine.ts
@@ -12433,7 +12542,7 @@ async function item(repo, id, res) {
12433
12542
  }
12434
12543
  async function asset(repo, assets, url, res) {
12435
12544
  const wanted = url.pathname === "/" || !extname(url.pathname) ? "/index.html" : url.pathname;
12436
- const path23 = join9(assets, wanted);
12545
+ const path23 = join10(assets, wanted);
12437
12546
  if (!path23.startsWith(assets)) {
12438
12547
  res.writeHead(403, { "cache-control": "no-store" }).end("no");
12439
12548
  return;
@@ -12524,13 +12633,13 @@ function serveUi(repo, port, options = {}) {
12524
12633
 
12525
12634
  // src/ui/source.ts
12526
12635
  import { spawn as spawn3 } from "child_process";
12527
- import { existsSync as existsSync7, readFileSync as readFileSync9, watch } from "fs";
12636
+ import { existsSync as existsSync7, readFileSync as readFileSync10, watch } from "fs";
12528
12637
  import { stat as stat3 } from "fs/promises";
12529
- import { dirname as dirname8, join as join10, resolve as resolve10 } from "path";
12638
+ import { dirname as dirname8, join as join11, resolve as resolve10 } from "path";
12530
12639
  import { fileURLToPath as fileURLToPath5 } from "url";
12531
- var PAGE = join10("apps", "cli", "dist", "ui");
12640
+ var PAGE = join11("apps", "cli", "dist", "ui");
12532
12641
  var BUNDLE = "app.js";
12533
- var WATCHED = [join10("apps", "cli", "src", "ui"), join10("packages", "ui", "src")];
12642
+ var WATCHED = [join11("apps", "cli", "src", "ui"), join11("packages", "ui", "src")];
12534
12643
  function fromSource() {
12535
12644
  return fileURLToPath5(import.meta.url).endsWith(".ts");
12536
12645
  }
@@ -12543,8 +12652,8 @@ function sourceCheckout() {
12543
12652
  }
12544
12653
  function builtFrom() {
12545
12654
  try {
12546
- const manifest = join10(dirname8(fileURLToPath5(import.meta.url)), "..", "package.json");
12547
- const read3 = JSON.parse(readFileSync9(manifest, "utf-8"));
12655
+ const manifest = join11(dirname8(fileURLToPath5(import.meta.url)), "..", "package.json");
12656
+ const read3 = JSON.parse(readFileSync10(manifest, "utf-8"));
12548
12657
  return typeof read3.jarvis?.source === "string" ? read3.jarvis.source : null;
12549
12658
  } catch {
12550
12659
  return null;
@@ -12552,16 +12661,16 @@ function builtFrom() {
12552
12661
  }
12553
12662
  function usable(root) {
12554
12663
  const files2 = [
12555
- join10(root, "apps", "cli", "src", "ui", "browser", "App.tsx"),
12556
- join10(root, "apps", "cli", "tsup.ui.config.ts")
12664
+ join11(root, "apps", "cli", "src", "ui", "browser", "App.tsx"),
12665
+ join11(root, "apps", "cli", "tsup.ui.config.ts")
12557
12666
  ];
12558
12667
  const present = files2.every((path23) => existsSync7(path23)) && tool(root, "tsup") && tool(root, "tsx");
12559
12668
  return present ? root : null;
12560
12669
  }
12561
12670
  function tool(root, name) {
12562
12671
  const places = [
12563
- join10(root, "apps", "cli", "node_modules", ".bin", name),
12564
- join10(root, "node_modules", ".bin", name)
12672
+ join11(root, "apps", "cli", "node_modules", ".bin", name),
12673
+ join11(root, "node_modules", ".bin", name)
12565
12674
  ];
12566
12675
  return places.find((path23) => existsSync7(path23)) ?? null;
12567
12676
  }
@@ -12571,7 +12680,7 @@ function runFromCheckout(req) {
12571
12680
  [
12572
12681
  "watch",
12573
12682
  "--clear-screen=false",
12574
- join10(req.root, "apps", "cli", "src", "bin.ts"),
12683
+ join11(req.root, "apps", "cli", "src", "bin.ts"),
12575
12684
  "ui",
12576
12685
  "--repo",
12577
12686
  req.repo,
@@ -12594,25 +12703,25 @@ function runFromCheckout(req) {
12594
12703
  return child;
12595
12704
  }
12596
12705
  async function watchPage(root) {
12597
- const dir = join10(root, PAGE);
12598
- const before = await changedAt(join10(dir, BUNDLE));
12706
+ const dir = join11(root, PAGE);
12707
+ const before = await changedAt(join11(dir, BUNDLE));
12599
12708
  const build2 = spawn3(
12600
12709
  tool(root, "tsup") ?? "tsup",
12601
12710
  [
12602
12711
  "--config",
12603
12712
  "tsup.ui.config.ts",
12604
- ...WATCHED.flatMap((where) => ["--watch", join10(root, where)])
12713
+ ...WATCHED.flatMap((where) => ["--watch", join11(root, where)])
12605
12714
  ],
12606
12715
  {
12607
12716
  stdio: ["ignore", "ignore", "inherit"],
12608
- cwd: join10(root, "apps", "cli")
12717
+ cwd: join11(root, "apps", "cli")
12609
12718
  }
12610
12719
  );
12611
12720
  const stop = () => {
12612
12721
  build2.kill("SIGTERM");
12613
12722
  };
12614
12723
  try {
12615
- await landed(join10(dir, BUNDLE), before);
12724
+ await landed(join11(dir, BUNDLE), before);
12616
12725
  } catch (err) {
12617
12726
  stop();
12618
12727
  throw err;