terminalhire 0.40.11 → 0.40.12

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.
@@ -1276,7 +1276,7 @@ async function requireStoredLogin() {
1276
1276
  }
1277
1277
  }
1278
1278
  function sleep(ms) {
1279
- return new Promise((resolve6) => setTimeout(resolve6, ms));
1279
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
1280
1280
  }
1281
1281
  var TERMINALHIRE_DIR3, TOKEN_FILE, ALGO, IV_BYTES, GITHUB_SCOPE, DEVICE_CODE_URL, ACCESS_TOKEN_URL, BAKED_IN_CLIENT_ID, MOCK_TOKEN, MOCK_LOGIN;
1282
1282
  var init_github_auth = __esm({
@@ -2343,8 +2343,8 @@ function makeGitHubGovernor(fetchImpl, cfg) {
2343
2343
  try {
2344
2344
  const res = bound == null ? await fetchP : await Promise.race([
2345
2345
  fetchP,
2346
- new Promise((resolve6) => {
2347
- timer = setTimeout(() => resolve6(null), bound);
2346
+ new Promise((resolve7) => {
2347
+ timer = setTimeout(() => resolve7(null), bound);
2348
2348
  })
2349
2349
  ]);
2350
2350
  if (!res || !res.ok) return null;
@@ -4391,14 +4391,14 @@ async function mapWithConcurrency(items, limit2, fn) {
4391
4391
  if (items.length === 0) return results;
4392
4392
  const workers = Math.max(1, Math.min(Math.floor(limit2) || 1, items.length));
4393
4393
  let next = 0;
4394
- async function run31() {
4394
+ async function run32() {
4395
4395
  for (; ; ) {
4396
4396
  const i = next++;
4397
4397
  if (i >= items.length) return;
4398
4398
  results[i] = await fn(items[i], i);
4399
4399
  }
4400
4400
  }
4401
- await Promise.all(Array.from({ length: workers }, run31));
4401
+ await Promise.all(Array.from({ length: workers }, run32));
4402
4402
  return results;
4403
4403
  }
4404
4404
  var init_concurrency = __esm({
@@ -6402,8 +6402,8 @@ async function getWithTimeout(governor, url, token, timeoutMs) {
6402
6402
  try {
6403
6403
  const res = await Promise.race([
6404
6404
  getP,
6405
- new Promise((resolve6) => {
6406
- timer = setTimeout(() => resolve6(null), timeoutMs);
6405
+ new Promise((resolve7) => {
6406
+ timer = setTimeout(() => resolve7(null), timeoutMs);
6407
6407
  })
6408
6408
  ]);
6409
6409
  if (res === null) controller.abort();
@@ -12383,10 +12383,10 @@ async function maybePromptPeerConnect({
12383
12383
  } = {}) {
12384
12384
  const promptOnce = ask5 ? async (q) => String(await ask5(q) ?? "").trim().toLowerCase() : async (q) => {
12385
12385
  const rl = createInterface({ input, output });
12386
- const a = await new Promise((resolve6) => {
12386
+ const a = await new Promise((resolve7) => {
12387
12387
  rl.question(q, (x) => {
12388
12388
  rl.close();
12389
- resolve6(x);
12389
+ resolve7(x);
12390
12390
  });
12391
12391
  });
12392
12392
  return String(a).trim().toLowerCase();
@@ -12500,11 +12500,11 @@ async function runLogin() {
12500
12500
  let ghProfile;
12501
12501
  if (process.env["TERMINALHIRE_GITHUB_MOCK"] === "1" || process.env["JPI_GITHUB_MOCK"] === "1") {
12502
12502
  const { fileURLToPath: fileURLToPath12 } = await import("url");
12503
- const { join: join47 } = await import("path");
12503
+ const { join: join48 } = await import("path");
12504
12504
  const __dirname9 = fileURLToPath12(new URL(".", import.meta.url));
12505
- const fixturePath = join47(__dirname9, "../../fixtures/github-sample.json");
12506
- const { readFileSync: readFileSync38 } = await import("fs");
12507
- ghProfile = JSON.parse(readFileSync38(fixturePath, "utf8"));
12505
+ const fixturePath = join48(__dirname9, "../../fixtures/github-sample.json");
12506
+ const { readFileSync: readFileSync39 } = await import("fs");
12507
+ ghProfile = JSON.parse(readFileSync39(fixturePath, "utf8"));
12508
12508
  } else {
12509
12509
  ghProfile = await fetchGitHubProfile2(login, token);
12510
12510
  }
@@ -13799,12 +13799,12 @@ async function maybeAskPulse() {
13799
13799
  }
13800
13800
  writeConfig({ lastPulseAskAt: (/* @__PURE__ */ new Date()).toISOString() });
13801
13801
  const rl = createInterface2({ input: process.stdin, output: process.stdout });
13802
- const ask5 = (question) => new Promise((resolve6) => {
13803
- const onClose = () => resolve6(null);
13802
+ const ask5 = (question) => new Promise((resolve7) => {
13803
+ const onClose = () => resolve7(null);
13804
13804
  rl.once("close", onClose);
13805
13805
  rl.question(question, (answer2) => {
13806
13806
  rl.removeListener("close", onClose);
13807
- resolve6((answer2 || "").trim());
13807
+ resolve7((answer2 || "").trim());
13808
13808
  });
13809
13809
  });
13810
13810
  const answer = await ask5(
@@ -13945,10 +13945,10 @@ async function fetchIndex() {
13945
13945
  }
13946
13946
  function prompt(question) {
13947
13947
  const rl = createInterface3({ input: process.stdin, output: process.stdout });
13948
- return new Promise((resolve6) => {
13948
+ return new Promise((resolve7) => {
13949
13949
  rl.question(question, (answer) => {
13950
13950
  rl.close();
13951
- resolve6(answer.trim().toLowerCase());
13951
+ resolve7(answer.trim().toLowerCase());
13952
13952
  });
13953
13953
  });
13954
13954
  }
@@ -14575,10 +14575,10 @@ __export(jpi_devs_exports, {
14575
14575
  import { createInterface as createInterface4 } from "readline";
14576
14576
  function prompt2(question) {
14577
14577
  const rl = createInterface4({ input: process.stdin, output: process.stdout });
14578
- return new Promise((resolve6) => {
14578
+ return new Promise((resolve7) => {
14579
14579
  rl.question(question, (answer) => {
14580
14580
  rl.close();
14581
- resolve6(answer.trim().toLowerCase());
14581
+ resolve7(answer.trim().toLowerCase());
14582
14582
  });
14583
14583
  });
14584
14584
  }
@@ -14721,10 +14721,10 @@ function readProject2() {
14721
14721
  }
14722
14722
  function promptRaw(question) {
14723
14723
  const rl = createInterface5({ input: process.stdin, output: process.stdout });
14724
- return new Promise((resolve6) => {
14724
+ return new Promise((resolve7) => {
14725
14725
  rl.question(question, (answer) => {
14726
14726
  rl.close();
14727
- resolve6(answer.trim());
14727
+ resolve7(answer.trim());
14728
14728
  });
14729
14729
  });
14730
14730
  }
@@ -15440,10 +15440,10 @@ async function fetchIndex2() {
15440
15440
  }
15441
15441
  function prompt3(question) {
15442
15442
  const rl = createInterface6({ input: process.stdin, output: process.stdout });
15443
- return new Promise((resolve6) => {
15443
+ return new Promise((resolve7) => {
15444
15444
  rl.question(question, (answer) => {
15445
15445
  rl.close();
15446
- resolve6(answer.trim().toLowerCase());
15446
+ resolve7(answer.trim().toLowerCase());
15447
15447
  });
15448
15448
  });
15449
15449
  }
@@ -16977,16 +16977,16 @@ var sleep2;
16977
16977
  var init_sleep = __esm({
16978
16978
  "../../node_modules/@anthropic-ai/sdk/internal/utils/sleep.mjs"() {
16979
16979
  "use strict";
16980
- sleep2 = (ms, signal) => new Promise((resolve6) => {
16980
+ sleep2 = (ms, signal) => new Promise((resolve7) => {
16981
16981
  if (signal?.aborted)
16982
- return resolve6();
16982
+ return resolve7();
16983
16983
  const onAbort = () => {
16984
16984
  clearTimeout(timer);
16985
- resolve6();
16985
+ resolve7();
16986
16986
  };
16987
16987
  const timer = setTimeout(() => {
16988
16988
  signal?.removeEventListener("abort", onAbort);
16989
- resolve6();
16989
+ resolve7();
16990
16990
  }, ms);
16991
16991
  signal?.addEventListener("abort", onAbort, { once: true });
16992
16992
  });
@@ -19115,8 +19115,8 @@ var init_api_promise = __esm({
19115
19115
  init_parse();
19116
19116
  APIPromise = class _APIPromise extends Promise {
19117
19117
  constructor(client, responsePromise, parseResponse = defaultParseResponse) {
19118
- super((resolve6) => {
19119
- resolve6(null);
19118
+ super((resolve7) => {
19119
+ resolve7(null);
19120
19120
  });
19121
19121
  this.responsePromise = responsePromise;
19122
19122
  this.parseResponse = parseResponse;
@@ -21636,16 +21636,16 @@ var init_async_queue = __esm({
21636
21636
  if (__classPrivateFieldGet(this, _AsyncQueue_closed, "f") || signal?.aborted) {
21637
21637
  return Promise.resolve({ done: true, value: void 0 });
21638
21638
  }
21639
- return new Promise((resolve6) => {
21639
+ return new Promise((resolve7) => {
21640
21640
  const waiter = (r) => {
21641
21641
  signal?.removeEventListener("abort", onAbort);
21642
- resolve6(r);
21642
+ resolve7(r);
21643
21643
  };
21644
21644
  const onAbort = () => {
21645
21645
  const idx = __classPrivateFieldGet(this, _AsyncQueue_waiters, "f").indexOf(waiter);
21646
21646
  if (idx >= 0)
21647
21647
  __classPrivateFieldGet(this, _AsyncQueue_waiters, "f").splice(idx, 1);
21648
- resolve6({ done: true, value: void 0 });
21648
+ resolve7({ done: true, value: void 0 });
21649
21649
  };
21650
21650
  __classPrivateFieldGet(this, _AsyncQueue_waiters, "f").push(waiter);
21651
21651
  signal?.addEventListener("abort", onAbort, { once: true });
@@ -22245,13 +22245,13 @@ var init_json_schema = __esm({
22245
22245
 
22246
22246
  // ../../node_modules/@anthropic-ai/sdk/internal/utils/promise.mjs
22247
22247
  function promiseWithResolvers() {
22248
- let resolve6;
22248
+ let resolve7;
22249
22249
  let reject;
22250
22250
  const promise = new Promise((res, rej) => {
22251
- resolve6 = res;
22251
+ resolve7 = res;
22252
22252
  reject = rej;
22253
22253
  });
22254
- return { promise, resolve: resolve6, reject };
22254
+ return { promise, resolve: resolve7, reject };
22255
22255
  }
22256
22256
  var init_promise = __esm({
22257
22257
  "../../node_modules/@anthropic-ai/sdk/internal/utils/promise.mjs"() {
@@ -22853,7 +22853,7 @@ function betaGrepTool(ctx) {
22853
22853
  });
22854
22854
  }
22855
22855
  function runRipgrep(rg, pattern, searchPath, signal) {
22856
- return new Promise((resolve6, reject) => {
22856
+ return new Promise((resolve7, reject) => {
22857
22857
  const proc = cp.spawn(rg, ["-n", "--no-heading", "-e", pattern, "--", searchPath], {
22858
22858
  ...signal ? { signal } : {}
22859
22859
  });
@@ -22875,12 +22875,12 @@ function runRipgrep(rg, pattern, searchPath, signal) {
22875
22875
  if (signal?.aborted)
22876
22876
  return reject(new ToolError("grep: aborted"));
22877
22877
  if (truncated)
22878
- return resolve6(out + `
22878
+ return resolve7(out + `
22879
22879
  [output truncated at ${GREP_OUTPUT_LIMIT} bytes]`);
22880
22880
  if (code === 0)
22881
- return resolve6(out);
22881
+ return resolve7(out);
22882
22882
  if (code === 1)
22883
- return resolve6("no matches");
22883
+ return resolve7("no matches");
22884
22884
  reject(new ToolError(`grep: rg failed: ${errOut || `exit ${code}`}`));
22885
22885
  });
22886
22886
  proc.on("error", (e) => {
@@ -23058,8 +23058,8 @@ var init_node = __esm({
23058
23058
  `;
23059
23059
  __classPrivateFieldGet(this, _BashSession_proc, "f").stdin.write(wrapped);
23060
23060
  if (__classPrivateFieldGet(this, _BashSession_buf, "f").indexOf(sentinel2) < 0) {
23061
- const { promise: sentinelSeen, resolve: resolve6 } = promiseWithResolvers();
23062
- __classPrivateFieldSet(this, _BashSession_waiting, { sentinel: sentinel2, resolve: resolve6 }, "f");
23061
+ const { promise: sentinelSeen, resolve: resolve7 } = promiseWithResolvers();
23062
+ __classPrivateFieldSet(this, _BashSession_waiting, { sentinel: sentinel2, resolve: resolve7 }, "f");
23063
23063
  let timer;
23064
23064
  let onAbort;
23065
23065
  try {
@@ -24814,12 +24814,12 @@ var init_BetaMessageStream = __esm({
24814
24814
  }
24815
24815
  return this._emit("error", new AnthropicError(String(error2)));
24816
24816
  });
24817
- __classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((resolve6, reject) => {
24818
- __classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise, resolve6, "f");
24817
+ __classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((resolve7, reject) => {
24818
+ __classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise, resolve7, "f");
24819
24819
  __classPrivateFieldSet(this, _BetaMessageStream_rejectConnectedPromise, reject, "f");
24820
24820
  }), "f");
24821
- __classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((resolve6, reject) => {
24822
- __classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise, resolve6, "f");
24821
+ __classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((resolve7, reject) => {
24822
+ __classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise, resolve7, "f");
24823
24823
  __classPrivateFieldSet(this, _BetaMessageStream_rejectEndPromise, reject, "f");
24824
24824
  }), "f");
24825
24825
  __classPrivateFieldGet(this, _BetaMessageStream_connectedPromise, "f").catch(() => {
@@ -24989,11 +24989,11 @@ var init_BetaMessageStream = __esm({
24989
24989
  * const message = await stream.emitted('message') // rejects if the stream errors
24990
24990
  */
24991
24991
  emitted(event) {
24992
- return new Promise((resolve6, reject) => {
24992
+ return new Promise((resolve7, reject) => {
24993
24993
  __classPrivateFieldSet(this, _BetaMessageStream_catchingPromiseCreated, true, "f");
24994
24994
  if (event !== "error")
24995
24995
  this.once("error", reject);
24996
- this.once(event, resolve6);
24996
+ this.once(event, resolve7);
24997
24997
  });
24998
24998
  }
24999
24999
  async done() {
@@ -25355,7 +25355,7 @@ var init_BetaMessageStream = __esm({
25355
25355
  if (done) {
25356
25356
  return { value: void 0, done: true };
25357
25357
  }
25358
- return new Promise((resolve6, reject) => readQueue.push({ resolve: resolve6, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
25358
+ return new Promise((resolve7, reject) => readQueue.push({ resolve: resolve7, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
25359
25359
  }
25360
25360
  const chunk = pushQueue.shift();
25361
25361
  return { value: chunk, done: false };
@@ -27593,12 +27593,12 @@ var init_MessageStream = __esm({
27593
27593
  }
27594
27594
  return this._emit("error", new AnthropicError(String(error2)));
27595
27595
  });
27596
- __classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((resolve6, reject) => {
27597
- __classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise, resolve6, "f");
27596
+ __classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((resolve7, reject) => {
27597
+ __classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise, resolve7, "f");
27598
27598
  __classPrivateFieldSet(this, _MessageStream_rejectConnectedPromise, reject, "f");
27599
27599
  }), "f");
27600
- __classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((resolve6, reject) => {
27601
- __classPrivateFieldSet(this, _MessageStream_resolveEndPromise, resolve6, "f");
27600
+ __classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((resolve7, reject) => {
27601
+ __classPrivateFieldSet(this, _MessageStream_resolveEndPromise, resolve7, "f");
27602
27602
  __classPrivateFieldSet(this, _MessageStream_rejectEndPromise, reject, "f");
27603
27603
  }), "f");
27604
27604
  __classPrivateFieldGet(this, _MessageStream_connectedPromise, "f").catch(() => {
@@ -27768,11 +27768,11 @@ var init_MessageStream = __esm({
27768
27768
  * const message = await stream.emitted('message') // rejects if the stream errors
27769
27769
  */
27770
27770
  emitted(event) {
27771
- return new Promise((resolve6, reject) => {
27771
+ return new Promise((resolve7, reject) => {
27772
27772
  __classPrivateFieldSet(this, _MessageStream_catchingPromiseCreated, true, "f");
27773
27773
  if (event !== "error")
27774
27774
  this.once("error", reject);
27775
- this.once(event, resolve6);
27775
+ this.once(event, resolve7);
27776
27776
  });
27777
27777
  }
27778
27778
  async done() {
@@ -28093,7 +28093,7 @@ var init_MessageStream = __esm({
28093
28093
  if (done) {
28094
28094
  return { value: void 0, done: true };
28095
28095
  }
28096
- return new Promise((resolve6, reject) => readQueue.push({ resolve: resolve6, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
28096
+ return new Promise((resolve7, reject) => readQueue.push({ resolve: resolve7, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
28097
28097
  }
28098
28098
  const chunk = pushQueue.shift();
28099
28099
  return { value: chunk, done: false };
@@ -30491,7 +30491,7 @@ function splitProgressChunk(chunk) {
30491
30491
  }
30492
30492
  function shStream(cmd, args5, opts = {}) {
30493
30493
  const cap = opts.maxStderrBytes ?? 64 * 1024;
30494
- return new Promise((resolve6, reject) => {
30494
+ return new Promise((resolve7, reject) => {
30495
30495
  void (async () => {
30496
30496
  const spawn4 = opts.spawnFn ?? (await import("child_process")).spawn;
30497
30497
  const child = spawn4(cmd, args5, { shell: false, stdio: ["ignore", "pipe", "pipe"] });
@@ -30509,7 +30509,7 @@ function shStream(cmd, args5, opts = {}) {
30509
30509
  child.on("error", (err) => reject(err));
30510
30510
  child.on("close", (code, signal) => {
30511
30511
  if (code === 0) {
30512
- resolve6({ stdout: stdout.trim(), stderr });
30512
+ resolve7({ stdout: stdout.trim(), stderr });
30513
30513
  return;
30514
30514
  }
30515
30515
  const err = new Error(
@@ -30945,7 +30945,7 @@ async function sh(cmd, args5, opts = {}) {
30945
30945
  async function confirm(question) {
30946
30946
  const rl = createInterface8({ input: process.stdin, output: process.stdout });
30947
30947
  try {
30948
- const ans = await new Promise((resolve6) => rl.question(question, resolve6));
30948
+ const ans = await new Promise((resolve7) => rl.question(question, resolve7));
30949
30949
  return /^y(es)?$/i.test(String(ans).trim());
30950
30950
  } finally {
30951
30951
  rl.close();
@@ -30954,7 +30954,7 @@ async function confirm(question) {
30954
30954
  async function ask(question) {
30955
30955
  const rl = createInterface8({ input: process.stdin, output: process.stdout });
30956
30956
  try {
30957
- const ans = await new Promise((resolve6) => rl.question(question, resolve6));
30957
+ const ans = await new Promise((resolve7) => rl.question(question, resolve7));
30958
30958
  return String(ans).trim();
30959
30959
  } finally {
30960
30960
  rl.close();
@@ -32980,21 +32980,21 @@ function buildPatchSubmission({ bountyId, claimId, patch, authorName, authorEmai
32980
32980
  }
32981
32981
  return { bountyId, claimId, patch, authorName, authorEmail, proofToken: auth.proofToken };
32982
32982
  }
32983
- function renderRunView(run31, message) {
32983
+ function renderRunView(run32, message) {
32984
32984
  const lines = [];
32985
- const sha = run31.commitSha ? String(run31.commitSha).slice(0, 10) : null;
32986
- lines.push(` run: ${run31.branch ?? "(no branch)"}${sha ? ` @ ${sha}` : ""}`);
32985
+ const sha = run32.commitSha ? String(run32.commitSha).slice(0, 10) : null;
32986
+ lines.push(` run: ${run32.branch ?? "(no branch)"}${sha ? ` @ ${sha}` : ""}`);
32987
32987
  lines.push(
32988
- ` status: ${terminalSafeInline(run31.status)}${run31.conclusion ? ` \xB7 conclusion: ${terminalSafeInline(run31.conclusion)}` : ""}`
32988
+ ` status: ${terminalSafeInline(run32.status)}${run32.conclusion ? ` \xB7 conclusion: ${terminalSafeInline(run32.conclusion)}` : ""}`
32989
32989
  );
32990
- if (Array.isArray(run31.failingJobs) && run31.failingJobs.length > 0) {
32991
- lines.push(` failing: ${run31.failingJobs.map(terminalSafeInline).join(", ")}`);
32990
+ if (Array.isArray(run32.failingJobs) && run32.failingJobs.length > 0) {
32991
+ lines.push(` failing: ${run32.failingJobs.map(terminalSafeInline).join(", ")}`);
32992
32992
  }
32993
- if (run31.previewUrl) lines.push(` preview: ${terminalSafeInline(run31.previewUrl)}`);
32994
- if (run31.roundTrips != null) lines.push(` round trips: ${run31.roundTrips}`);
32995
- if (run31.logTail) {
32993
+ if (run32.previewUrl) lines.push(` preview: ${terminalSafeInline(run32.previewUrl)}`);
32994
+ if (run32.roundTrips != null) lines.push(` round trips: ${run32.roundTrips}`);
32995
+ if (run32.logTail) {
32996
32996
  lines.push(" \u2500\u2500 log tail \u2500\u2500");
32997
- for (const l of terminalSafeLines(run31.logTail)) lines.push(` \u2502 ${l}`);
32997
+ for (const l of terminalSafeLines(run32.logTail)) lines.push(` \u2502 ${l}`);
32998
32998
  }
32999
32999
  if (message) lines.push(` ${message}`);
33000
33000
  return lines.join("\n");
@@ -34718,7 +34718,7 @@ an interactive terminal and creates an unowned web draft; the browser publishes
34718
34718
  async function ask2(question) {
34719
34719
  const rl = createInterface9({ input: process.stdin, output: process.stdout });
34720
34720
  try {
34721
- return await new Promise((resolve6) => rl.question(question, (answer) => resolve6(answer.trim())));
34721
+ return await new Promise((resolve7) => rl.question(question, (answer) => resolve7(answer.trim())));
34722
34722
  } finally {
34723
34723
  rl.close();
34724
34724
  }
@@ -35036,12 +35036,241 @@ var init_jpi_repo = __esm({
35036
35036
  }
35037
35037
  });
35038
35038
 
35039
+ // bin/jpi-run.js
35040
+ var jpi_run_exports = {};
35041
+ __export(jpi_run_exports, {
35042
+ run: () => run10
35043
+ });
35044
+ import { existsSync as existsSync17, readFileSync as readFileSync26 } from "fs";
35045
+ import { join as join33, resolve as resolve5 } from "path";
35046
+ import { tmpdir } from "os";
35047
+ import { mkdtempSync, rmSync as rmSync9 } from "fs";
35048
+ function parseArgs2(argv) {
35049
+ const out = { flags: {}, bools: /* @__PURE__ */ new Set() };
35050
+ for (let i = 0; i < argv.length; i += 1) {
35051
+ const arg = argv[i];
35052
+ if (!arg.startsWith("--")) continue;
35053
+ const name = arg.slice(2);
35054
+ if (["watch", "json", "no-preview", "help", "verbose"].includes(name)) {
35055
+ out.bools.add(name);
35056
+ continue;
35057
+ }
35058
+ const next = argv[i + 1];
35059
+ if (next === void 0 || next.startsWith("--")) {
35060
+ throw new Error(`terminalhire: --${name} needs a value`);
35061
+ }
35062
+ out.flags[name] = next;
35063
+ i += 1;
35064
+ }
35065
+ return out;
35066
+ }
35067
+ function runScratchRoot() {
35068
+ const root = mkdtempSync(join33(tmpdir(), "th-run-"));
35069
+ let cleaned = false;
35070
+ const cleanup = () => {
35071
+ if (cleaned) return;
35072
+ cleaned = true;
35073
+ try {
35074
+ rmSync9(root, { recursive: true, force: true });
35075
+ } catch {
35076
+ }
35077
+ };
35078
+ process.on("exit", cleanup);
35079
+ for (const sig of ["SIGINT", "SIGTERM", "SIGHUP"]) {
35080
+ process.on(sig, () => {
35081
+ cleanup();
35082
+ process.exit(130);
35083
+ });
35084
+ }
35085
+ return { root, cleanup };
35086
+ }
35087
+ async function loadEngine() {
35088
+ try {
35089
+ return await import("@terminalhire/envrun");
35090
+ } catch (err) {
35091
+ throw new Error(
35092
+ `terminalhire: \`run\` needs the @terminalhire/envrun engine, which is not installed here.
35093
+ It drives Docker and is not published, so this verb works from a monorepo checkout today. Run \`npm run -w @terminalhire/envrun build\` there first.
35094
+ (resolution error: ${err && err.message ? err.message : String(err)})`
35095
+ );
35096
+ }
35097
+ }
35098
+ function readConfig2(localDir) {
35099
+ const file = join33(localDir, ".th-run.json");
35100
+ if (!existsSync17(file)) return {};
35101
+ try {
35102
+ const parsed = JSON.parse(readFileSync26(file, "utf8"));
35103
+ return parsed && typeof parsed === "object" ? parsed : {};
35104
+ } catch (err) {
35105
+ throw new Error(
35106
+ `terminalhire: ${file} is not readable JSON (${err && err.message ? err.message : String(err)}). Fix or remove it \u2014 a config we cannot read is not a config we should guess at.`
35107
+ );
35108
+ }
35109
+ }
35110
+ function requireField(value, name, hint) {
35111
+ if (typeof value === "string" && value.trim() !== "") return value.trim();
35112
+ throw new Error(`terminalhire: run needs ${name}. ${hint}`);
35113
+ }
35114
+ async function once(engine, opts) {
35115
+ const { root } = opts.scratch;
35116
+ const started = Date.now();
35117
+ const outcome = await engine.verifyWorkingDiff({
35118
+ claimId: opts.claimId,
35119
+ localRepoDir: opts.localDir,
35120
+ sliceFiles: opts.slice,
35121
+ targetRepo: opts.target,
35122
+ targetSha: opts.sha,
35123
+ scratchRoot: root,
35124
+ preview: opts.preview,
35125
+ ...opts.testCommand ? { testCommandOverride: opts.testCommand } : {},
35126
+ onProgress: (stage, detail) => {
35127
+ if (!opts.json) process.stderr.write(` ${stage.padEnd(8)} ${detail}
35128
+ `);
35129
+ }
35130
+ });
35131
+ const { result, preview } = outcome;
35132
+ if (opts.json) {
35133
+ process.stdout.write(`${JSON.stringify(result, null, 2)}
35134
+ `);
35135
+ } else {
35136
+ process.stdout.write(`
35137
+ ${engine.renderRunReport(result)}
35138
+ `);
35139
+ }
35140
+ if (preview) {
35141
+ if (opts.keepSeconds !== null) {
35142
+ await new Promise((r) => setTimeout(r, opts.keepSeconds * 1e3));
35143
+ preview.teardown();
35144
+ } else if (!opts.watch) {
35145
+ process.stderr.write(
35146
+ `
35147
+ Preview is live at ${preview.url} \u2014 press Ctrl-C to tear it down.
35148
+ Expiry and revocation are not built yet (TERM-350 phase 5); Ctrl-C is the only stop.
35149
+ `
35150
+ );
35151
+ await new Promise((resolve_) => {
35152
+ process.on("SIGINT", () => {
35153
+ preview.teardown();
35154
+ resolve_();
35155
+ });
35156
+ });
35157
+ } else {
35158
+ preview.teardown();
35159
+ }
35160
+ }
35161
+ if (!opts.json) {
35162
+ process.stderr.write(` total ${String(Date.now() - started)}ms
35163
+ `);
35164
+ }
35165
+ if (result.status === "refused") return 2;
35166
+ return result.outcome === "completed" ? 0 : 1;
35167
+ }
35168
+ async function run10() {
35169
+ const argv = process.argv.slice(2);
35170
+ const parsed = parseArgs2(argv);
35171
+ if (parsed.bools.has("help") || argv.length === 0) {
35172
+ process.stdout.write(`${USAGE}
35173
+ `);
35174
+ return 0;
35175
+ }
35176
+ const localDir = resolve5(parsed.flags["local"] ?? process.cwd());
35177
+ const config2 = readConfig2(localDir);
35178
+ const pick2 = (name) => parsed.flags[name] ?? config2[name];
35179
+ const sliceRaw = pick2("slice");
35180
+ const slice = Array.isArray(sliceRaw) ? sliceRaw : typeof sliceRaw === "string" ? sliceRaw.split(",").map((s) => s.trim()).filter((s) => s.length > 0) : [];
35181
+ if (slice.length === 0) {
35182
+ throw new Error(
35183
+ 'terminalhire: run needs --slice (or a "slice" array in .th-run.json). An empty slice means nothing may be touched, so every diff would be refused \u2014 that is almost never what you meant, so it is an error rather than a silent refusal.'
35184
+ );
35185
+ }
35186
+ const opts = {
35187
+ claimId: requireField(pick2("claim"), "--claim", "It is the id the result is filed under."),
35188
+ target: requireField(pick2("target"), "--target", "e.g. https://github.com/koajs/koa.git"),
35189
+ sha: requireField(pick2("sha"), "--sha", "The full 40-character commit your diff applies to."),
35190
+ slice,
35191
+ localDir,
35192
+ preview: !parsed.bools.has("no-preview"),
35193
+ watch: parsed.bools.has("watch"),
35194
+ json: parsed.bools.has("json"),
35195
+ testCommand: pick2("test-command") ?? null,
35196
+ keepSeconds: pick2("keep") === void 0 ? null : Number(pick2("keep")),
35197
+ scratch: runScratchRoot()
35198
+ };
35199
+ if (!/^[0-9a-f]{40}$/.test(opts.sha)) {
35200
+ throw new Error(
35201
+ `terminalhire: --sha must be a full 40-character commit, got ${JSON.stringify(opts.sha)}. An abbreviated sha cannot be checked against what was actually fetched.`
35202
+ );
35203
+ }
35204
+ const engine = await loadEngine();
35205
+ if (!opts.watch) return once(engine, opts);
35206
+ const { watch } = await import("fs");
35207
+ let last = await once(engine, opts);
35208
+ let timer = null;
35209
+ let running = false;
35210
+ process.stderr.write("\nwatching for changes \u2014 Ctrl-C to stop\n");
35211
+ watch(opts.localDir, { recursive: true }, (_event, filename) => {
35212
+ if (typeof filename === "string" && filename.includes(".git/")) return;
35213
+ if (timer) clearTimeout(timer);
35214
+ timer = setTimeout(() => {
35215
+ if (running) return;
35216
+ running = true;
35217
+ once(engine, opts).then((code) => {
35218
+ last = code;
35219
+ }).catch((err) => {
35220
+ process.stderr.write(`${err && err.message ? err.message : String(err)}
35221
+ `);
35222
+ }).finally(() => {
35223
+ running = false;
35224
+ });
35225
+ }, 500);
35226
+ });
35227
+ await new Promise(() => {
35228
+ });
35229
+ return last;
35230
+ }
35231
+ var USAGE;
35232
+ var init_jpi_run = __esm({
35233
+ "bin/jpi-run.js"() {
35234
+ "use strict";
35235
+ USAGE = `terminalhire run \u2014 verify your working diff in a fresh container
35236
+
35237
+ Usage:
35238
+ th run [options]
35239
+
35240
+ Options:
35241
+ --claim <id> The claim this work belongs to.
35242
+ --target <git-url> Repository the work is verified against.
35243
+ --sha <40-hex> The commit your diff applies on top of.
35244
+ --slice <a,b,c> Comma-separated files this claim shares. A diff touching
35245
+ anything else is refused locally, before any container.
35246
+ --local <dir> Checkout to read the working diff from (default: cwd).
35247
+ --watch Re-run when a file in the checkout changes.
35248
+ --json Print the run result as JSON instead of a report.
35249
+ --no-preview Skip the preview URL.
35250
+ --keep <seconds> Hold the preview open this long (default: until Ctrl-C).
35251
+ --test-command <cmd> Disclosed override of the derived test command.
35252
+ --help
35253
+
35254
+ Defaults are read from .th-run.json in the local checkout when present, so a
35255
+ claim you run repeatedly needs no flags. Every flag overrides the file.
35256
+
35257
+ Needs Docker running. Needs network for the first clone of the target.`;
35258
+ if (process.argv[1] && process.argv[1].endsWith("jpi-run.js")) {
35259
+ run10().then((code) => process.exit(code ?? 0)).catch((err) => {
35260
+ process.stderr.write(`${err && err.message ? err.message : String(err)}
35261
+ `);
35262
+ process.exit(1);
35263
+ });
35264
+ }
35265
+ }
35266
+ });
35267
+
35039
35268
  // bin/jpi-update.js
35040
35269
  var jpi_update_exports = {};
35041
35270
  __export(jpi_update_exports, {
35042
35271
  decideUpdate: () => decideUpdate,
35043
35272
  pathIsInsidePluginRoot: () => pathIsInsidePluginRoot,
35044
- run: () => run10
35273
+ run: () => run11
35045
35274
  });
35046
35275
  import { spawnSync as spawnSync3 } from "child_process";
35047
35276
  import { fileURLToPath as fileURLToPath6 } from "url";
@@ -35118,7 +35347,7 @@ function runNpmInstall() {
35118
35347
  console.log("\u2713 update complete \u2014 the new version is active on your next terminalhire run.");
35119
35348
  return 0;
35120
35349
  }
35121
- async function run10(argv) {
35350
+ async function run11(argv) {
35122
35351
  try {
35123
35352
  const args5 = argv ?? [];
35124
35353
  const check = args5.includes("--check");
@@ -35320,7 +35549,7 @@ function finalize(build) {
35320
35549
  };
35321
35550
  }
35322
35551
  function reconstruct(files, opts = {}) {
35323
- const join47 = opts.joinSidechains !== false;
35552
+ const join48 = opts.joinSidechains !== false;
35324
35553
  const mains = [];
35325
35554
  const sidechains = [];
35326
35555
  for (const file of files) {
@@ -35345,7 +35574,7 @@ function reconstruct(files, opts = {}) {
35345
35574
  }
35346
35575
  const orphanedSidechainPaths = [];
35347
35576
  const joinedPaths = /* @__PURE__ */ new Set();
35348
- if (join47) {
35577
+ if (join48) {
35349
35578
  const sidechainsBySession = /* @__PURE__ */ new Map();
35350
35579
  for (const sc of sidechains) {
35351
35580
  const acc = sidechainsBySession.get(sc.sessionId) ?? [];
@@ -35615,12 +35844,12 @@ function deriveRecoveryDepth(episodes, nodesByUuid) {
35615
35844
  continue;
35616
35845
  }
35617
35846
  spansConsidered++;
35618
- let run31 = 0;
35847
+ let run32 = 0;
35619
35848
  const closeChain = () => {
35620
- if (run31 > 0) {
35849
+ if (run32 > 0) {
35621
35850
  recoveryChains++;
35622
- totalDepth += run31;
35623
- run31 = 0;
35851
+ totalDepth += run32;
35852
+ run32 = 0;
35624
35853
  }
35625
35854
  };
35626
35855
  for (const uuid2 of episode.mainNodeUuids) {
@@ -35629,9 +35858,9 @@ function deriveRecoveryDepth(episodes, nodesByUuid) {
35629
35858
  continue;
35630
35859
  }
35631
35860
  if (node.kind === "tool_result" /* ToolResult */ && node.isError) {
35632
- run31++;
35633
- if (run31 > maxConsecutiveErrors) {
35634
- maxConsecutiveErrors = run31;
35861
+ run32++;
35862
+ if (run32 > maxConsecutiveErrors) {
35863
+ maxConsecutiveErrors = run32;
35635
35864
  }
35636
35865
  } else if (node.kind === "tool_result" /* ToolResult */ && !node.isError) {
35637
35866
  closeChain();
@@ -35681,9 +35910,9 @@ __export(trajectory_exports, {
35681
35910
  runTrajectory: () => runTrajectory,
35682
35911
  runTrajectoryPush: () => runTrajectoryPush
35683
35912
  });
35684
- import { existsSync as existsSync17, readFileSync as readFileSync26, readdirSync as readdirSync3, writeFileSync as writeFileSync20 } from "fs";
35913
+ import { existsSync as existsSync18, readFileSync as readFileSync27, readdirSync as readdirSync3, writeFileSync as writeFileSync20 } from "fs";
35685
35914
  import { homedir as homedir24 } from "os";
35686
- import { join as join33 } from "path";
35915
+ import { join as join34 } from "path";
35687
35916
  function isRecord4(value) {
35688
35917
  return typeof value === "object" && value !== null && !Array.isArray(value);
35689
35918
  }
@@ -35715,7 +35944,7 @@ function findJsonlFiles(dir) {
35715
35944
  return out;
35716
35945
  }
35717
35946
  for (const entry of entries) {
35718
- const full = join33(dir, entry.name);
35947
+ const full = join34(dir, entry.name);
35719
35948
  if (entry.isDirectory()) {
35720
35949
  out.push(...findJsonlFiles(full));
35721
35950
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -35729,7 +35958,7 @@ function loadCorpus(paths) {
35729
35958
  for (const path6 of paths) {
35730
35959
  let text;
35731
35960
  try {
35732
- text = readFileSync26(path6, "utf8");
35961
+ text = readFileSync27(path6, "utf8");
35733
35962
  } catch {
35734
35963
  continue;
35735
35964
  }
@@ -35836,10 +36065,10 @@ function renderMarkdown(view) {
35836
36065
  return lines.join("\n");
35837
36066
  }
35838
36067
  function writeExportArtifacts(score, markdown) {
35839
- const dir = process.env.TERMINALHIRE_DIR || join33(homedir24(), ".terminalhire");
36068
+ const dir = process.env.TERMINALHIRE_DIR || join34(homedir24(), ".terminalhire");
35840
36069
  ensureStateDir(dir);
35841
- const jsonPath = join33(dir, "trajectory-export.json");
35842
- const mdPath = join33(dir, "trajectory-export.md");
36070
+ const jsonPath = join34(dir, "trajectory-export.json");
36071
+ const mdPath = join34(dir, "trajectory-export.md");
35843
36072
  writeFileSync20(jsonPath, JSON.stringify(score, null, 2) + "\n", "utf8");
35844
36073
  writeFileSync20(mdPath, markdown, "utf8");
35845
36074
  return { jsonPath, mdPath };
@@ -35860,8 +36089,8 @@ function renderInward(allNodes, view, files) {
35860
36089
  console.log("");
35861
36090
  }
35862
36091
  function buildTrajectory() {
35863
- const projectsDir = join33(homedir24(), ".claude", "projects");
35864
- if (!existsSync17(projectsDir)) return null;
36092
+ const projectsDir = join34(homedir24(), ".claude", "projects");
36093
+ if (!existsSync18(projectsDir)) return null;
35865
36094
  const paths = findJsonlFiles(projectsDir);
35866
36095
  if (paths.length === 0) return null;
35867
36096
  const files = loadCorpus(paths);
@@ -36136,9 +36365,9 @@ var init_trajectory = __esm({
36136
36365
  // bin/jpi-trajectory.js
36137
36366
  var jpi_trajectory_exports = {};
36138
36367
  __export(jpi_trajectory_exports, {
36139
- run: () => run11
36368
+ run: () => run12
36140
36369
  });
36141
- async function run11() {
36370
+ async function run12() {
36142
36371
  try {
36143
36372
  const args5 = process.argv.slice(2);
36144
36373
  if (args5.includes("--push")) {
@@ -36573,7 +36802,7 @@ var init_intro2 = __esm({
36573
36802
  // bin/jpi-intro.js
36574
36803
  var jpi_intro_exports = {};
36575
36804
  __export(jpi_intro_exports, {
36576
- run: () => run12
36805
+ run: () => run13
36577
36806
  });
36578
36807
  function readOption(args5, name) {
36579
36808
  const i = args5.indexOf(name);
@@ -36581,7 +36810,7 @@ function readOption(args5, name) {
36581
36810
  const v = args5[i + 1];
36582
36811
  return typeof v === "string" && !v.startsWith("--") ? v : void 0;
36583
36812
  }
36584
- async function run12() {
36813
+ async function run13() {
36585
36814
  try {
36586
36815
  const args5 = process.argv.slice(2);
36587
36816
  if (args5.includes("--list")) {
@@ -36621,13 +36850,13 @@ var init_jpi_intro = __esm({
36621
36850
  });
36622
36851
 
36623
36852
  // src/chat-keystore.ts
36624
- import { existsSync as existsSync18, linkSync as linkSync2, readFileSync as readFileSync27, rmSync as rmSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync21 } from "fs";
36853
+ import { existsSync as existsSync19, linkSync as linkSync2, readFileSync as readFileSync28, rmSync as rmSync10, unlinkSync as unlinkSync4, writeFileSync as writeFileSync21 } from "fs";
36625
36854
  import { randomBytes as randomBytes8 } from "crypto";
36626
36855
  import { homedir as homedir25 } from "os";
36627
- import { join as join34 } from "path";
36856
+ import { join as join35 } from "path";
36628
36857
  async function loadOrCreateIdentity() {
36629
36858
  const key = await loadKey();
36630
- if (existsSync18(IDENTITY_FILE)) {
36859
+ if (existsSync19(IDENTITY_FILE)) {
36631
36860
  return readIdentityFileOrThrow(key);
36632
36861
  }
36633
36862
  waitForTestRaceBarrier("identity");
@@ -36646,7 +36875,7 @@ function isValidChatKeypairShape(value) {
36646
36875
  }
36647
36876
  function readIdentityFileOrThrow(key) {
36648
36877
  try {
36649
- const raw = readFileSync27(IDENTITY_FILE, "utf8");
36878
+ const raw = readFileSync28(IDENTITY_FILE, "utf8");
36650
36879
  const blob = JSON.parse(raw);
36651
36880
  const decrypted = decrypt(blob, key);
36652
36881
  const parsed = JSON.parse(decrypted);
@@ -36697,20 +36926,20 @@ var init_chat_keystore = __esm({
36697
36926
  init_src();
36698
36927
  init_github_auth();
36699
36928
  init_state_dir();
36700
- TERMINALHIRE_DIR18 = process.env.TERMINALHIRE_DIR || join34(homedir25(), ".terminalhire");
36701
- IDENTITY_FILE = join34(TERMINALHIRE_DIR18, "chat-identity.enc");
36929
+ TERMINALHIRE_DIR18 = process.env.TERMINALHIRE_DIR || join35(homedir25(), ".terminalhire");
36930
+ IDENTITY_FILE = join35(TERMINALHIRE_DIR18, "chat-identity.enc");
36702
36931
  HEX64_RE = /^[0-9a-f]{64}$/;
36703
36932
  }
36704
36933
  });
36705
36934
 
36706
36935
  // src/chat-client.ts
36707
- import { existsSync as existsSync19, readFileSync as readFileSync28, writeFileSync as writeFileSync22 } from "fs";
36936
+ import { existsSync as existsSync20, readFileSync as readFileSync29, writeFileSync as writeFileSync22 } from "fs";
36708
36937
  import { homedir as homedir26 } from "os";
36709
- import { join as join35 } from "path";
36938
+ import { join as join36 } from "path";
36710
36939
  function defaultReadPeerPins() {
36711
36940
  try {
36712
- if (!existsSync19(PEERS_FILE)) return {};
36713
- const parsed = JSON.parse(readFileSync28(PEERS_FILE, "utf8"));
36941
+ if (!existsSync20(PEERS_FILE)) return {};
36942
+ const parsed = JSON.parse(readFileSync29(PEERS_FILE, "utf8"));
36714
36943
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
36715
36944
  const out = {};
36716
36945
  for (const [login, key] of Object.entries(parsed)) {
@@ -36910,8 +37139,8 @@ var init_chat_client = __esm({
36910
37139
  init_state_dir();
36911
37140
  CHAT_BASE = process.env["TERMINALHIRE_API_URL"] || "https://terminalhire.com";
36912
37141
  GH_SESSION_COOKIE5 = "__jpi_gh_session";
36913
- TERMINALHIRE_DIR19 = process.env.TERMINALHIRE_DIR || join35(homedir26(), ".terminalhire");
36914
- PEERS_FILE = join35(TERMINALHIRE_DIR19, "chat-peers.json");
37142
+ TERMINALHIRE_DIR19 = process.env.TERMINALHIRE_DIR || join36(homedir26(), ".terminalhire");
37143
+ PEERS_FILE = join36(TERMINALHIRE_DIR19, "chat-peers.json");
36915
37144
  REQUEST_TIMEOUT_MS2 = 1e4;
36916
37145
  ChatNotLinkedError = class extends Error {
36917
37146
  constructor() {
@@ -37074,27 +37303,27 @@ function diff(prev, next, cols) {
37074
37303
  if (!Number.isInteger(cols) || cols <= 0) return [];
37075
37304
  const ops = [];
37076
37305
  const len = next.length;
37077
- let run31 = null;
37306
+ let run32 = null;
37078
37307
  for (let i = 0; i < len; i++) {
37079
37308
  const col = i % cols;
37080
37309
  const row = (i - col) / cols;
37081
- if (col === 0 && run31) {
37082
- ops.push(run31);
37083
- run31 = null;
37310
+ if (col === 0 && run32) {
37311
+ ops.push(run32);
37312
+ run32 = null;
37084
37313
  }
37085
37314
  if (cellNe(prev[i], next[i])) {
37086
- if (run31 && run31.row === row && run31.col + run31.run.length === col) {
37087
- run31.run.push(next[i]);
37315
+ if (run32 && run32.row === row && run32.col + run32.run.length === col) {
37316
+ run32.run.push(next[i]);
37088
37317
  } else {
37089
- if (run31) ops.push(run31);
37090
- run31 = { row, col, run: [next[i]] };
37318
+ if (run32) ops.push(run32);
37319
+ run32 = { row, col, run: [next[i]] };
37091
37320
  }
37092
- } else if (run31) {
37093
- ops.push(run31);
37094
- run31 = null;
37321
+ } else if (run32) {
37322
+ ops.push(run32);
37323
+ run32 = null;
37095
37324
  }
37096
37325
  }
37097
- if (run31) ops.push(run31);
37326
+ if (run32) ops.push(run32);
37098
37327
  return ops;
37099
37328
  }
37100
37329
  function styleOf(cell) {
@@ -37341,16 +37570,16 @@ __export(jpi_chat_read_exports, {
37341
37570
  syncUnreadBadge: () => syncUnreadBadge,
37342
37571
  writeReadCursor: () => writeReadCursor
37343
37572
  });
37344
- import { existsSync as existsSync20, readFileSync as readFileSync29, writeFileSync as writeFileSync23 } from "fs";
37573
+ import { existsSync as existsSync21, readFileSync as readFileSync30, writeFileSync as writeFileSync23 } from "fs";
37345
37574
  import { homedir as homedir27 } from "os";
37346
- import { join as join36 } from "path";
37575
+ import { join as join37 } from "path";
37347
37576
  async function syncUnreadBadge(deps = {}) {
37348
37577
  const readCookie = deps.readCookie ?? readWebSessionCookie;
37349
37578
  const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
37350
37579
  const cacheFile = deps.cacheFile ?? INDEX_CACHE_FILE6;
37351
37580
  try {
37352
37581
  const cookie = readCookie();
37353
- if (!cookie || !existsSync20(cacheFile)) return;
37582
+ if (!cookie || !existsSync21(cacheFile)) return;
37354
37583
  const res = await fetchImpl(`${CHAT_BASE2}/api/chat/inbox`, {
37355
37584
  method: "GET",
37356
37585
  headers: { Cookie: `${GH_SESSION_COOKIE6}=${cookie}` },
@@ -37363,7 +37592,7 @@ async function syncUnreadBadge(deps = {}) {
37363
37592
  (sum, it) => sum + (it && typeof it.unreadCount === "number" && it.unreadCount > 0 ? it.unreadCount : 0),
37364
37593
  0
37365
37594
  );
37366
- const entry = JSON.parse(readFileSync29(cacheFile, "utf8"));
37595
+ const entry = JSON.parse(readFileSync30(cacheFile, "utf8"));
37367
37596
  entry.unreadChat = { count: total };
37368
37597
  writeFileSync23(cacheFile, JSON.stringify(entry), "utf8");
37369
37598
  } catch {
@@ -37371,8 +37600,8 @@ async function syncUnreadBadge(deps = {}) {
37371
37600
  }
37372
37601
  function readReadCursors() {
37373
37602
  try {
37374
- if (!existsSync20(READS_FILE)) return {};
37375
- const parsed = JSON.parse(readFileSync29(READS_FILE, "utf8"));
37603
+ if (!existsSync21(READS_FILE)) return {};
37604
+ const parsed = JSON.parse(readFileSync30(READS_FILE, "utf8"));
37376
37605
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
37377
37606
  const out = {};
37378
37607
  for (const [login, iso] of Object.entries(parsed)) {
@@ -37749,9 +37978,9 @@ var init_jpi_chat_read = __esm({
37749
37978
  init_jpi_chat();
37750
37979
  CHAT_BASE2 = process.env["TERMINALHIRE_API_URL"] || "https://terminalhire.com";
37751
37980
  GH_SESSION_COOKIE6 = "__jpi_gh_session";
37752
- TERMINALHIRE_DIR20 = process.env.TERMINALHIRE_DIR || join36(homedir27(), ".terminalhire");
37753
- READS_FILE = join36(TERMINALHIRE_DIR20, "chat-reads.json");
37754
- INDEX_CACHE_FILE6 = join36(TERMINALHIRE_DIR20, "index-cache.json");
37981
+ TERMINALHIRE_DIR20 = process.env.TERMINALHIRE_DIR || join37(homedir27(), ".terminalhire");
37982
+ READS_FILE = join37(TERMINALHIRE_DIR20, "chat-reads.json");
37983
+ INDEX_CACHE_FILE6 = join37(TERMINALHIRE_DIR20, "index-cache.json");
37755
37984
  REACHABLE_DISPLAY = { shareActivity: false, optin: false, lastSeen: null };
37756
37985
  }
37757
37986
  });
@@ -37761,7 +37990,7 @@ var jpi_inbox_exports = {};
37761
37990
  __export(jpi_inbox_exports, {
37762
37991
  defaultDecideIntro: () => defaultDecideIntro,
37763
37992
  formatInbox: () => formatInbox,
37764
- run: () => run13,
37993
+ run: () => run14,
37765
37994
  runInboxPane: () => runInboxPane,
37766
37995
  runInboxTui: () => runInboxTui,
37767
37996
  sortConversations: () => sortConversations
@@ -37886,7 +38115,7 @@ async function runInboxPane(opts = {}) {
37886
38115
  clearTimer = (t) => clearInterval(t),
37887
38116
  refreshMs = DEFAULT_REFRESH_MS
37888
38117
  } = opts;
37889
- return await new Promise((resolve6) => {
38118
+ return await new Promise((resolve7) => {
37890
38119
  let rows = [];
37891
38120
  let inviteCount = 0;
37892
38121
  let selected = 0;
@@ -38154,7 +38383,7 @@ async function runInboxPane(opts = {}) {
38154
38383
  function finish(result) {
38155
38384
  if (cleaned) return;
38156
38385
  cleanup();
38157
- resolve6(result);
38386
+ resolve7(result);
38158
38387
  }
38159
38388
  function onSignal() {
38160
38389
  finish({ action: "quit" });
@@ -38192,7 +38421,7 @@ async function runInboxPane(opts = {}) {
38192
38421
  Inbox error: ${err instanceof Error ? err.message : String(err)}
38193
38422
 
38194
38423
  `);
38195
- resolve6({ action: "quit" });
38424
+ resolve7({ action: "quit" });
38196
38425
  }
38197
38426
  });
38198
38427
  }
@@ -38220,7 +38449,7 @@ async function runInboxTui(deps = {}) {
38220
38449
  }
38221
38450
  return { ok: true };
38222
38451
  }
38223
- async function run13(opts = {}) {
38452
+ async function run14(opts = {}) {
38224
38453
  const {
38225
38454
  isTTY = process.stdout.isTTY,
38226
38455
  input = process.stdin,
@@ -38282,7 +38511,7 @@ __export(jpi_chat_exports, {
38282
38511
  formatThread: () => formatThread,
38283
38512
  readCachedSessionStale: () => readCachedSessionStale,
38284
38513
  relativeTime: () => relativeTime2,
38285
- run: () => run14,
38514
+ run: () => run15,
38286
38515
  runBlockCommand: () => runBlockCommand,
38287
38516
  runChatPane: () => runChatPane,
38288
38517
  runNoticePane: () => runNoticePane,
@@ -38290,16 +38519,16 @@ __export(jpi_chat_exports, {
38290
38519
  sanitizeLine: () => sanitizeLine
38291
38520
  });
38292
38521
  import { createInterface as createInterface10 } from "readline";
38293
- import { existsSync as existsSync21, readFileSync as readFileSync30 } from "fs";
38522
+ import { existsSync as existsSync22, readFileSync as readFileSync31 } from "fs";
38294
38523
  import { homedir as homedir28 } from "os";
38295
- import { join as join37 } from "path";
38524
+ import { join as join38 } from "path";
38296
38525
  function defaultPromptAck({ input = process.stdin, output = process.stdout } = {}) {
38297
38526
  if (!input || input.isTTY !== true) return Promise.resolve(false);
38298
38527
  const rl = createInterface10({ input, output });
38299
- return new Promise((resolve6) => {
38528
+ return new Promise((resolve7) => {
38300
38529
  rl.question(" Press Enter to acknowledge and continue (Ctrl-C to cancel): ", () => {
38301
38530
  rl.close();
38302
- resolve6(true);
38531
+ resolve7(true);
38303
38532
  });
38304
38533
  });
38305
38534
  }
@@ -38458,9 +38687,9 @@ function mergeMessages(existing, incoming) {
38458
38687
  }
38459
38688
  function readCachedSessionStale() {
38460
38689
  try {
38461
- const p = join37(process.env.TERMINALHIRE_DIR || join37(homedir28(), ".terminalhire"), "index-cache.json");
38462
- if (!existsSync21(p)) return false;
38463
- const cache = JSON.parse(readFileSync30(p, "utf8"));
38690
+ const p = join38(process.env.TERMINALHIRE_DIR || join38(homedir28(), ".terminalhire"), "index-cache.json");
38691
+ if (!existsSync22(p)) return false;
38692
+ const cache = JSON.parse(readFileSync31(p, "utf8"));
38464
38693
  return cache?.sessionStale === true;
38465
38694
  } catch {
38466
38695
  return false;
@@ -38482,7 +38711,7 @@ function runNoticePane(opts = {}) {
38482
38711
  output = process.stdout,
38483
38712
  signals = process
38484
38713
  } = opts;
38485
- return new Promise((resolve6) => {
38714
+ return new Promise((resolve7) => {
38486
38715
  let cleaned = false;
38487
38716
  const body = String(message ?? "").replace(/^\n+/, "").replace(/\n+$/, "");
38488
38717
  function render() {
@@ -38521,7 +38750,7 @@ function runNoticePane(opts = {}) {
38521
38750
  function onDismiss() {
38522
38751
  if (cleaned) return;
38523
38752
  cleanup();
38524
- resolve6();
38753
+ resolve7();
38525
38754
  }
38526
38755
  function onUncaught(err) {
38527
38756
  cleanup();
@@ -38560,7 +38789,7 @@ function runNoticePane(opts = {}) {
38560
38789
  ${err instanceof Error ? err.message : String(err)}
38561
38790
 
38562
38791
  `);
38563
- resolve6();
38792
+ resolve7();
38564
38793
  }
38565
38794
  });
38566
38795
  }
@@ -38698,7 +38927,7 @@ async function runChatPane(opts = {}) {
38698
38927
  selfShareActivity = readConfig().chatShareActivity === true;
38699
38928
  } catch {
38700
38929
  }
38701
- return await new Promise((resolve6) => {
38930
+ return await new Promise((resolve7) => {
38702
38931
  let messages = [];
38703
38932
  let inputBuffer = "";
38704
38933
  let presence = null;
@@ -38767,7 +38996,7 @@ async function runChatPane(opts = {}) {
38767
38996
  exitReason = reason;
38768
38997
  cleanup();
38769
38998
  output.write(DEPOSIT_CTA);
38770
- resolve6({ entered: true, reason });
38999
+ resolve7({ entered: true, reason });
38771
39000
  }
38772
39001
  async function doPoll() {
38773
39002
  if (polling || cleaned) return;
@@ -38808,7 +39037,7 @@ async function runChatPane(opts = {}) {
38808
39037
  ${err.message}
38809
39038
 
38810
39039
  `);
38811
- resolve6({ entered: true, reason: "session-expired" });
39040
+ resolve7({ entered: true, reason: "session-expired" });
38812
39041
  }
38813
39042
  return;
38814
39043
  }
@@ -38862,7 +39091,7 @@ async function runChatPane(opts = {}) {
38862
39091
  ${err.message}
38863
39092
 
38864
39093
  `);
38865
- resolve6({ entered: true, reason: "session-expired" });
39094
+ resolve7({ entered: true, reason: "session-expired" });
38866
39095
  }
38867
39096
  return;
38868
39097
  }
@@ -38880,7 +39109,7 @@ async function runChatPane(opts = {}) {
38880
39109
 
38881
39110
  `
38882
39111
  );
38883
- resolve6({ entered: true, reason: "blocked" });
39112
+ resolve7({ entered: true, reason: "blocked" });
38884
39113
  }
38885
39114
  return;
38886
39115
  }
@@ -38896,7 +39125,7 @@ async function runChatPane(opts = {}) {
38896
39125
  ${err.message}
38897
39126
 
38898
39127
  `);
38899
- resolve6({ entered: true, reason: "session-expired" });
39128
+ resolve7({ entered: true, reason: "session-expired" });
38900
39129
  }
38901
39130
  return;
38902
39131
  }
@@ -38983,7 +39212,7 @@ async function runChatPane(opts = {}) {
38983
39212
  Chat pane error: ${err instanceof Error ? err.message : String(err)}
38984
39213
 
38985
39214
  `);
38986
- resolve6({ entered: true, reason: "error" });
39215
+ resolve7({ entered: true, reason: "error" });
38987
39216
  }
38988
39217
  });
38989
39218
  }
@@ -39076,7 +39305,7 @@ async function runShareActivityCommand(opts = {}) {
39076
39305
  }
39077
39306
  return { ok: true, share };
39078
39307
  }
39079
- async function run14() {
39308
+ async function run15() {
39080
39309
  const args5 = process.argv.slice(2);
39081
39310
  let login;
39082
39311
  let limit2 = 8;
@@ -39192,7 +39421,7 @@ var init_jpi_chat = __esm({
39192
39421
  // bin/jpi-hub.js
39193
39422
  var jpi_hub_exports = {};
39194
39423
  __export(jpi_hub_exports, {
39195
- run: () => run15,
39424
+ run: () => run16,
39196
39425
  runHubTui: () => runHubTui
39197
39426
  });
39198
39427
  function stubRows(paneName) {
@@ -39241,7 +39470,7 @@ function runHubTui({ input = process.stdin, output = process.stdout, signals, de
39241
39470
  // tests override with a tiny value to exercise auto-dismiss without a real wait.
39242
39471
  splashMs: _splashMs = DEFAULT_SPLASH_MS
39243
39472
  } = deps;
39244
- return new Promise((resolve6) => {
39473
+ return new Promise((resolve7) => {
39245
39474
  const level = detectColorLevel(
39246
39475
  typeof process !== "undefined" ? process.env : {},
39247
39476
  output && output.isTTY
@@ -40088,7 +40317,7 @@ function runHubTui({ input = process.stdin, output = process.stdout, signals, de
40088
40317
  } catch {
40089
40318
  }
40090
40319
  runtime.cleanup();
40091
- resolve6({ ok: true, lastVerb });
40320
+ resolve7({ ok: true, lastVerb });
40092
40321
  }
40093
40322
  runtime.enter();
40094
40323
  splashTimer = setTimeout(() => {
@@ -40117,7 +40346,7 @@ function printStatic(output = process.stdout) {
40117
40346
  out(" Panes: " + PANES.map((p) => sanitizeLine(p)).join(" \xB7 ") + "\n\n");
40118
40347
  out(" Run `terminalhire hub` in an interactive terminal to launch the full-screen hub.\n\n");
40119
40348
  }
40120
- async function run15(opts = {}) {
40349
+ async function run16(opts = {}) {
40121
40350
  const {
40122
40351
  isTTY = process.stdout.isTTY,
40123
40352
  input = process.stdin,
@@ -40198,15 +40427,15 @@ __export(mcp_config_exports, {
40198
40427
  writeServerToFile: () => writeServerToFile
40199
40428
  });
40200
40429
  import { homedir as homedir29 } from "os";
40201
- import { join as join38 } from "path";
40202
- import { existsSync as existsSync22, readFileSync as readFileSync31, copyFileSync as copyFileSync2, writeFileSync as writeFileSync24, mkdirSync as mkdirSync6 } from "fs";
40430
+ import { join as join39 } from "path";
40431
+ import { existsSync as existsSync23, readFileSync as readFileSync32, copyFileSync as copyFileSync2, writeFileSync as writeFileSync24, mkdirSync as mkdirSync6 } from "fs";
40203
40432
  import { dirname as dirname9 } from "path";
40204
40433
  function serverEntry() {
40205
40434
  return { command: SERVER_COMMAND, args: [...SERVER_ARGS] };
40206
40435
  }
40207
40436
  function hostConfigPath(host, home = homedir29()) {
40208
40437
  if (!host || !Array.isArray(host.relPath)) return null;
40209
- return join38(home, ...host.relPath);
40438
+ return join39(home, ...host.relPath);
40210
40439
  }
40211
40440
  function jsonSnippet(host) {
40212
40441
  const entry = serverEntry();
@@ -40290,8 +40519,8 @@ function mergeServerIntoJson(existingText, serversKey, entry = serverEntry()) {
40290
40519
  `, added: !already };
40291
40520
  }
40292
40521
  function writeServerToFile(configPath, serversKey, entry = serverEntry()) {
40293
- const fileExists = existsSync22(configPath);
40294
- const existingText = fileExists ? readFileSync31(configPath, "utf8") : "";
40522
+ const fileExists = existsSync23(configPath);
40523
+ const existingText = fileExists ? readFileSync32(configPath, "utf8") : "";
40295
40524
  const merged = mergeServerIntoJson(existingText, serversKey, entry);
40296
40525
  if (!merged.ok) {
40297
40526
  return { status: "skipped", reason: merged.reason };
@@ -40335,7 +40564,7 @@ async function initMcpStep({
40335
40564
  return;
40336
40565
  }
40337
40566
  const writableHosts = HOSTS.filter((h) => h.writable);
40338
- const detected = writableHosts.filter((h) => existsSync22(hostConfigPath(h, home)));
40567
+ const detected = writableHosts.filter((h) => existsSync23(hostConfigPath(h, home)));
40339
40568
  if (detected.length === 0) {
40340
40569
  out("");
40341
40570
  out(" No editor/CLI config detected (looked for ~/.cursor/mcp.json, ~/.gemini/settings.json).");
@@ -48665,7 +48894,7 @@ var init_protocol2 = __esm({
48665
48894
  return;
48666
48895
  }
48667
48896
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
48668
- await new Promise((resolve6) => setTimeout(resolve6, pollInterval));
48897
+ await new Promise((resolve7) => setTimeout(resolve7, pollInterval));
48669
48898
  options?.signal?.throwIfAborted();
48670
48899
  }
48671
48900
  } catch (error2) {
@@ -48682,7 +48911,7 @@ var init_protocol2 = __esm({
48682
48911
  */
48683
48912
  request(request, resultSchema, options) {
48684
48913
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
48685
- return new Promise((resolve6, reject) => {
48914
+ return new Promise((resolve7, reject) => {
48686
48915
  const earlyReject = (error2) => {
48687
48916
  reject(error2);
48688
48917
  };
@@ -48760,7 +48989,7 @@ var init_protocol2 = __esm({
48760
48989
  if (!parseResult.success) {
48761
48990
  reject(parseResult.error);
48762
48991
  } else {
48763
- resolve6(parseResult.data);
48992
+ resolve7(parseResult.data);
48764
48993
  }
48765
48994
  } catch (error2) {
48766
48995
  reject(error2);
@@ -49021,12 +49250,12 @@ var init_protocol2 = __esm({
49021
49250
  }
49022
49251
  } catch {
49023
49252
  }
49024
- return new Promise((resolve6, reject) => {
49253
+ return new Promise((resolve7, reject) => {
49025
49254
  if (signal.aborted) {
49026
49255
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
49027
49256
  return;
49028
49257
  }
49029
- const timeoutId = setTimeout(resolve6, interval);
49258
+ const timeoutId = setTimeout(resolve7, interval);
49030
49259
  signal.addEventListener("abort", () => {
49031
49260
  clearTimeout(timeoutId);
49032
49261
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -52053,7 +52282,7 @@ var require_compile = __commonJS({
52053
52282
  const schOrFunc = root.refs[ref];
52054
52283
  if (schOrFunc)
52055
52284
  return schOrFunc;
52056
- let _sch = resolve6.call(this, root, ref);
52285
+ let _sch = resolve7.call(this, root, ref);
52057
52286
  if (_sch === void 0) {
52058
52287
  const schema = (_a4 = root.localRefs) === null || _a4 === void 0 ? void 0 : _a4[ref];
52059
52288
  const { schemaId } = this.opts;
@@ -52080,7 +52309,7 @@ var require_compile = __commonJS({
52080
52309
  function sameSchemaEnv(s1, s2) {
52081
52310
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
52082
52311
  }
52083
- function resolve6(root, ref) {
52312
+ function resolve7(root, ref) {
52084
52313
  let sch;
52085
52314
  while (typeof (sch = this.refs[ref]) == "string")
52086
52315
  ref = sch;
@@ -52711,7 +52940,7 @@ var require_fast_uri = __commonJS({
52711
52940
  }
52712
52941
  return uri;
52713
52942
  }
52714
- function resolve6(baseURI, relativeURI, options) {
52943
+ function resolve7(baseURI, relativeURI, options) {
52715
52944
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
52716
52945
  const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
52717
52946
  schemelessOptions.skipEscape = true;
@@ -52969,7 +53198,7 @@ var require_fast_uri = __commonJS({
52969
53198
  var fastUri = {
52970
53199
  SCHEMES,
52971
53200
  normalize: normalize3,
52972
- resolve: resolve6,
53201
+ resolve: resolve7,
52973
53202
  resolveComponent,
52974
53203
  equal,
52975
53204
  serialize,
@@ -58760,7 +58989,7 @@ var require_compile2 = __commonJS({
58760
58989
  const schOrFunc = root.refs[ref];
58761
58990
  if (schOrFunc)
58762
58991
  return schOrFunc;
58763
- let _sch = resolve6.call(this, root, ref);
58992
+ let _sch = resolve7.call(this, root, ref);
58764
58993
  if (_sch === void 0) {
58765
58994
  const schema = (_a4 = root.localRefs) === null || _a4 === void 0 ? void 0 : _a4[ref];
58766
58995
  const { schemaId } = this.opts;
@@ -58787,7 +59016,7 @@ var require_compile2 = __commonJS({
58787
59016
  function sameSchemaEnv(s1, s2) {
58788
59017
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
58789
59018
  }
58790
- function resolve6(root, ref) {
59019
+ function resolve7(root, ref) {
58791
59020
  let sch;
58792
59021
  while (typeof (sch = this.refs[ref]) == "string")
58793
59022
  ref = sch;
@@ -62478,12 +62707,12 @@ var init_stdio2 = __esm({
62478
62707
  this.onclose?.();
62479
62708
  }
62480
62709
  send(message) {
62481
- return new Promise((resolve6) => {
62710
+ return new Promise((resolve7) => {
62482
62711
  const json = serializeMessage(message);
62483
62712
  if (this._stdout.write(json)) {
62484
- resolve6();
62713
+ resolve7();
62485
62714
  } else {
62486
- this._stdout.once("drain", resolve6);
62715
+ this._stdout.once("drain", resolve7);
62487
62716
  }
62488
62717
  });
62489
62718
  }
@@ -62502,7 +62731,7 @@ __export(jpi_mcp_exports, {
62502
62731
  contributeResult: () => contributeResult,
62503
62732
  inboxResult: () => inboxResult,
62504
62733
  jobsResult: () => jobsResult,
62505
- run: () => run16
62734
+ run: () => run17
62506
62735
  });
62507
62736
  function clampLimit(limit2) {
62508
62737
  const n = Number(limit2);
@@ -62812,19 +63041,19 @@ function buildToolResult(name, args5, entry, contributeEnabled, order = {}) {
62812
63041
  return { status: "error", hint: `Unknown tool: ${name}` };
62813
63042
  }
62814
63043
  }
62815
- async function run16() {
63044
+ async function run17() {
62816
63045
  const { Server: Server2 } = await Promise.resolve().then(() => (init_server2(), server_exports));
62817
63046
  const { StdioServerTransport: StdioServerTransport2 } = await Promise.resolve().then(() => (init_stdio2(), stdio_exports));
62818
63047
  const { ListToolsRequestSchema: ListToolsRequestSchema2, CallToolRequestSchema: CallToolRequestSchema2 } = await Promise.resolve().then(() => (init_types4(), types_exports));
62819
63048
  let version2 = "0.0.0";
62820
63049
  try {
62821
- const { readFileSync: readFileSync38, existsSync: existsSync29 } = await import("fs");
62822
- const { join: join47 } = await import("path");
63050
+ const { readFileSync: readFileSync39, existsSync: existsSync30 } = await import("fs");
63051
+ const { join: join48 } = await import("path");
62823
63052
  const { fileURLToPath: fileURLToPath12 } = await import("url");
62824
63053
  const here = fileURLToPath12(new URL(".", import.meta.url));
62825
- for (const p of [join47(here, "..", "..", "package.json"), join47(here, "..", "package.json")]) {
62826
- if (existsSync29(p)) {
62827
- const pkg = JSON.parse(readFileSync38(p, "utf8"));
63054
+ for (const p of [join48(here, "..", "..", "package.json"), join48(here, "..", "package.json")]) {
63055
+ if (existsSync30(p)) {
63056
+ const pkg = JSON.parse(readFileSync39(p, "utf8"));
62828
63057
  if (pkg.version) {
62829
63058
  version2 = pkg.version;
62830
63059
  break;
@@ -62977,7 +63206,7 @@ __export(jpi_mcp_chat_exports, {
62977
63206
  buildReplyPrompt: () => buildReplyPrompt,
62978
63207
  chargeIfAllowed: () => chargeIfAllowed,
62979
63208
  createRateState: () => createRateState,
62980
- run: () => run17,
63209
+ run: () => run18,
62981
63210
  runReply: () => runReply
62982
63211
  });
62983
63212
  function createRateState() {
@@ -63089,19 +63318,19 @@ async function runReply(opts = {}) {
63089
63318
  if (sent && sent.ok) return { status: "sent", messagesShown: messages.length };
63090
63319
  return { status: "error", messagesShown: messages.length };
63091
63320
  }
63092
- async function run17() {
63321
+ async function run18() {
63093
63322
  const { Server: Server2 } = await Promise.resolve().then(() => (init_server2(), server_exports));
63094
63323
  const { StdioServerTransport: StdioServerTransport2 } = await Promise.resolve().then(() => (init_stdio2(), stdio_exports));
63095
63324
  const { ListToolsRequestSchema: ListToolsRequestSchema2, CallToolRequestSchema: CallToolRequestSchema2 } = await Promise.resolve().then(() => (init_types4(), types_exports));
63096
63325
  let version2 = "0.0.0";
63097
63326
  try {
63098
- const { readFileSync: readFileSync38, existsSync: existsSync29 } = await import("fs");
63099
- const { join: join47 } = await import("path");
63327
+ const { readFileSync: readFileSync39, existsSync: existsSync30 } = await import("fs");
63328
+ const { join: join48 } = await import("path");
63100
63329
  const { fileURLToPath: fileURLToPath12 } = await import("url");
63101
63330
  const here = fileURLToPath12(new URL(".", import.meta.url));
63102
- for (const p of [join47(here, "..", "..", "package.json"), join47(here, "..", "package.json")]) {
63103
- if (existsSync29(p)) {
63104
- const pkg = JSON.parse(readFileSync38(p, "utf8"));
63331
+ for (const p of [join48(here, "..", "..", "package.json"), join48(here, "..", "package.json")]) {
63332
+ if (existsSync30(p)) {
63333
+ const pkg = JSON.parse(readFileSync39(p, "utf8"));
63105
63334
  if (pkg.version) {
63106
63335
  version2 = pkg.version;
63107
63336
  break;
@@ -63171,9 +63400,9 @@ var init_jpi_mcp_chat = __esm({
63171
63400
  // bin/jpi-connect.js
63172
63401
  var jpi_connect_exports = {};
63173
63402
  __export(jpi_connect_exports, {
63174
- run: () => run18
63403
+ run: () => run19
63175
63404
  });
63176
- async function run18() {
63405
+ async function run19() {
63177
63406
  const args5 = process.argv.slice(2).filter((a) => a !== "connect");
63178
63407
  if (args5.includes("--mute")) {
63179
63408
  writeConfig({ inboundNudgeMuted: true });
@@ -63402,9 +63631,9 @@ var init_link = __esm({
63402
63631
  // bin/jpi-link.js
63403
63632
  var jpi_link_exports = {};
63404
63633
  __export(jpi_link_exports, {
63405
- run: () => run19
63634
+ run: () => run20
63406
63635
  });
63407
- async function run19() {
63636
+ async function run20() {
63408
63637
  try {
63409
63638
  const args5 = process.argv.slice(2);
63410
63639
  if (args5.includes("--logout")) {
@@ -63431,7 +63660,7 @@ var init_jpi_link = __esm({
63431
63660
  // bin/jpi-protocol.js
63432
63661
  var jpi_protocol_exports = {};
63433
63662
  __export(jpi_protocol_exports, {
63434
- run: () => run20
63663
+ run: () => run21
63435
63664
  });
63436
63665
  function printUsage() {
63437
63666
  console.log("");
@@ -63442,7 +63671,7 @@ function printUsage() {
63442
63671
  console.log(" status Show whether claim links are currently registered");
63443
63672
  console.log("");
63444
63673
  }
63445
- async function run20() {
63674
+ async function run21() {
63446
63675
  const args5 = process.argv.slice(2);
63447
63676
  const verb = args5[0];
63448
63677
  if (verb === "--help" || verb === "-h") {
@@ -63490,19 +63719,19 @@ var init_jpi_protocol = __esm({
63490
63719
  // bin/jpi-profile.js
63491
63720
  var jpi_profile_exports = {};
63492
63721
  __export(jpi_profile_exports, {
63493
- run: () => run21
63722
+ run: () => run22
63494
63723
  });
63495
63724
  import { createInterface as createInterface11 } from "readline";
63496
63725
  function prompt4(question) {
63497
63726
  const rl = createInterface11({ input: process.stdin, output: process.stdout });
63498
- return new Promise((resolve6) => {
63727
+ return new Promise((resolve7) => {
63499
63728
  rl.question(question, (answer) => {
63500
63729
  rl.close();
63501
- resolve6(answer.trim());
63730
+ resolve7(answer.trim());
63502
63731
  });
63503
63732
  });
63504
63733
  }
63505
- async function run21() {
63734
+ async function run22() {
63506
63735
  const { readProfile: readProfile2, writeProfile: writeProfile2, deleteProfile: deleteProfile2 } = await Promise.resolve().then(() => (init_profile(), profile_exports));
63507
63736
  const args5 = process.argv.slice(2);
63508
63737
  if (args5.includes("--show")) {
@@ -63575,9 +63804,9 @@ var signal_exports = {};
63575
63804
  __export(signal_exports, {
63576
63805
  extractFingerprint: () => extractFingerprint
63577
63806
  });
63578
- import { readFileSync as readFileSync32, readdirSync as readdirSync4 } from "fs";
63807
+ import { readFileSync as readFileSync33, readdirSync as readdirSync4 } from "fs";
63579
63808
  import { execFileSync } from "child_process";
63580
- import { join as join39 } from "path";
63809
+ import { join as join40 } from "path";
63581
63810
  function safeGit(args5, cwd) {
63582
63811
  try {
63583
63812
  return execFileSync("git", ["-C", cwd, ...args5], {
@@ -63605,20 +63834,20 @@ function isEmployerContext(cwd) {
63605
63834
  }
63606
63835
  function readJsonSafe(path6) {
63607
63836
  try {
63608
- return JSON.parse(readFileSync32(path6, "utf8"));
63837
+ return JSON.parse(readFileSync33(path6, "utf8"));
63609
63838
  } catch {
63610
63839
  return null;
63611
63840
  }
63612
63841
  }
63613
63842
  function readFileSafe(path6) {
63614
63843
  try {
63615
- return readFileSync32(path6, "utf8");
63844
+ return readFileSync33(path6, "utf8");
63616
63845
  } catch {
63617
63846
  return "";
63618
63847
  }
63619
63848
  }
63620
63849
  function tokensFromPackageJson(cwd) {
63621
- const pkg = readJsonSafe(join39(cwd, "package.json"));
63850
+ const pkg = readJsonSafe(join40(cwd, "package.json"));
63622
63851
  if (!pkg || typeof pkg !== "object") return [];
63623
63852
  const p = pkg;
63624
63853
  const deps = {
@@ -63632,9 +63861,9 @@ function workspaceMemberDirs(cwd) {
63632
63861
  const dirs = [cwd];
63633
63862
  for (const group of ["apps", "packages"]) {
63634
63863
  try {
63635
- const groupDir = join39(cwd, group);
63864
+ const groupDir = join40(cwd, group);
63636
63865
  for (const e of readdirSync4(groupDir, { withFileTypes: true })) {
63637
- if (e.isDirectory() && !e.isSymbolicLink()) dirs.push(join39(groupDir, e.name));
63866
+ if (e.isDirectory() && !e.isSymbolicLink()) dirs.push(join40(groupDir, e.name));
63638
63867
  }
63639
63868
  } catch {
63640
63869
  }
@@ -63642,18 +63871,18 @@ function workspaceMemberDirs(cwd) {
63642
63871
  return dirs;
63643
63872
  }
63644
63873
  function tokensFromRequirementsTxt(cwd) {
63645
- const content = readFileSafe(join39(cwd, "requirements.txt"));
63874
+ const content = readFileSafe(join40(cwd, "requirements.txt"));
63646
63875
  if (!content) return [];
63647
63876
  return content.split("\n").map((l) => l.trim().split(/[>=<!\[;]/)[0].trim().toLowerCase()).filter(Boolean);
63648
63877
  }
63649
63878
  function tokensFromGoMod(cwd) {
63650
- const content = readFileSafe(join39(cwd, "go.mod"));
63879
+ const content = readFileSafe(join40(cwd, "go.mod"));
63651
63880
  if (!content) return [];
63652
63881
  const requires = Array.from(content.matchAll(/^\s+([^\s]+)\s+v/gm)).map((m) => m[1].split("/").pop() ?? "").filter(Boolean);
63653
63882
  return ["go", ...requires];
63654
63883
  }
63655
63884
  function tokensFromCargoToml(cwd) {
63656
- const content = readFileSafe(join39(cwd, "Cargo.toml"));
63885
+ const content = readFileSafe(join40(cwd, "Cargo.toml"));
63657
63886
  if (!content) return [];
63658
63887
  const deps = [];
63659
63888
  let inDeps = false;
@@ -63674,7 +63903,7 @@ function tokensFromFileExtensions(cwd) {
63674
63903
  const tokens = [];
63675
63904
  const scanDirs = [cwd];
63676
63905
  try {
63677
- const srcDir = join39(cwd, "src");
63906
+ const srcDir = join40(cwd, "src");
63678
63907
  readdirSync4(srcDir);
63679
63908
  scanDirs.push(srcDir);
63680
63909
  } catch {
@@ -63835,9 +64064,9 @@ var init_signal = __esm({
63835
64064
  // bin/jpi-learn.js
63836
64065
  var jpi_learn_exports = {};
63837
64066
  __export(jpi_learn_exports, {
63838
- run: () => run22
64067
+ run: () => run23
63839
64068
  });
63840
- async function run22() {
64069
+ async function run23() {
63841
64070
  try {
63842
64071
  const args5 = process.argv.slice(2);
63843
64072
  const cwdIdx = args5.indexOf("--cwd");
@@ -63864,7 +64093,7 @@ var init_jpi_learn = __esm({
63864
64093
  "use strict";
63865
64094
  isMain = process.argv[1]?.endsWith("jpi-learn.js") || process.argv[1]?.endsWith("jpi-learn");
63866
64095
  if (isMain) {
63867
- run22();
64096
+ run23();
63868
64097
  }
63869
64098
  }
63870
64099
  });
@@ -63872,9 +64101,9 @@ var init_jpi_learn = __esm({
63872
64101
  // bin/jpi-config.js
63873
64102
  var jpi_config_exports = {};
63874
64103
  __export(jpi_config_exports, {
63875
- run: () => run23
64104
+ run: () => run24
63876
64105
  });
63877
- import { join as join40 } from "path";
64106
+ import { join as join41 } from "path";
63878
64107
  import { homedir as homedir30 } from "os";
63879
64108
  function parseNudgeMode2(raw) {
63880
64109
  if (raw === "session" || raw === "always") return raw;
@@ -63888,7 +64117,7 @@ function printMixValues() {
63888
64117
  console.log(" balanced \u2014 rebalanced default (contribute 8, roles ~12)");
63889
64118
  console.log(" credential \u2014 contribution-forward (contribute 12, roles ~8)");
63890
64119
  }
63891
- async function run23() {
64120
+ async function run24() {
63892
64121
  const args5 = process.argv.slice(2);
63893
64122
  const filtered = args5[0] === "config" ? args5.slice(1) : args5;
63894
64123
  if (filtered[0] === "get" && filtered[1] === "mix") {
@@ -64019,34 +64248,34 @@ var init_jpi_config = __esm({
64019
64248
  "bin/jpi-config.js"() {
64020
64249
  "use strict";
64021
64250
  init_config();
64022
- TERMINALHIRE_DIR21 = process.env.TERMINALHIRE_DIR || join40(homedir30(), ".terminalhire");
64023
- CONFIG_FILE2 = join40(TERMINALHIRE_DIR21, "config.json");
64251
+ TERMINALHIRE_DIR21 = process.env.TERMINALHIRE_DIR || join41(homedir30(), ".terminalhire");
64252
+ CONFIG_FILE2 = join41(TERMINALHIRE_DIR21, "config.json");
64024
64253
  }
64025
64254
  });
64026
64255
 
64027
64256
  // bin/jpi-spinner.js
64028
64257
  var jpi_spinner_exports = {};
64029
64258
  __export(jpi_spinner_exports, {
64030
- run: () => run24
64259
+ run: () => run25
64031
64260
  });
64032
- import { readFileSync as readFileSync33, writeFileSync as writeFileSync25, copyFileSync as copyFileSync3, existsSync as existsSync23 } from "fs";
64033
- import { join as join41 } from "path";
64261
+ import { readFileSync as readFileSync34, writeFileSync as writeFileSync25, copyFileSync as copyFileSync3, existsSync as existsSync24 } from "fs";
64262
+ import { join as join42 } from "path";
64034
64263
  import { homedir as homedir31 } from "os";
64035
64264
  import { createInterface as createInterface12 } from "readline";
64036
- function readConfig2() {
64265
+ function readConfig3() {
64037
64266
  try {
64038
- return existsSync23(CONFIG_FILE3) ? JSON.parse(readFileSync33(CONFIG_FILE3, "utf8")) : {};
64267
+ return existsSync24(CONFIG_FILE3) ? JSON.parse(readFileSync34(CONFIG_FILE3, "utf8")) : {};
64039
64268
  } catch {
64040
64269
  return {};
64041
64270
  }
64042
64271
  }
64043
64272
  function writeConfig2(patch) {
64044
64273
  ensureStateDir(TH_DIR);
64045
- const merged = { ...readConfig2(), ...patch };
64274
+ const merged = { ...readConfig3(), ...patch };
64046
64275
  writeFileSync25(CONFIG_FILE3, JSON.stringify(merged, null, 2) + "\n", "utf8");
64047
64276
  }
64048
64277
  function backupSettings() {
64049
- if (!existsSync23(SETTINGS_PATH)) return null;
64278
+ if (!existsSync24(SETTINGS_PATH)) return null;
64050
64279
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
64051
64280
  const backupPath = `${SETTINGS_PATH}.terminalhire-backup-${ts}`;
64052
64281
  copyFileSync3(SETTINGS_PATH, backupPath);
@@ -64063,7 +64292,7 @@ function ask3(question) {
64063
64292
  }
64064
64293
  function readTopMatches() {
64065
64294
  try {
64066
- const c = JSON.parse(readFileSync33(CACHE_FILE2, "utf8"));
64295
+ const c = JSON.parse(readFileSync34(CACHE_FILE2, "utf8"));
64067
64296
  return Array.isArray(c.topMatches) ? c.topMatches : [];
64068
64297
  } catch {
64069
64298
  return [];
@@ -64076,7 +64305,7 @@ function attempt(fn) {
64076
64305
  return { skipped: true, reason: err && err.code || "write-failed", keptUserVerbs: 0 };
64077
64306
  }
64078
64307
  }
64079
- async function run24() {
64308
+ async function run25() {
64080
64309
  const args5 = process.argv.slice(2).filter((a) => a !== "spinner");
64081
64310
  const has2 = (f) => args5.includes(f);
64082
64311
  const val = (f) => {
@@ -64277,20 +64506,20 @@ var init_jpi_spinner = __esm({
64277
64506
  "use strict";
64278
64507
  init_spinner();
64279
64508
  init_state_dir();
64280
- TH_DIR = process.env["TERMINALHIRE_DIR"] || join41(homedir31(), ".terminalhire");
64281
- CONFIG_FILE3 = join41(TH_DIR, "config.json");
64282
- SETTINGS_PATH = process.env["TERMINALHIRE_CLAUDE_SETTINGS"] || join41(homedir31(), ".claude", "settings.json");
64283
- CACHE_FILE2 = join41(TH_DIR, "index-cache.json");
64509
+ TH_DIR = process.env["TERMINALHIRE_DIR"] || join42(homedir31(), ".terminalhire");
64510
+ CONFIG_FILE3 = join42(TH_DIR, "config.json");
64511
+ SETTINGS_PATH = process.env["TERMINALHIRE_CLAUDE_SETTINGS"] || join42(homedir31(), ".claude", "settings.json");
64512
+ CACHE_FILE2 = join42(TH_DIR, "index-cache.json");
64284
64513
  }
64285
64514
  });
64286
64515
 
64287
64516
  // bin/jpi-sync.js
64288
64517
  var jpi_sync_exports = {};
64289
64518
  __export(jpi_sync_exports, {
64290
- run: () => run25
64519
+ run: () => run26
64291
64520
  });
64292
- import { readFileSync as readFileSync34, writeFileSync as writeFileSync26, existsSync as existsSync24, rmSync as rmSync10 } from "fs";
64293
- import { join as join42 } from "path";
64521
+ import { readFileSync as readFileSync35, writeFileSync as writeFileSync26, existsSync as existsSync25, rmSync as rmSync11 } from "fs";
64522
+ import { join as join43 } from "path";
64294
64523
  import { homedir as homedir32, hostname as osHostname2 } from "os";
64295
64524
  import { createInterface as createInterface13 } from "readline";
64296
64525
  function ask4(question) {
@@ -64304,7 +64533,7 @@ function ask4(question) {
64304
64533
  }
64305
64534
  function readMarker() {
64306
64535
  try {
64307
- return existsSync24(TIER1_MARKER) ? JSON.parse(readFileSync34(TIER1_MARKER, "utf8")) : null;
64536
+ return existsSync25(TIER1_MARKER) ? JSON.parse(readFileSync35(TIER1_MARKER, "utf8")) : null;
64308
64537
  } catch {
64309
64538
  return null;
64310
64539
  }
@@ -64315,7 +64544,7 @@ function writeMarker(marker) {
64315
64544
  }
64316
64545
  function clearMarker() {
64317
64546
  try {
64318
- rmSync10(TIER1_MARKER);
64547
+ rmSync11(TIER1_MARKER);
64319
64548
  } catch {
64320
64549
  }
64321
64550
  }
@@ -64376,13 +64605,13 @@ async function runPush() {
64376
64605
  }
64377
64606
  const fields = buildConsentFields(profile);
64378
64607
  renderPreview(fields);
64379
- await new Promise((resolve6) => {
64608
+ await new Promise((resolve7) => {
64380
64609
  const rl = createInterface13({ input: process.stdin, output: process.stdout });
64381
64610
  rl.question(
64382
64611
  " Press Enter to open your browser to authorize + consent (or Ctrl-C to cancel)... ",
64383
64612
  () => {
64384
64613
  rl.close();
64385
- resolve6();
64614
+ resolve7();
64386
64615
  }
64387
64616
  );
64388
64617
  });
@@ -64605,7 +64834,7 @@ async function runDelete() {
64605
64834
  clearMarker();
64606
64835
  console.log("\n Synced profile deleted and local marker cleared.\n");
64607
64836
  }
64608
- async function run25() {
64837
+ async function run26() {
64609
64838
  const args5 = process.argv.slice(2).filter((a) => a !== "sync");
64610
64839
  const has2 = (f) => args5.includes(f);
64611
64840
  if (has2("--push") || has2("--enable")) {
@@ -64639,8 +64868,8 @@ var init_jpi_sync = __esm({
64639
64868
  "use strict";
64640
64869
  init_open_url();
64641
64870
  init_state_dir();
64642
- TH_DIR2 = process.env["TERMINALHIRE_DIR"] || join42(homedir32(), ".terminalhire");
64643
- TIER1_MARKER = join42(TH_DIR2, "tier1.json");
64871
+ TH_DIR2 = process.env["TERMINALHIRE_DIR"] || join43(homedir32(), ".terminalhire");
64872
+ TIER1_MARKER = join43(TH_DIR2, "tier1.json");
64644
64873
  API_URL8 = process.env["TERMINALHIRE_API_URL"] || process.env["JPI_API_URL"] || "https://terminalhire.com";
64645
64874
  SYNC_BASE = "https://terminalhire.com";
64646
64875
  POLL_INTERVAL_MS = 2e3;
@@ -64652,50 +64881,50 @@ var init_jpi_sync = __esm({
64652
64881
  // bin/jpi-init.js
64653
64882
  var jpi_init_exports = {};
64654
64883
  __export(jpi_init_exports, {
64655
- run: () => run26
64884
+ run: () => run27
64656
64885
  });
64657
- import { existsSync as existsSync25 } from "fs";
64658
- import { join as join43, resolve as resolve5 } from "path";
64886
+ import { existsSync as existsSync26 } from "fs";
64887
+ import { join as join44, resolve as resolve6 } from "path";
64659
64888
  import { fileURLToPath as fileURLToPath7, pathToFileURL } from "url";
64660
64889
  import { createInterface as createInterface14 } from "readline";
64661
64890
  import { spawnSync as spawnSync4 } from "child_process";
64662
64891
  function resolveScript(name) {
64663
- const distPath = resolve5(join43(__dirname4, "..", "..", "dist", "bin", `${name}.js`));
64664
- const legacyPath = resolve5(join43(__dirname4, `${name}.js`));
64665
- return existsSync25(distPath) ? distPath : legacyPath;
64892
+ const distPath = resolve6(join44(__dirname4, "..", "..", "dist", "bin", `${name}.js`));
64893
+ const legacyPath = resolve6(join44(__dirname4, `${name}.js`));
64894
+ return existsSync26(distPath) ? distPath : legacyPath;
64666
64895
  }
64667
64896
  function resolveSrc(name) {
64668
- const distPath = resolve5(join43(__dirname4, "..", "..", "dist", "src", `${name}.js`));
64669
- const legacyPath = resolve5(join43(__dirname4, "..", "src", `${name}.js`));
64670
- return existsSync25(distPath) ? distPath : legacyPath;
64897
+ const distPath = resolve6(join44(__dirname4, "..", "..", "dist", "src", `${name}.js`));
64898
+ const legacyPath = resolve6(join44(__dirname4, "..", "src", `${name}.js`));
64899
+ return existsSync26(distPath) ? distPath : legacyPath;
64671
64900
  }
64672
64901
  function resolveInstallJs() {
64673
- const fromDist = resolve5(join43(__dirname4, "..", "..", "install.js"));
64674
- const fromBin = resolve5(join43(__dirname4, "..", "install.js"));
64675
- if (existsSync25(fromDist)) return fromDist;
64676
- if (existsSync25(fromBin)) return fromBin;
64902
+ const fromDist = resolve6(join44(__dirname4, "..", "..", "install.js"));
64903
+ const fromBin = resolve6(join44(__dirname4, "..", "install.js"));
64904
+ if (existsSync26(fromDist)) return fromDist;
64905
+ if (existsSync26(fromBin)) return fromBin;
64677
64906
  return fromBin;
64678
64907
  }
64679
64908
  function resolveStatuslineInstallJs() {
64680
- const fromDist = resolve5(join43(__dirname4, "..", "..", "statusline-install.js"));
64681
- const fromBin = resolve5(join43(__dirname4, "..", "statusline-install.js"));
64682
- if (existsSync25(fromDist)) return fromDist;
64683
- if (existsSync25(fromBin)) return fromBin;
64909
+ const fromDist = resolve6(join44(__dirname4, "..", "..", "statusline-install.js"));
64910
+ const fromBin = resolve6(join44(__dirname4, "..", "statusline-install.js"));
64911
+ if (existsSync26(fromDist)) return fromDist;
64912
+ if (existsSync26(fromBin)) return fromBin;
64684
64913
  return fromBin;
64685
64914
  }
64686
64915
  function tokenizeInterest(raw) {
64687
64916
  return raw.split(/[,/]|\s+/).map((t) => t.trim()).filter(Boolean);
64688
64917
  }
64689
- async function run26() {
64918
+ async function run27() {
64690
64919
  const rl = createInterface14({ input: process.stdin, output: process.stdout });
64691
- const ask5 = (question) => new Promise((resolve6) => {
64920
+ const ask5 = (question) => new Promise((resolve7) => {
64692
64921
  let answered = false;
64693
64922
  rl.question(question, (answer) => {
64694
64923
  answered = true;
64695
- resolve6((answer || "").trim().toLowerCase());
64924
+ resolve7((answer || "").trim().toLowerCase());
64696
64925
  });
64697
64926
  rl.once("close", () => {
64698
- if (!answered) resolve6(null);
64927
+ if (!answered) resolve7(null);
64699
64928
  });
64700
64929
  });
64701
64930
  console.log("");
@@ -65051,11 +65280,11 @@ var init_beta_nudge = __esm({
65051
65280
  // bin/jpi-refresh.js
65052
65281
  var jpi_refresh_exports = {};
65053
65282
  __export(jpi_refresh_exports, {
65054
- run: () => run27
65283
+ run: () => run28
65055
65284
  });
65056
65285
  import { fileURLToPath as fileURLToPath8 } from "url";
65057
65286
  import { hostname, homedir as osHomedir } from "os";
65058
- async function run27() {
65287
+ async function run28() {
65059
65288
  try {
65060
65289
  let index;
65061
65290
  let indexETag;
@@ -65524,16 +65753,16 @@ var init_jpi_refresh = __esm({
65524
65753
  // bin/jpi-save.js
65525
65754
  var jpi_save_exports = {};
65526
65755
  __export(jpi_save_exports, {
65527
- run: () => run28
65756
+ run: () => run29
65528
65757
  });
65529
- import { readFileSync as readFileSync35, existsSync as existsSync26 } from "fs";
65530
- import { join as join44 } from "path";
65758
+ import { readFileSync as readFileSync36, existsSync as existsSync27 } from "fs";
65759
+ import { join as join45 } from "path";
65531
65760
  import { homedir as homedir33 } from "os";
65532
65761
  import { fileURLToPath as fileURLToPath9 } from "url";
65533
65762
  function findJobInCache(jobId) {
65534
65763
  try {
65535
- if (!existsSync26(INDEX_CACHE_FILE7)) return null;
65536
- const raw = readFileSync35(INDEX_CACHE_FILE7, "utf8");
65764
+ if (!existsSync27(INDEX_CACHE_FILE7)) return null;
65765
+ const raw = readFileSync36(INDEX_CACHE_FILE7, "utf8");
65537
65766
  const entry = JSON.parse(raw);
65538
65767
  const jobs = entry?.index?.jobs ?? [];
65539
65768
  return jobs.find((j) => j.id === jobId) ?? null;
@@ -65602,7 +65831,7 @@ async function cmdUnsave(jobId) {
65602
65831
  process.exit(1);
65603
65832
  }
65604
65833
  }
65605
- async function run28() {
65834
+ async function run29() {
65606
65835
  const verb = process.argv[2];
65607
65836
  const jobId = process.argv[3];
65608
65837
  try {
@@ -65626,25 +65855,25 @@ var init_jpi_save = __esm({
65626
65855
  "bin/jpi-save.js"() {
65627
65856
  "use strict";
65628
65857
  __dirname6 = fileURLToPath9(new URL(".", import.meta.url));
65629
- TERMINALHIRE_DIR22 = process.env.TERMINALHIRE_DIR || join44(homedir33(), ".terminalhire");
65630
- INDEX_CACHE_FILE7 = join44(TERMINALHIRE_DIR22, "index-cache.json");
65858
+ TERMINALHIRE_DIR22 = process.env.TERMINALHIRE_DIR || join45(homedir33(), ".terminalhire");
65859
+ INDEX_CACHE_FILE7 = join45(TERMINALHIRE_DIR22, "index-cache.json");
65631
65860
  }
65632
65861
  });
65633
65862
 
65634
65863
  // bin/jpi-beta.js
65635
65864
  var jpi_beta_exports = {};
65636
65865
  __export(jpi_beta_exports, {
65637
- run: () => run29
65866
+ run: () => run30
65638
65867
  });
65639
65868
  import { createInterface as createInterface15 } from "readline";
65640
- async function run29() {
65869
+ async function run30() {
65641
65870
  const rl = createInterface15({ input: process.stdin, output: process.stdout });
65642
- const ask5 = (question) => new Promise((resolve6) => {
65643
- const onClose = () => resolve6(null);
65871
+ const ask5 = (question) => new Promise((resolve7) => {
65872
+ const onClose = () => resolve7(null);
65644
65873
  rl.once("close", onClose);
65645
65874
  rl.question(question, (answer) => {
65646
65875
  rl.removeListener("close", onClose);
65647
- resolve6((answer || "").trim());
65876
+ resolve7((answer || "").trim());
65648
65877
  });
65649
65878
  });
65650
65879
  const alreadyActed = readConfig().betaOptIn === true;
@@ -65677,8 +65906,8 @@ async function run29() {
65677
65906
  console.log(" rough edges you find.");
65678
65907
  console.log(" \u2022 A spot on the founding-contributors wall.");
65679
65908
  console.log("");
65680
- const join47 = await ask5(' Type "yes" to join the beta as a Founding Contributor (anything else cancels): ');
65681
- if ((join47 || "").toLowerCase() !== "yes") {
65909
+ const join48 = await ask5(' Type "yes" to join the beta as a Founding Contributor (anything else cancels): ');
65910
+ if ((join48 || "").toLowerCase() !== "yes") {
65682
65911
  console.log("\n No problem \u2014 nothing was sent. Run `terminalhire beta` any time.\n");
65683
65912
  rl.close();
65684
65913
  return;
@@ -65758,17 +65987,17 @@ var init_jpi_beta = __esm({
65758
65987
  // bin/jpi-feedback.js
65759
65988
  var jpi_feedback_exports = {};
65760
65989
  __export(jpi_feedback_exports, {
65761
- run: () => run30
65990
+ run: () => run31
65762
65991
  });
65763
65992
  import { createInterface as createInterface16 } from "readline";
65764
- import { readFileSync as readFileSync36, existsSync as existsSync27 } from "fs";
65765
- import { join as join45 } from "path";
65993
+ import { readFileSync as readFileSync37, existsSync as existsSync28 } from "fs";
65994
+ import { join as join46 } from "path";
65766
65995
  import { fileURLToPath as fileURLToPath10 } from "url";
65767
65996
  function readLocalVersion3() {
65768
65997
  try {
65769
- for (const p of [join45(__dirname7, "..", "..", "package.json"), join45(__dirname7, "..", "package.json")]) {
65770
- if (existsSync27(p)) {
65771
- const pkg = JSON.parse(readFileSync36(p, "utf8"));
65998
+ for (const p of [join46(__dirname7, "..", "..", "package.json"), join46(__dirname7, "..", "package.json")]) {
65999
+ if (existsSync28(p)) {
66000
+ const pkg = JSON.parse(readFileSync37(p, "utf8"));
65772
66001
  if (pkg.version) return pkg.version;
65773
66002
  }
65774
66003
  }
@@ -65776,14 +66005,14 @@ function readLocalVersion3() {
65776
66005
  }
65777
66006
  return null;
65778
66007
  }
65779
- async function run30() {
66008
+ async function run31() {
65780
66009
  const rl = createInterface16({ input: process.stdin, output: process.stdout });
65781
- const ask5 = (question) => new Promise((resolve6) => {
65782
- const onClose = () => resolve6(null);
66010
+ const ask5 = (question) => new Promise((resolve7) => {
66011
+ const onClose = () => resolve7(null);
65783
66012
  rl.once("close", onClose);
65784
66013
  rl.question(question, (answer) => {
65785
66014
  rl.removeListener("close", onClose);
65786
- resolve6((answer || "").trim());
66015
+ resolve7((answer || "").trim());
65787
66016
  });
65788
66017
  });
65789
66018
  const lastFull = readConfig().lastFullFeedbackAt;
@@ -65903,8 +66132,8 @@ var init_jpi_feedback = __esm({
65903
66132
 
65904
66133
  // bin/jpi-dispatch.js
65905
66134
  import { fileURLToPath as fileURLToPath11 } from "url";
65906
- import { join as join46 } from "path";
65907
- import { existsSync as existsSync28, readFileSync as readFileSync37 } from "fs";
66135
+ import { join as join47 } from "path";
66136
+ import { existsSync as existsSync29, readFileSync as readFileSync38 } from "fs";
65908
66137
  var __dirname8 = fileURLToPath11(new URL(".", import.meta.url));
65909
66138
  function isVerbose() {
65910
66139
  return Boolean(
@@ -65937,12 +66166,12 @@ process.on("unhandledRejection", reportFatal);
65937
66166
  function readPackageVersion() {
65938
66167
  try {
65939
66168
  const candidates = [
65940
- join46(__dirname8, "..", "..", "package.json"),
65941
- join46(__dirname8, "..", "package.json")
66169
+ join47(__dirname8, "..", "..", "package.json"),
66170
+ join47(__dirname8, "..", "package.json")
65942
66171
  ];
65943
66172
  for (const p of candidates) {
65944
- if (existsSync28(p)) {
65945
- const pkg = JSON.parse(readFileSync37(p, "utf8"));
66173
+ if (existsSync29(p)) {
66174
+ const pkg = JSON.parse(readFileSync38(p, "utf8"));
65946
66175
  if (pkg.version) return pkg.version;
65947
66176
  }
65948
66177
  }
@@ -65987,6 +66216,8 @@ var SUBCOMMANDS = [
65987
66216
  "upgrade",
65988
66217
  "beta",
65989
66218
  "feedback",
66219
+ // TERM-350 phase 4 — verify the working diff in a fresh ephemeral container.
66220
+ "run",
65990
66221
  "help",
65991
66222
  "--help",
65992
66223
  "-h",
@@ -65996,7 +66227,7 @@ var SUBCOMMANDS = [
65996
66227
  var firstArg = process.argv[2];
65997
66228
  if (!firstArg && !process.stdin.isTTY) {
65998
66229
  const { default: childProcess } = await import("child_process");
65999
- const nudgeScript = join46(__dirname8, "jpi.js");
66230
+ const nudgeScript = join47(__dirname8, "jpi.js");
66000
66231
  const child = childProcess.spawnSync(process.execPath, [nudgeScript], {
66001
66232
  stdio: ["inherit", "inherit", "inherit"]
66002
66233
  });
@@ -66006,8 +66237,8 @@ if (firstArg && SUBCOMMANDS.includes(firstArg) && process.stdin.isTTY) {
66006
66237
  try {
66007
66238
  const { readWebSessionFile: readWebSessionFile2 } = await Promise.resolve().then(() => (init_web_session(), web_session_exports));
66008
66239
  if (readWebSessionFile2()) {
66009
- const { readConfig: readConfig3, writeConfig: writeConfig3, isInboundNudgeMuted: isInboundNudgeMuted2 } = await Promise.resolve().then(() => (init_config(), config_exports));
66010
- if (!readConfig3().inboundNudgeDisclosed && !isInboundNudgeMuted2()) {
66240
+ const { readConfig: readConfig4, writeConfig: writeConfig3, isInboundNudgeMuted: isInboundNudgeMuted2 } = await Promise.resolve().then(() => (init_config(), config_exports));
66241
+ if (!readConfig4().inboundNudgeDisclosed && !isInboundNudgeMuted2()) {
66011
66242
  process.stderr.write(
66012
66243
  "\n Heads up: terminalhire now surfaces incoming connection requests in your spinner.\n Turn it off any time with `terminalhire connect --mute`.\n\n"
66013
66244
  );
@@ -66317,6 +66548,11 @@ if (firstArg === "repo") {
66317
66548
  await mod2.run();
66318
66549
  process.exit(0);
66319
66550
  }
66551
+ if (firstArg === "run") {
66552
+ const mod2 = await Promise.resolve().then(() => (init_jpi_run(), jpi_run_exports));
66553
+ const code = await mod2.run();
66554
+ process.exit(code ?? 0);
66555
+ }
66320
66556
  if (firstArg === "update" || firstArg === "upgrade") {
66321
66557
  const mod2 = await Promise.resolve().then(() => (init_jpi_update(), jpi_update_exports));
66322
66558
  const code = await mod2.run(process.argv.slice(3));
@@ -66496,9 +66732,9 @@ if (firstArg === "statusline") {
66496
66732
  console.error("Usage: terminalhire statusline --on | --off");
66497
66733
  process.exit(1);
66498
66734
  }
66499
- const fromDist = join46(__dirname8, "..", "..", "statusline-install.js");
66500
- const fromBin = join46(__dirname8, "..", "statusline-install.js");
66501
- const installer = existsSync28(fromDist) ? fromDist : fromBin;
66735
+ const fromDist = join47(__dirname8, "..", "..", "statusline-install.js");
66736
+ const fromBin = join47(__dirname8, "..", "statusline-install.js");
66737
+ const installer = existsSync29(fromDist) ? fromDist : fromBin;
66502
66738
  const { spawnSync: spawnSync5 } = await import("child_process");
66503
66739
  const child = spawnSync5(process.execPath, uninstall ? [installer, "--uninstall"] : [installer], {
66504
66740
  stdio: ["inherit", "inherit", "inherit"],