@brainervirus/workit-cli 8.20.0 → 8.21.0

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.
Files changed (2) hide show
  1. package/dist/index.js +719 -668
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ var package_default;
65
65
  var init_package = __esm(() => {
66
66
  package_default = {
67
67
  name: "@brainervirus/workit-cli",
68
- version: "8.20.0",
68
+ version: "8.21.0",
69
69
  private: false,
70
70
  description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
71
71
  keywords: [
@@ -103,13 +103,13 @@ var init_package = __esm(() => {
103
103
  },
104
104
  dependencies: {
105
105
  "@babel/parser": "7.29.9",
106
- "@brainervirus/workit-cursor": "^8.20.0",
106
+ "@brainervirus/workit-cursor": "^8.21.0",
107
107
  "@inkjs/ui": "2.0.0",
108
108
  ink: "7.1.1",
109
109
  react: "19.2.8"
110
110
  },
111
111
  devDependencies: {
112
- "@brainervirus/workit-core": "^8.20.0"
112
+ "@brainervirus/workit-core": "^8.21.0"
113
113
  },
114
114
  engines: {
115
115
  node: ">=24"
@@ -15262,11 +15262,23 @@ var init_workers = __esm(() => {
15262
15262
  UNCERTAIN_WORKER_STATES = ["dispatching", "running", "cancelling", "unknown"];
15263
15263
  });
15264
15264
 
15265
+ // packages/workit-core/src/hooks/standing-signal.ts
15266
+ import fs12 from "node:fs";
15267
+ import path16 from "node:path";
15268
+ var standingRevFile = (store) => path16.join(store, "standing", "rev"), bumpStandingRev = (store, rev) => {
15269
+ try {
15270
+ fs12.mkdirSync(path16.join(store, "standing"), { recursive: true });
15271
+ fs12.writeFileSync(standingRevFile(store), `${rev}
15272
+ `);
15273
+ } catch {}
15274
+ };
15275
+ var init_standing_signal = () => {};
15276
+
15265
15277
  // packages/workit-core/src/ledger.ts
15266
15278
  import { spawnSync as spawnSync9 } from "node:child_process";
15267
15279
  import { createHash as createHash10, randomBytes as randomBytes3 } from "node:crypto";
15268
- import fs12 from "node:fs";
15269
- import path16 from "node:path";
15280
+ import fs13 from "node:fs";
15281
+ import path17 from "node:path";
15270
15282
  function resolveCommit(cwd, ref) {
15271
15283
  if (!safeRef(ref))
15272
15284
  return null;
@@ -15332,14 +15344,14 @@ function diffHash(cwd, base, head) {
15332
15344
  return `sha256:${hash.digest("hex")}`;
15333
15345
  }
15334
15346
  function storeRoot(cwd) {
15335
- const location = resolveStore(path16.resolve(cwd));
15347
+ const location = resolveStore(path17.resolve(cwd));
15336
15348
  if (location instanceof Error)
15337
15349
  return err("unavailable", location.message.replace(/; fix the repository.*$/u, ""), "fix the repository (git status should work here) or run from a non-git directory");
15338
15350
  return { ok: true, value: { root: location.dir, shared: location.shared } };
15339
15351
  }
15340
15352
  function ledgerPath(cwd) {
15341
15353
  const root = storeRoot(cwd);
15342
- return root.ok ? { ok: true, value: path16.join(root.value.root, "ledger", "ledger.jsonl") } : root;
15354
+ return root.ok ? { ok: true, value: path17.join(root.value.root, "ledger", "ledger.jsonl") } : root;
15343
15355
  }
15344
15356
  function actorFromEnv(env) {
15345
15357
  const value = (key) => {
@@ -15377,15 +15389,15 @@ function withLedgerLock(file, fn, waitMs = hostAwareLockTimeout(LOCK_WAIT_MS)) {
15377
15389
  }
15378
15390
  function appendLine(file, build, options) {
15379
15391
  const write = () => {
15380
- const fd = fs12.openSync(file, "a+", 384);
15392
+ const fd = fs13.openSync(file, "a+", 384);
15381
15393
  try {
15382
15394
  if (process.platform !== "win32")
15383
15395
  tighten(fd);
15384
- const size = fs12.fstatSync(fd).size;
15396
+ const size = fs13.fstatSync(fd).size;
15385
15397
  let fence = "";
15386
15398
  if (size > 0) {
15387
15399
  const last = Buffer.alloc(1);
15388
- fs12.readSync(fd, last, 0, 1, size - 1);
15400
+ fs13.readSync(fd, last, 0, 1, size - 1);
15389
15401
  if (last[0] !== 10)
15390
15402
  fence = `
15391
15403
  `;
@@ -15394,17 +15406,17 @@ function appendLine(file, build, options) {
15394
15406
  if (!line.ok)
15395
15407
  return line;
15396
15408
  const bytes = Buffer.from(fence + line.value);
15397
- const written = fs12.writeSync(fd, bytes);
15409
+ const written = fs13.writeSync(fd, bytes);
15398
15410
  if (written !== bytes.length)
15399
15411
  return err("unavailable", `short write to ${file}: ${written} of ${bytes.length} bytes; the row is torn and will be skipped`);
15400
15412
  return { ok: true, value: undefined };
15401
15413
  } finally {
15402
- fs12.closeSync(fd);
15414
+ fs13.closeSync(fd);
15403
15415
  }
15404
15416
  };
15405
15417
  try {
15406
- fs12.mkdirSync(path16.dirname(file), { recursive: true });
15407
- if (!options.forceLock && !onNetworkFs(path16.dirname(file)))
15418
+ fs13.mkdirSync(path17.dirname(file), { recursive: true });
15419
+ if (!options.forceLock && !onNetworkFs(path17.dirname(file)))
15408
15420
  return write();
15409
15421
  const locked = withLedgerLock(file, write);
15410
15422
  return locked ?? err("busy", `ledger lock ${file}.lock is held`, "retry; remove the .lock directory if no workit process is running");
@@ -15461,8 +15473,8 @@ function readLedger(cwd, options = {}) {
15461
15473
  let text = "";
15462
15474
  let stat = null;
15463
15475
  try {
15464
- stat = fs12.statSync(file.value);
15465
- text = fs12.readFileSync(file.value, "utf8");
15476
+ stat = fs13.statSync(file.value);
15477
+ text = fs13.readFileSync(file.value, "utf8");
15466
15478
  } catch (error) {
15467
15479
  if (error.code === "ENOENT")
15468
15480
  return {
@@ -15594,7 +15606,7 @@ function ledgerTampering(cwd) {
15594
15606
  if (!file.ok)
15595
15607
  return [];
15596
15608
  try {
15597
- const stat = fs12.statSync(file.value);
15609
+ const stat = fs13.statSync(file.value);
15598
15610
  const cached = tamperCache.get(file.value);
15599
15611
  if (cached && cached.size === stat.size && cached.stamp === fileStamp(stat))
15600
15612
  return cached.breaks;
@@ -16011,8 +16023,14 @@ function leadOnly(context, lead) {
16011
16023
  return { ok: true, value: undefined };
16012
16024
  return err("blocked", lead !== null ? `session ${session ?? "(none)"} is not the fanout's lead (${lead}): standing orders come from the lead` : `session ${session} is a worker or verifier: standing orders come from the lead`, lead !== null ? `the lead in a new session? workit fanout plan <plan.json> --take-lead from this session; a worker or verifier reports the order to the lead instead` : "a worker or verifier reports the order to the lead instead");
16013
16025
  }
16026
+ function signalStanding(cwd, result) {
16027
+ const root = result.ok ? storeRoot(cwd) : null;
16028
+ if (result.ok && root?.ok && root.value.shared)
16029
+ bumpStandingRev(root.value.root, result.value.id);
16030
+ return result;
16031
+ }
16014
16032
  function recordStanding(context, input) {
16015
- const what = required2(input.what, "<order>");
16033
+ const what = input.stop ? { ok: true, value: stopOrderText(input.what?.trim() || null) } : required2(input.what, "<order>");
16016
16034
  if (!what.ok)
16017
16035
  return what;
16018
16036
  if (/\p{Cc}/u.test(what.value))
@@ -16023,12 +16041,14 @@ function recordStanding(context, input) {
16023
16041
  const link = checkSupersede(context, "standing");
16024
16042
  if (!link.ok)
16025
16043
  return link;
16026
- return appendRow(context.cwd, {
16044
+ const recorded = appendRow(context.cwd, {
16027
16045
  ...common(context, noteKey(context)),
16028
16046
  type: "standing",
16029
16047
  fanout: input.fanout,
16030
- what: what.value
16048
+ what: what.value,
16049
+ ...input.stop ? { stop: true } : {}
16031
16050
  }, { now: context.now });
16051
+ return signalStanding(context.cwd, recorded);
16032
16052
  }
16033
16053
  function clearStanding(context, input) {
16034
16054
  const lead = leadOnly(context, input.lead);
@@ -16041,12 +16061,31 @@ function clearStanding(context, input) {
16041
16061
  if (!activeStanding(ledger.value.rows, input.fanout, input.leads ?? null).some((row) => row.id === input.target))
16042
16062
  return err("not_found", `no standing order ${input.target} in force for fanout ${input.fanout}`, `workit ledger standing list --fanout ${input.fanout}`);
16043
16063
  }
16044
- return appendRow(context.cwd, {
16064
+ return signalStanding(context.cwd, appendRow(context.cwd, {
16045
16065
  ...common(context, noteKey(context)),
16046
16066
  type: "standing.cleared",
16047
16067
  fanout: input.fanout,
16048
16068
  target: input.target
16049
- }, { now: context.now });
16069
+ }, { now: context.now }));
16070
+ }
16071
+ function liftStop(context, input) {
16072
+ const lead = leadOnly(context, input.lead);
16073
+ if (!lead.ok)
16074
+ return lead;
16075
+ const ledger = readLedger(context.cwd);
16076
+ if (!ledger.ok)
16077
+ return ledger;
16078
+ const stops = activeStanding(ledger.value.rows, input.fanout, input.leads ?? null).filter((row) => row.stop === true);
16079
+ if (!stops.length)
16080
+ return err("not_found", `no stop line in force for fanout ${input.fanout}`, `workit ledger standing list --fanout ${input.fanout}`);
16081
+ const cleared = [];
16082
+ for (const stop of stops) {
16083
+ const row = clearStanding(context, { ...input, target: stop.id });
16084
+ if (!row.ok)
16085
+ return row;
16086
+ cleared.push(row.value);
16087
+ }
16088
+ return { ok: true, value: cleared };
16050
16089
  }
16051
16090
  function dirtyElsewhere(cwd, branch, head) {
16052
16091
  if (headSha(cwd) === head)
@@ -16202,17 +16241,17 @@ function summarizeRow(row) {
16202
16241
  };
16203
16242
  }
16204
16243
  function stackPosition(root, branch) {
16205
- const dir = path16.join(root, "stacks");
16244
+ const dir = path17.join(root, "stacks");
16206
16245
  let names = [];
16207
16246
  try {
16208
- names = fs12.readdirSync(dir).filter((name) => name.endsWith(".json"));
16247
+ names = fs13.readdirSync(dir).filter((name) => name.endsWith(".json"));
16209
16248
  } catch {
16210
16249
  return null;
16211
16250
  }
16212
16251
  for (const name of names.toSorted()) {
16213
16252
  let parsed;
16214
16253
  try {
16215
- parsed = JSON.parse(fs12.readFileSync(path16.join(dir, name), "utf8"));
16254
+ parsed = JSON.parse(fs13.readFileSync(path17.join(dir, name), "utf8"));
16216
16255
  } catch {
16217
16256
  continue;
16218
16257
  }
@@ -16351,20 +16390,20 @@ var LEDGER_VERSION = 1, MAX_LINE_BYTES = 4096, VERDICT_RESULTS, PASSING, FAILING
16351
16390
  if (process.platform !== "linux")
16352
16391
  return false;
16353
16392
  try {
16354
- return isNetworkFsType(fs12.statfsSync(dir).type);
16393
+ return isNetworkFsType(fs13.statfsSync(dir).type);
16355
16394
  } catch {
16356
16395
  return false;
16357
16396
  }
16358
16397
  }, LOCK_WAIT_MS = 5000, LOCK_STALE_MS = 30000, LOCK_OWNER = "owner", lockToken = (lock) => {
16359
16398
  try {
16360
- return fs12.readFileSync(path16.join(lock, LOCK_OWNER), "utf8");
16399
+ return fs13.readFileSync(path17.join(lock, LOCK_OWNER), "utf8");
16361
16400
  } catch {
16362
16401
  return null;
16363
16402
  }
16364
16403
  }, lockAgeMs = (lock) => {
16365
- for (const target of [path16.join(lock, LOCK_OWNER), lock]) {
16404
+ for (const target of [path17.join(lock, LOCK_OWNER), lock]) {
16366
16405
  try {
16367
- return Date.now() - fs12.statSync(target).mtimeMs;
16406
+ return Date.now() - fs13.statSync(target).mtimeMs;
16368
16407
  } catch {}
16369
16408
  }
16370
16409
  return null;
@@ -16372,7 +16411,7 @@ var LEDGER_VERSION = 1, MAX_LINE_BYTES = 4096, VERDICT_RESULTS, PASSING, FAILING
16372
16411
  ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
16373
16412
  for (let span = Math.min(size, TAIL_BYTES);span > 0; span = Math.min(size, span * 2)) {
16374
16413
  const buffer = Buffer.alloc(span);
16375
- fs12.readSync(fd, buffer, 0, span, size - span);
16414
+ fs13.readSync(fd, buffer, 0, span, size - span);
16376
16415
  const end = buffer.lastIndexOf(10);
16377
16416
  if (end < 0) {
16378
16417
  if (span === size)
@@ -16402,8 +16441,8 @@ ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
16402
16441
  return null;
16403
16442
  }, tighten = (fd) => {
16404
16443
  try {
16405
- if ((fs12.fstatSync(fd).mode & 63) !== 0)
16406
- fs12.fchmodSync(fd, 384);
16444
+ if ((fs13.fstatSync(fd).mode & 63) !== 0)
16445
+ fs13.fchmodSync(fd, 384);
16407
16446
  } catch {}
16408
16447
  }, sealed = (row, id, at, previous) => {
16409
16448
  const { prevHash: _prev, rowHash: _row, ...fields } = row;
@@ -16465,7 +16504,7 @@ ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
16465
16504
  }, required2 = (value, flag) => {
16466
16505
  const text = value?.trim();
16467
16506
  return text ? { ok: true, value: text } : err("invalid_input", `${flag} is required`);
16468
- }, fromLead = (row, leads) => leads === null || row.actor.session !== null && leads.includes(row.actor.session), isDelegateSession = (session) => session !== null && (/-w-[a-z0-9._-]+(?:\+try\d)?$/u.test(session) || /-v\d+$/u.test(session) || session.includes(":")), OBSERVED_ONLY, MAX_DIRTY_PATHS = 10, dirtyState = (cwd) => {
16507
+ }, fromLead = (row, leads) => leads === null || row.actor.session !== null && leads.includes(row.actor.session), isDelegateSession = (session) => session !== null && (/-w-[a-z0-9._-]+(?:\+try\d)?$/u.test(session) || /-v\d+$/u.test(session) || session.includes(":")), stopOrderText = (note) => `STOP: start nothing new, stop every process you started (dev servers, browsers, watchers), commit only finished work, and report to the lead now${note ? ` (${note})` : ""}`, OBSERVED_ONLY, MAX_DIRTY_PATHS = 10, dirtyState = (cwd) => {
16469
16508
  const run = gitRun2(cwd, ["status", "--porcelain=v1", "-z", "--untracked-files=normal"], GIT_TIMEOUTS.worktree);
16470
16509
  if (!run.ok)
16471
16510
  return { dirty: false, files: 0, paths: [] };
@@ -16502,6 +16541,7 @@ var init_ledger = __esm(() => {
16502
16541
  init_vcs_config();
16503
16542
  init_rev();
16504
16543
  init_host_session();
16544
+ init_standing_signal();
16505
16545
  init_paths();
16506
16546
  VERDICT_RESULTS = [
16507
16547
  "verified",
@@ -16536,14 +16576,14 @@ var init_ledger = __esm(() => {
16536
16576
  ledgerLock = {
16537
16577
  acquire(lock) {
16538
16578
  try {
16539
- fs12.mkdirSync(lock);
16579
+ fs13.mkdirSync(lock);
16540
16580
  } catch (error) {
16541
16581
  if (error.code === "EEXIST")
16542
16582
  return null;
16543
16583
  throw error;
16544
16584
  }
16545
16585
  const token = `${process.pid}-${randomBytes3(8).toString("hex")}`;
16546
- fs12.writeFileSync(path16.join(lock, LOCK_OWNER), token);
16586
+ fs13.writeFileSync(path17.join(lock, LOCK_OWNER), token);
16547
16587
  return token;
16548
16588
  },
16549
16589
  release(lock, token) {
@@ -16551,35 +16591,35 @@ var init_ledger = __esm(() => {
16551
16591
  return false;
16552
16592
  const tomb = `${lock}.release-${randomBytes3(6).toString("hex")}`;
16553
16593
  try {
16554
- fs12.renameSync(lock, tomb);
16594
+ fs13.renameSync(lock, tomb);
16555
16595
  } catch {
16556
16596
  return false;
16557
16597
  }
16558
16598
  if (lockToken(tomb) !== token) {
16559
16599
  try {
16560
- fs12.renameSync(tomb, lock);
16600
+ fs13.renameSync(tomb, lock);
16561
16601
  } catch {}
16562
16602
  return false;
16563
16603
  }
16564
- fs12.rmSync(tomb, { recursive: true, force: true });
16604
+ fs13.rmSync(tomb, { recursive: true, force: true });
16565
16605
  return true;
16566
16606
  },
16567
16607
  token: lockToken,
16568
16608
  reap(lock, observed) {
16569
16609
  const tomb = `${lock}.reap-${randomBytes3(6).toString("hex")}`;
16570
16610
  try {
16571
- fs12.renameSync(lock, tomb);
16611
+ fs13.renameSync(lock, tomb);
16572
16612
  } catch {
16573
16613
  return false;
16574
16614
  }
16575
16615
  if (lockToken(tomb) === observed) {
16576
- fs12.rmSync(tomb, { recursive: true, force: true });
16616
+ fs13.rmSync(tomb, { recursive: true, force: true });
16577
16617
  return true;
16578
16618
  }
16579
16619
  try {
16580
- fs12.renameSync(tomb, lock);
16620
+ fs13.renameSync(tomb, lock);
16581
16621
  } catch {
16582
- fs12.rmSync(tomb, { recursive: true, force: true });
16622
+ fs13.rmSync(tomb, { recursive: true, force: true });
16583
16623
  }
16584
16624
  return false;
16585
16625
  }
@@ -16613,7 +16653,7 @@ var init_ledger = __esm(() => {
16613
16653
 
16614
16654
  // packages/workit-core/src/core/policy/derive.ts
16615
16655
  import { existsSync as existsSync4 } from "node:fs";
16616
- import path17 from "node:path";
16656
+ import path18 from "node:path";
16617
16657
  function deriveRequirements(judgment, scope, constraints, verification = "self") {
16618
16658
  const out = [];
16619
16659
  const base = { scope, dependentAction: null };
@@ -16754,7 +16794,7 @@ var RULES, derived2 = (spec) => ({
16754
16794
  decisionIds: []
16755
16795
  };
16756
16796
  }, planRecorded = (task, root) => {
16757
- const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync4(path17.resolve(root, ref.path)));
16797
+ const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync4(path18.resolve(root, ref.path)));
16758
16798
  if (cited)
16759
16799
  return {
16760
16800
  met: true,
@@ -16801,13 +16841,13 @@ var init_derive = __esm(() => {
16801
16841
 
16802
16842
  // packages/workit-core/src/core/task-evaluation.ts
16803
16843
  import { createHash as createHash11 } from "node:crypto";
16804
- import * as fs13 from "node:fs";
16844
+ import * as fs14 from "node:fs";
16805
16845
  import { spawnSync as spawnSync10 } from "node:child_process";
16806
- import path18 from "node:path";
16846
+ import path19 from "node:path";
16807
16847
  function captureCandidate(root, scope, environment = []) {
16808
16848
  let checkout;
16809
16849
  try {
16810
- checkout = fs13.realpathSync(root);
16850
+ checkout = fs14.realpathSync(root);
16811
16851
  } catch {
16812
16852
  return failure2("invalid_input", "candidate root does not exist");
16813
16853
  }
@@ -16825,11 +16865,11 @@ function captureCandidate(root, scope, environment = []) {
16825
16865
  if (item === ".git" || item === ".workit")
16826
16866
  continue;
16827
16867
  names.add(item);
16828
- if (!fs13.existsSync(target))
16868
+ if (!fs14.existsSync(target))
16829
16869
  continue;
16830
16870
  let stat;
16831
16871
  try {
16832
- stat = fs13.lstatSync(target);
16872
+ stat = fs14.lstatSync(target);
16833
16873
  } catch {
16834
16874
  uncertain = true;
16835
16875
  continue;
@@ -16845,17 +16885,17 @@ function captureCandidate(root, scope, environment = []) {
16845
16885
  for (const item of [...names].toSorted()) {
16846
16886
  if (!scopeMatches(item, normalizedScope))
16847
16887
  continue;
16848
- const target = path18.join(checkout, item);
16888
+ const target = path19.join(checkout, item);
16849
16889
  try {
16850
- const stat = fs13.lstatSync(target);
16890
+ const stat = fs14.lstatSync(target);
16851
16891
  if (stat.isSymbolicLink()) {
16852
- const link = fs13.readlinkSync(target);
16892
+ const link = fs14.readlinkSync(target);
16853
16893
  files.push({ path: item, kind: "symlink", digest: digestBytes(link), executable: null });
16854
16894
  } else if (stat.isFile()) {
16855
16895
  files.push({
16856
16896
  path: item,
16857
16897
  kind: "file",
16858
- digest: digestBytes(fs13.readFileSync(target)),
16898
+ digest: digestBytes(fs14.readFileSync(target)),
16859
16899
  executable: (stat.mode & 73) !== 0
16860
16900
  });
16861
16901
  } else if (!stat.isDirectory()) {
@@ -17254,12 +17294,12 @@ function boundTaskSummary(summary) {
17254
17294
  brief.truncated = JSON.stringify(brief).includes("…") || progress.blockers.length > BRIEF_BLOCKERS || unmet.length > BRIEF_OPEN;
17255
17295
  return brief;
17256
17296
  }
17257
- var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"), inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path18.sep}`), relative = (root, candidate) => path18.relative(root, candidate).split(path18.sep).join("/") || ".", canonicalPath = (value) => {
17297
+ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"), inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path19.sep}`), relative = (root, candidate) => path19.relative(root, candidate).split(path19.sep).join("/") || ".", canonicalPath = (value) => {
17258
17298
  if (typeof value !== "string" || !value)
17259
17299
  return null;
17260
17300
  if (value.includes("\\") || value.split("/").includes(".."))
17261
17301
  return null;
17262
- const normalized = path18.posix.normalize(value);
17302
+ const normalized = path19.posix.normalize(value);
17263
17303
  if (normalized === ".." || normalized.startsWith("../") || normalized.startsWith("/"))
17264
17304
  return null;
17265
17305
  return normalized === "." ? "." : normalized.replace(/\/$/, "");
@@ -17301,20 +17341,20 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
17301
17341
  git: !/not a git repository/i.test(stderr)
17302
17342
  };
17303
17343
  }
17304
- const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path18.sep).join("/")) : [];
17344
+ const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path19.sep).join("/")) : [];
17305
17345
  const stagedDeleted = spawnSync10("git", ["diff", "--cached", "--name-only", "--diff-filter=D", "-z"], { cwd: root, encoding: "buffer" });
17306
17346
  if (stagedDeleted.status !== 0) {
17307
17347
  const stderr = stagedDeleted.stderr?.toString("utf8") ?? "";
17308
17348
  if (!/not a git repository/i.test(stderr))
17309
17349
  return { paths, uncertain: true, git: true };
17310
17350
  } else if (stagedDeleted.stdout) {
17311
- paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path18.sep).join("/")));
17351
+ paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path19.sep).join("/")));
17312
17352
  }
17313
17353
  return { paths: [...new Set(paths)], uncertain: false, git: true };
17314
17354
  }, walk = (root, directory, output) => {
17315
17355
  let names;
17316
17356
  try {
17317
- names = fs13.readdirSync(directory);
17357
+ names = fs14.readdirSync(directory);
17318
17358
  } catch {
17319
17359
  return true;
17320
17360
  }
@@ -17322,10 +17362,10 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
17322
17362
  for (const name of names) {
17323
17363
  if (name === ".git" || name === ".workit")
17324
17364
  continue;
17325
- const target = path18.join(directory, name);
17365
+ const target = path19.join(directory, name);
17326
17366
  let stat;
17327
17367
  try {
17328
- stat = fs13.lstatSync(target);
17368
+ stat = fs14.lstatSync(target);
17329
17369
  } catch {
17330
17370
  uncertain = true;
17331
17371
  continue;
@@ -17339,14 +17379,14 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
17339
17379
  }, scopeRoots = (root, scope) => {
17340
17380
  const roots = [];
17341
17381
  for (const item of scope.paths.length ? scope.paths : ["."]) {
17342
- const target = path18.resolve(root, item);
17382
+ const target = path19.resolve(root, item);
17343
17383
  if (!inside(root, target))
17344
17384
  return failure2("invalid_input", `candidate scope escapes checkout: ${item} — keep one task per repository and coordinate a separate linked task in the other checkout`, { fields: [{ path: "scope.paths", reason: `${item} is outside the checkout` }] });
17345
17385
  let ancestor = target;
17346
- while (!fs13.existsSync(ancestor) && ancestor !== root)
17347
- ancestor = path18.dirname(ancestor);
17386
+ while (!fs14.existsSync(ancestor) && ancestor !== root)
17387
+ ancestor = path19.dirname(ancestor);
17348
17388
  try {
17349
- if (!inside(root, fs13.realpathSync(ancestor)))
17389
+ if (!inside(root, fs14.realpathSync(ancestor)))
17350
17390
  return failure2("invalid_input", `candidate scope escapes checkout through a symlink: ${item} — keep one task per repository and coordinate a separate linked task in the other checkout`, { fields: [{ path: "scope.paths", reason: `${item} resolves outside the checkout` }] });
17351
17391
  } catch {
17352
17392
  return failure2("invalid_input", `candidate scope cannot be inspected: ${item}`);
@@ -17399,7 +17439,7 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
17399
17439
  }, findingVerificationPasses = (findingCandidateId, evidence) => evidence.status === "passed" && (evidence.kind === "check" || evidence.kind === "review") && ((findingCandidateId ?? null) === null || evidence.candidateId != null), verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
17400
17440
  let root;
17401
17441
  try {
17402
- root = fs13.realpathSync(checkoutRoot);
17442
+ root = fs14.realpathSync(checkoutRoot);
17403
17443
  } catch {
17404
17444
  return failure2("permission_denied", "checkout root is unavailable");
17405
17445
  }
@@ -17408,23 +17448,23 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
17408
17448
  continue;
17409
17449
  if (!reference.digest)
17410
17450
  return failure2("invalid_input", "document references require a byte digest");
17411
- const target = path18.resolve(root, reference.path);
17412
- if (target !== root && !target.startsWith(`${root}${path18.sep}`))
17451
+ const target = path19.resolve(root, reference.path);
17452
+ if (target !== root && !target.startsWith(`${root}${path19.sep}`))
17413
17453
  return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
17414
17454
  fields: [
17415
17455
  { path: "contentRefs.path", reason: `${reference.path} is outside the checkout` }
17416
17456
  ]
17417
17457
  });
17418
17458
  try {
17419
- const below = path18.relative(root, target);
17459
+ const below = path19.relative(root, target);
17420
17460
  let current = root;
17421
- for (const segment of below.split(path18.sep)) {
17461
+ for (const segment of below.split(path19.sep)) {
17422
17462
  if (!segment)
17423
17463
  continue;
17424
- current = path18.join(current, segment);
17425
- const stat = fs13.lstatSync(current);
17426
- const real = fs13.realpathSync(current);
17427
- if (real !== root && !real.startsWith(`${root}${path18.sep}`))
17464
+ current = path19.join(current, segment);
17465
+ const stat = fs14.lstatSync(current);
17466
+ const real = fs14.realpathSync(current);
17467
+ if (real !== root && !real.startsWith(`${root}${path19.sep}`))
17428
17468
  return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
17429
17469
  fields: [
17430
17470
  {
@@ -17440,7 +17480,7 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
17440
17480
  if (current !== target && !stat.isDirectory())
17441
17481
  return failure2("invalid_input", "document reference ancestor is not a directory");
17442
17482
  }
17443
- if (digestBytes(fs13.readFileSync(target)) !== reference.digest)
17483
+ if (digestBytes(fs14.readFileSync(target)) !== reference.digest)
17444
17484
  return failure2("permission_denied", "decision document bytes have changed");
17445
17485
  } catch {
17446
17486
  return failure2("invalid_input", "decision document is unavailable");
@@ -18089,7 +18129,7 @@ var init_shell_words = __esm(() => {
18089
18129
 
18090
18130
  // packages/workit-core/src/hooks/raw-git.ts
18091
18131
  import os4 from "node:os";
18092
- import path19 from "node:path";
18132
+ import path20 from "node:path";
18093
18133
  function rawInvocations(command, dialect = "posix", depth = 0) {
18094
18134
  if (depth > 0)
18095
18135
  return walk2(command, dialect, depth);
@@ -18271,12 +18311,12 @@ function simpleCommand(command, dialect = "posix", depth = 0) {
18271
18311
  return null;
18272
18312
  return words;
18273
18313
  }
18274
- var SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLARATIONS, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, GIT_CONFIG_OPTIONS, GIT_CONFIG_ENV, ASSIGNMENT, MAX_DEPTH = 4, MAX_EXPANSIONS = 16, isAbsolute = (value) => path19.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\"), HERE, joinDir = (base, raw) => {
18314
+ var SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLARATIONS, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, GIT_CONFIG_OPTIONS, GIT_CONFIG_ENV, ASSIGNMENT, MAX_DEPTH = 4, MAX_EXPANSIONS = 16, isAbsolute = (value) => path20.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\"), HERE, joinDir = (base, raw) => {
18275
18315
  const next = raw.replace(HERE, ".");
18276
18316
  if (base === undefined || /[$`*?]/.test(next) || next === "-")
18277
18317
  return;
18278
- const expanded = next === "~" || next.startsWith("~/") ? path19.join(os4.homedir(), next.slice(1)) : next;
18279
- return base === null || isAbsolute(expanded) ? expanded : path19.join(base, expanded);
18318
+ const expanded = next === "~" || next.startsWith("~/") ? path20.join(os4.homedir(), next.slice(1)) : next;
18319
+ return base === null || isAbsolute(expanded) ? expanded : path20.join(base, expanded);
18280
18320
  }, rebase = (base, inner) => inner === null ? base : inner === undefined ? undefined : joinDir(base, inner), cdTarget = (words) => {
18281
18321
  const args = words.slice(1);
18282
18322
  const flag = args.findIndex((word) => /^-(?:literal)?path$/i.test(word));
@@ -18795,7 +18835,7 @@ import {
18795
18835
  unlinkSync as unlinkSync2,
18796
18836
  writeFileSync as writeFileSync3
18797
18837
  } from "node:fs";
18798
- import path20 from "node:path";
18838
+ import path21 from "node:path";
18799
18839
  function writeFileExclusive(file, content, mode) {
18800
18840
  try {
18801
18841
  writeFileSync3(file, content, { encoding: "utf8", flag: "wx", mode });
@@ -18807,9 +18847,9 @@ function writeFileExclusive(file, content, mode) {
18807
18847
  }
18808
18848
  }
18809
18849
  function writeFileAtomic(file, content, mode) {
18810
- const absolute = path20.resolve(file);
18811
- let parent = path20.dirname(absolute);
18812
- const root = path20.parse(parent).root;
18850
+ const absolute = path21.resolve(file);
18851
+ let parent = path21.dirname(absolute);
18852
+ const root = path21.parse(parent).root;
18813
18853
  for (;; ) {
18814
18854
  try {
18815
18855
  if (lstatSync3(parent).isSymbolicLink())
@@ -18818,12 +18858,12 @@ function writeFileAtomic(file, content, mode) {
18818
18858
  if (error.code !== "ENOENT")
18819
18859
  throw error;
18820
18860
  }
18821
- const next = path20.dirname(parent);
18861
+ const next = path21.dirname(parent);
18822
18862
  if (parent === root || next === parent)
18823
18863
  break;
18824
18864
  parent = next;
18825
18865
  }
18826
- const directory = path20.dirname(absolute);
18866
+ const directory = path21.dirname(absolute);
18827
18867
  mkdirSync4(directory, { recursive: true });
18828
18868
  let existing = null;
18829
18869
  try {
@@ -18863,7 +18903,7 @@ var init_safe_write = () => {};
18863
18903
  // packages/workit-core/src/autonomy.ts
18864
18904
  import { copyFileSync as copyFileSync3, existsSync as existsSync6 } from "node:fs";
18865
18905
  import os5 from "node:os";
18866
- import path21 from "node:path";
18906
+ import path22 from "node:path";
18867
18907
  function endpointOf(entry) {
18868
18908
  const raw = entry?.defaultEndpoint;
18869
18909
  if (raw === undefined)
@@ -19106,9 +19146,9 @@ var accountHome = () => {
19106
19146
  } catch {
19107
19147
  return os5.homedir();
19108
19148
  }
19109
- }, grantsHome, grantsDir = () => path21.join(grantsHome.resolve(), ".config", "workit"), grantsOverride = () => {
19110
- const configured = path21.resolve(resolveConfigDir());
19111
- return configured === path21.resolve(grantsDir()) ? null : `the config directory is redirected to ${configured} (WORKFLOW_TOOLKIT_CONFIG, WORKFLOW_TOOLKIT_CONFIG_DIR or XDG_CONFIG_HOME); grants are read only from ${path21.join(grantsDir(), "workspaces.json")}, so the D4 defaults apply`;
19149
+ }, grantsHome, grantsDir = () => path22.join(grantsHome.resolve(), ".config", "workit"), grantsOverride = () => {
19150
+ const configured = path22.resolve(resolveConfigDir());
19151
+ return configured === path22.resolve(grantsDir()) ? null : `the config directory is redirected to ${configured} (WORKFLOW_TOOLKIT_CONFIG, WORKFLOW_TOOLKIT_CONFIG_DIR or XDG_CONFIG_HOME); grants are read only from ${path22.join(grantsDir(), "workspaces.json")}, so the D4 defaults apply`;
19112
19152
  }, GRANT_KINDS, DEFAULT_GRANTS, DEFAULT_ENDPOINTS, DEFAULT_ENDPOINT = "commit", isDefaultEndpoint = (value) => typeof value === "string" && DEFAULT_ENDPOINTS.includes(value), raisesEndpoint = (current, next) => DEFAULT_ENDPOINTS.indexOf(next) > DEFAULT_ENDPOINTS.indexOf(current), DEFAULT_VERIFICATION = "self", verificationOf = (entry) => entry?.verification === "independent" ? "independent" : "self", isGrantKind = (value) => typeof value === "string" && GRANT_KINDS.includes(value), isGrantValue = (value) => value === true || value === false || value === "verified", normalized = (kind, value) => value === "verified" && kind !== "merge" ? true : value, fromAutoApprove = (value) => {
19113
19153
  if (value === true)
19114
19154
  return { push: true, pr: true, merge: "verified" };
@@ -20842,12 +20882,12 @@ var init_pr_body = __esm(() => {
20842
20882
  });
20843
20883
 
20844
20884
  // packages/workit-core/src/core/pr-create.ts
20845
- import path22 from "node:path";
20885
+ import path23 from "node:path";
20846
20886
  import { spawnSync as spawnSync11 } from "node:child_process";
20847
20887
  import { pathToFileURL } from "node:url";
20848
20888
  var safePushUrl = (remote) => {
20849
20889
  const raw = remote.trim();
20850
- if (path22.isAbsolute(raw))
20890
+ if (path23.isAbsolute(raw))
20851
20891
  return pathToFileURL(raw).href;
20852
20892
  if (!raw.includes("://")) {
20853
20893
  const scp = /^(?:([^@\s]+)@)?([^:]+):(.+)$/u.exec(raw);
@@ -20907,16 +20947,16 @@ var init_scripts = __esm(() => {
20907
20947
  });
20908
20948
 
20909
20949
  // packages/workit-core/src/core/youtrack.ts
20910
- import fs14 from "node:fs";
20911
- import path23 from "node:path";
20950
+ import fs15 from "node:fs";
20951
+ import path24 from "node:path";
20912
20952
  function readYouTrackConfig(required) {
20913
20953
  const cfgPath = youTrackConfigPath();
20914
- if (!fs14.existsSync(cfgPath)) {
20954
+ if (!fs15.existsSync(cfgPath)) {
20915
20955
  return required ? { error: "ERROR: missing youtrack.json", path: cfgPath } : { config: {}, path: cfgPath };
20916
20956
  }
20917
20957
  let parsed;
20918
20958
  try {
20919
- parsed = JSON.parse(fs14.readFileSync(cfgPath, "utf8"));
20959
+ parsed = JSON.parse(fs15.readFileSync(cfgPath, "utf8"));
20920
20960
  } catch {
20921
20961
  return { error: `${cfgPath} is not valid JSON`, path: cfgPath };
20922
20962
  }
@@ -20932,22 +20972,22 @@ function youTrackConfigLoad() {
20932
20972
  }
20933
20973
  const cfgPath = loaded.path;
20934
20974
  const tokenFile = String(loaded.config.tokenFile ?? "");
20935
- const tokenPath = tokenFile ? path23.isAbsolute(tokenFile) ? path23.resolve(tokenFile) : path23.resolve(process.cwd(), tokenFile) : "";
20936
- if (!tokenPath || !fs14.existsSync(tokenPath)) {
20975
+ const tokenPath = tokenFile ? path24.isAbsolute(tokenFile) ? path24.resolve(tokenFile) : path24.resolve(process.cwd(), tokenFile) : "";
20976
+ if (!tokenPath || !fs15.existsSync(tokenPath)) {
20937
20977
  return { error: "missing youtrack.token" };
20938
20978
  }
20939
20979
  if (!youTrackTokenModeOk(tokenPath)) {
20940
20980
  return { error: "youtrack.token mode must be 0600" };
20941
20981
  }
20942
- const token = fs14.readFileSync(tokenPath, "utf8").trim();
20982
+ const token = fs15.readFileSync(tokenPath, "utf8").trim();
20943
20983
  if (!token || token === TOKEN_PLACEHOLDER || token.startsWith(TOKEN_PLACEHOLDER)) {
20944
20984
  return { error: "token file still placeholder — edit locally, then /wk-status" };
20945
20985
  }
20946
20986
  const redacted = { ...loaded.config };
20947
20987
  delete redacted.tokenFile;
20948
20988
  redacted.tokenPresent = true;
20949
- redacted.configPath = path23.resolve(cfgPath);
20950
- redacted.tokenPath = path23.resolve(tokenPath);
20989
+ redacted.configPath = path24.resolve(cfgPath);
20990
+ redacted.tokenPath = path24.resolve(tokenPath);
20951
20991
  return { data: redacted };
20952
20992
  }
20953
20993
  function tzParts(date, tz) {
@@ -20976,10 +21016,10 @@ function youTrackParseDuration(text) {
20976
21016
  function youTrackWorkDateMs(dateRaw) {
20977
21017
  const cfgPath = youTrackConfigPath();
20978
21018
  let effective = effectiveWorkTimezone(null);
20979
- if (fs14.existsSync(cfgPath)) {
21019
+ if (fs15.existsSync(cfgPath)) {
20980
21020
  let parsed;
20981
21021
  try {
20982
- parsed = JSON.parse(fs14.readFileSync(cfgPath, "utf8"));
21022
+ parsed = JSON.parse(fs15.readFileSync(cfgPath, "utf8"));
20983
21023
  } catch {
20984
21024
  return { error: `${cfgPath} is not valid JSON` };
20985
21025
  }
@@ -21119,9 +21159,9 @@ function resolveYouTrackFromPaths(spec_path, plan_path, workspace_root) {
21119
21159
  } catch {
21120
21160
  continue;
21121
21161
  }
21122
- if (!fs14.existsSync(full))
21162
+ if (!fs15.existsSync(full))
21123
21163
  continue;
21124
- const text = fs14.readFileSync(full, "utf8");
21164
+ const text = fs15.readFileSync(full, "utf8");
21125
21165
  const m = text.match(/^\*\*YouTrack:\*\*\s*`?([A-Z]+-\d+)`?/m);
21126
21166
  if (m)
21127
21167
  return m[1];
@@ -21270,18 +21310,18 @@ async function postUpdate({
21270
21310
  }
21271
21311
  return { ok: true, issueId, postedComment: true };
21272
21312
  }
21273
- var ISSUE_RE, TOKEN_PLACEHOLDER = "YOUR_TOKEN_HERE", youTrackConfigPath = () => process.env.WORKFLOW_YOUTRACK_CONFIG ?? path23.join(configDir(), "youtrack.json"), youTrackReadOnlyConfigPath = () => process.env.WORKFLOW_YOUTRACK_CONFIG ?? path23.join(resolveConfigDir(), "youtrack.json"), youTrackTokenModeOk = (p) => {
21313
+ var ISSUE_RE, TOKEN_PLACEHOLDER = "YOUR_TOKEN_HERE", youTrackConfigPath = () => process.env.WORKFLOW_YOUTRACK_CONFIG ?? path24.join(configDir(), "youtrack.json"), youTrackReadOnlyConfigPath = () => process.env.WORKFLOW_YOUTRACK_CONFIG ?? path24.join(resolveConfigDir(), "youtrack.json"), youTrackTokenModeOk = (p) => {
21274
21314
  if (process.platform === "win32")
21275
21315
  return true;
21276
- const mode = fs14.statSync(p).mode & 511;
21316
+ const mode = fs15.statSync(p).mode & 511;
21277
21317
  return mode === 384;
21278
21318
  }, readYouTrackContextConfig = () => {
21279
21319
  const cfgPath = youTrackReadOnlyConfigPath();
21280
- if (!fs14.existsSync(cfgPath))
21320
+ if (!fs15.existsSync(cfgPath))
21281
21321
  return { data: {} };
21282
21322
  let parsed;
21283
21323
  try {
21284
- parsed = JSON.parse(fs14.readFileSync(cfgPath, "utf8"));
21324
+ parsed = JSON.parse(fs15.readFileSync(cfgPath, "utf8"));
21285
21325
  } catch {
21286
21326
  return { error: "YouTrack configuration is unavailable" };
21287
21327
  }
@@ -21312,12 +21352,12 @@ var ISSUE_RE, TOKEN_PLACEHOLDER = "YOUR_TOKEN_HERE", youTrackConfigPath = () =>
21312
21352
  if ("error" in loaded)
21313
21353
  return loaded;
21314
21354
  const tokenFile = String(loaded.config.tokenFile ?? "");
21315
- const tokenPath = tokenFile ? path23.isAbsolute(tokenFile) ? path23.resolve(tokenFile) : path23.resolve(process.cwd(), tokenFile) : "";
21316
- if (!tokenPath || !fs14.existsSync(tokenPath))
21355
+ const tokenPath = tokenFile ? path24.isAbsolute(tokenFile) ? path24.resolve(tokenFile) : path24.resolve(process.cwd(), tokenFile) : "";
21356
+ if (!tokenPath || !fs15.existsSync(tokenPath))
21317
21357
  return { error: "missing youtrack.token" };
21318
21358
  if (!youTrackTokenModeOk(tokenPath))
21319
21359
  return { error: "youtrack.token mode must be 0600" };
21320
- const token = fs14.readFileSync(tokenPath, "utf8").trim();
21360
+ const token = fs15.readFileSync(tokenPath, "utf8").trim();
21321
21361
  if (!token)
21322
21362
  return { error: "empty token file" };
21323
21363
  if (token === TOKEN_PLACEHOLDER || token.startsWith(TOKEN_PLACEHOLDER)) {
@@ -21417,18 +21457,18 @@ var init_context_read = __esm(() => {
21417
21457
 
21418
21458
  // packages/workit-core/src/core.ts
21419
21459
  import { existsSync as existsSync7, realpathSync as realpathSync5 } from "node:fs";
21420
- import path24 from "node:path";
21460
+ import path25 from "node:path";
21421
21461
  function resolveInside(root, candidate) {
21422
21462
  const base = realpathSync5(root);
21423
- const target = path24.resolve(base, candidate);
21424
- if (target !== base && !target.startsWith(base + path24.sep)) {
21463
+ const target = path25.resolve(base, candidate);
21464
+ if (target !== base && !target.startsWith(base + path25.sep)) {
21425
21465
  throw new Error("path must stay inside repository root");
21426
21466
  }
21427
21467
  let ancestor = target;
21428
21468
  while (!existsSync7(ancestor))
21429
- ancestor = path24.dirname(ancestor);
21469
+ ancestor = path25.dirname(ancestor);
21430
21470
  const canonicalAncestor = realpathSync5(ancestor);
21431
- if (canonicalAncestor !== base && !canonicalAncestor.startsWith(base + path24.sep)) {
21471
+ if (canonicalAncestor !== base && !canonicalAncestor.startsWith(base + path25.sep)) {
21432
21472
  throw new Error("path must stay inside repository root");
21433
21473
  }
21434
21474
  return target;
@@ -21454,7 +21494,7 @@ var init_core3 = __esm(() => {
21454
21494
 
21455
21495
  // packages/workit-cli/src/task.ts
21456
21496
  import { readFileSync as readFileSync7 } from "node:fs";
21457
- import path25 from "node:path";
21497
+ import path26 from "node:path";
21458
21498
  async function readInput(input) {
21459
21499
  if (typeof input === "string")
21460
21500
  return input;
@@ -21781,7 +21821,7 @@ var TASK_FAMILIES, workspaceRootFor = (deps = {}) => {
21781
21821
  return explicit;
21782
21822
  const cwd = deps.cwd ?? process.cwd();
21783
21823
  const top = checkRoot(cwd);
21784
- return sameDirectoryIdentity(top, path25.resolve(cwd)) ? cwd : top;
21824
+ return sameDirectoryIdentity(top, path26.resolve(cwd)) ? cwd : top;
21785
21825
  }, TASK_ACTIONS, outOf = (deps) => deps.out ?? process.stdout, errOf = (deps) => deps.err ?? process.stderr, write = (stream, value) => stream.write(value.endsWith(`
21786
21826
  `) ? value : `${value}
21787
21827
  `), jsonResult = (stream, result) => write(stream, JSON.stringify(result)), usage = (message) => failure2("invalid_input", message), parseUsage = (message, json) => ({
@@ -25834,7 +25874,7 @@ var init_wrap_ansi = __esm(() => {
25834
25874
  // node_modules/terminal-size/index.js
25835
25875
  import process3 from "node:process";
25836
25876
  import { execFileSync as execFileSync2 } from "node:child_process";
25837
- import fs15 from "node:fs";
25877
+ import fs16 from "node:fs";
25838
25878
  import tty from "node:tty";
25839
25879
  function terminalSize() {
25840
25880
  const { env, stdout, stderr } = process3;
@@ -25882,7 +25922,7 @@ var defaultColumns = 80, defaultRows = 24, exec2 = (command, arguments_, { shell
25882
25922
  return true;
25883
25923
  }
25884
25924
  try {
25885
- const statContents = fs15.readFileSync("/proc/self/stat", "utf8");
25925
+ const statContents = fs16.readFileSync("/proc/self/stat", "utf8");
25886
25926
  const closingParenthesisIndex = statContents.lastIndexOf(") ");
25887
25927
  if (closingParenthesisIndex === -1) {
25888
25928
  return false;
@@ -25902,8 +25942,8 @@ var defaultColumns = 80, defaultRows = 24, exec2 = (command, arguments_, { shell
25902
25942
  }
25903
25943
  }, devTty = () => {
25904
25944
  try {
25905
- const flags = process3.platform === "darwin" ? fs15.constants.O_EVTONLY | fs15.constants.O_NONBLOCK : fs15.constants.O_NONBLOCK;
25906
- const { columns, rows } = tty.WriteStream(fs15.openSync("/dev/tty", flags));
25945
+ const flags = process3.platform === "darwin" ? fs16.constants.O_EVTONLY | fs16.constants.O_NONBLOCK : fs16.constants.O_NONBLOCK;
25946
+ const { columns, rows } = tty.WriteStream(fs16.openSync("/dev/tty", flags));
25907
25947
  return { columns, rows };
25908
25948
  } catch {}
25909
25949
  }, tput = () => {
@@ -61016,7 +61056,7 @@ var init_Text = __esm(() => {
61016
61056
  });
61017
61057
 
61018
61058
  // node_modules/ink/build/components/ErrorOverview.js
61019
- import * as fs16 from "node:fs";
61059
+ import * as fs17 from "node:fs";
61020
61060
  import { cwd } from "node:process";
61021
61061
  function ErrorOverview({ error }) {
61022
61062
  const stack = error.stack ? error.stack.split(`
@@ -61026,8 +61066,8 @@ function ErrorOverview({ error }) {
61026
61066
  let excerpt;
61027
61067
  let lineWidth = 0;
61028
61068
  const stackLineCounts = new Map;
61029
- if (filePath && origin?.line && fs16.existsSync(filePath)) {
61030
- const sourceCode = fs16.readFileSync(filePath, "utf8");
61069
+ if (filePath && origin?.line && fs17.existsSync(filePath)) {
61070
+ const sourceCode = fs17.readFileSync(filePath, "utf8");
61031
61071
  excerpt = dist_default3(sourceCode, origin.line);
61032
61072
  if (excerpt) {
61033
61073
  for (const { line } of excerpt) {
@@ -64692,8 +64732,8 @@ var init_gitignore = __esm(() => {
64692
64732
  });
64693
64733
 
64694
64734
  // packages/workit-core/src/core/changelog.ts
64695
- import fs17 from "node:fs";
64696
- import path26 from "node:path";
64735
+ import fs18 from "node:fs";
64736
+ import path27 from "node:path";
64697
64737
  import { createHash as createHash13 } from "node:crypto";
64698
64738
  function normalizeBullet(text) {
64699
64739
  text = text.trim();
@@ -64853,8 +64893,8 @@ function applyChangelog(target, entries, normalizeOnly) {
64853
64893
  const rendered = renderChangelog(source.text, entries, normalizeOnly);
64854
64894
  if ("error" in rendered)
64855
64895
  return { error: rendered.error };
64856
- fs17.mkdirSync(path26.dirname(target), { recursive: true });
64857
- fs17.writeFileSync(target, rendered.text, "utf8");
64896
+ fs18.mkdirSync(path27.dirname(target), { recursive: true });
64897
+ fs18.writeFileSync(target, rendered.text, "utf8");
64858
64898
  return { ...rendered.result, path: target };
64859
64899
  }
64860
64900
  function renderChangelog(source, entries, normalizeOnly) {
@@ -64982,12 +65022,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
64982
65022
  ## [Unreleased]
64983
65023
 
64984
65024
  `, digestBytes2 = (value) => createHash13("sha256").update(value).digest("hex"), readChangelogSource = (target) => {
64985
- if (!fs17.existsSync(target)) {
65025
+ if (!fs18.existsSync(target)) {
64986
65026
  const bytes = Buffer.from(SKELETON, "utf8");
64987
65027
  return { exists: false, bytes, text: SKELETON };
64988
65028
  }
64989
65029
  try {
64990
- const bytes = fs17.readFileSync(target);
65030
+ const bytes = fs18.readFileSync(target);
64991
65031
  const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
64992
65032
  return { exists: true, bytes, text };
64993
65033
  } catch {
@@ -64995,17 +65035,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
64995
65035
  }
64996
65036
  }, changelogTarget = (workspaceRoot, changelogPath) => {
64997
65037
  try {
64998
- const cwd = fs17.realpathSync(resolveWorkspaceRoot(workspaceRoot));
64999
- const target = path26.resolve(cwd, changelogPath || "CHANGELOG.md");
65000
- if (target !== cwd && !target.startsWith(cwd + path26.sep))
65038
+ const cwd = fs18.realpathSync(resolveWorkspaceRoot(workspaceRoot));
65039
+ const target = path27.resolve(cwd, changelogPath || "CHANGELOG.md");
65040
+ if (target !== cwd && !target.startsWith(cwd + path27.sep))
65001
65041
  return { error: "changelog path must be inside workspace_root" };
65002
65042
  let ancestor = target;
65003
- while (!fs17.existsSync(ancestor))
65004
- ancestor = path26.dirname(ancestor);
65005
- const canonicalAncestor = fs17.realpathSync(ancestor);
65006
- if (canonicalAncestor !== cwd && !canonicalAncestor.startsWith(cwd + path26.sep))
65043
+ while (!fs18.existsSync(ancestor))
65044
+ ancestor = path27.dirname(ancestor);
65045
+ const canonicalAncestor = fs18.realpathSync(ancestor);
65046
+ if (canonicalAncestor !== cwd && !canonicalAncestor.startsWith(cwd + path27.sep))
65007
65047
  return { error: "changelog path must be inside workspace_root" };
65008
- return { cwd, target: fs17.existsSync(target) ? fs17.realpathSync(target) : target };
65048
+ return { cwd, target: fs18.existsSync(target) ? fs18.realpathSync(target) : target };
65009
65049
  } catch {
65010
65050
  return { error: "changelog path must be inside workspace_root" };
65011
65051
  }
@@ -65023,22 +65063,22 @@ var init_changelog = __esm(() => {
65023
65063
  // packages/workit-core/src/core/hygiene.ts
65024
65064
  import { spawnSync as spawnSync12 } from "node:child_process";
65025
65065
  import { existsSync as existsSync9, readFileSync as readFileSync9, readdirSync as readdirSync5, writeFileSync as writeFileSync4 } from "node:fs";
65026
- import path27 from "node:path";
65027
- var repoRoot2, templatesDir = () => path27.join(repoRoot2, "templates", "hygiene"), packageJson = (root) => {
65028
- if (!existsSync9(path27.join(root, "package.json")))
65066
+ import path28 from "node:path";
65067
+ var repoRoot2, templatesDir = () => path28.join(repoRoot2, "templates", "hygiene"), packageJson = (root) => {
65068
+ if (!existsSync9(path28.join(root, "package.json")))
65029
65069
  return null;
65030
65070
  try {
65031
- return JSON.parse(readFileSync9(path27.join(root, "package.json"), "utf8"));
65071
+ return JSON.parse(readFileSync9(path28.join(root, "package.json"), "utf8"));
65032
65072
  } catch {
65033
65073
  return null;
65034
65074
  }
65035
65075
  }, isOpenSource = (root) => {
65036
- if (existsSync9(path27.join(root, "LICENSE")))
65076
+ if (existsSync9(path28.join(root, "LICENSE")))
65037
65077
  return true;
65038
65078
  const pkg = packageJson(root);
65039
65079
  if (pkg && !pkg.private)
65040
65080
  return true;
65041
- return path27.basename(root) === "workflow-toolkit";
65081
+ return path28.basename(root) === "workflow-toolkit";
65042
65082
  }, licenseHolder = (root) => {
65043
65083
  const pkg = packageJson(root);
65044
65084
  if (pkg) {
@@ -65053,14 +65093,14 @@ var repoRoot2, templatesDir = () => path27.join(repoRoot2, "templates", "hygiene
65053
65093
  }
65054
65094
  return "";
65055
65095
  }, projectTarget = (dir) => {
65056
- const start = path27.resolve(dir);
65096
+ const start = path28.resolve(dir);
65057
65097
  const top = spawnSync12("git", ["rev-parse", "--show-toplevel"], { cwd: start, encoding: "utf8" });
65058
65098
  const root = top.status === 0 ? (top.stdout ?? "").trim() : "";
65059
65099
  if (root)
65060
- return { ok: true, root: path27.resolve(root) };
65100
+ return { ok: true, root: path28.resolve(root) };
65061
65101
  let children = [];
65062
65102
  try {
65063
- children = readdirSync5(start, { withFileTypes: true }).filter((entry) => entry.isDirectory() && existsSync9(path27.join(start, entry.name, ".git"))).map((entry) => path27.join(start, entry.name)).toSorted();
65103
+ children = readdirSync5(start, { withFileTypes: true }).filter((entry) => entry.isDirectory() && existsSync9(path28.join(start, entry.name, ".git"))).map((entry) => path28.join(start, entry.name)).toSorted();
65064
65104
  } catch {
65065
65105
  children = [];
65066
65106
  }
@@ -65076,13 +65116,13 @@ var repoRoot2, templatesDir = () => path27.join(repoRoot2, "templates", "hygiene
65076
65116
  files.push("LICENSE", "CONTRIBUTING.md");
65077
65117
  const planned = [];
65078
65118
  for (const file of files) {
65079
- if (existsSync9(path27.join(root, file)))
65119
+ if (existsSync9(path28.join(root, file)))
65080
65120
  continue;
65081
- const tpl = path27.join(templatesDir(), file);
65121
+ const tpl = path28.join(templatesDir(), file);
65082
65122
  if (!existsSync9(tpl))
65083
65123
  continue;
65084
- const content = readFileSync9(tpl, "utf8").replace(/<PROJECT>/g, path27.basename(root)).replace(/<YEAR>/g, String(new Date().getFullYear())).replace(/<HOLDER>\s*/g, licenseHolder(root));
65085
- planned.push({ path: path27.join(root, file), content });
65124
+ const content = readFileSync9(tpl, "utf8").replace(/<PROJECT>/g, path28.basename(root)).replace(/<YEAR>/g, String(new Date().getFullYear())).replace(/<HOLDER>\s*/g, licenseHolder(root));
65125
+ planned.push({ path: path28.join(root, file), content });
65086
65126
  }
65087
65127
  return planned;
65088
65128
  };
@@ -65094,9 +65134,9 @@ var init_hygiene = __esm(() => {
65094
65134
 
65095
65135
  // packages/workit-cli/src/admin/setup-state.ts
65096
65136
  import { existsSync as existsSync10, readFileSync as readFileSync10 } from "node:fs";
65097
- import path28 from "node:path";
65137
+ import path29 from "node:path";
65098
65138
  var classifySetupFile = (dir, name) => {
65099
- const file = path28.join(dir, name);
65139
+ const file = path29.join(dir, name);
65100
65140
  let raw;
65101
65141
  try {
65102
65142
  raw = readFileSync10(file, "utf8");
@@ -65134,7 +65174,7 @@ var init_setup_state = __esm(() => {
65134
65174
  });
65135
65175
 
65136
65176
  // packages/workit-cli/src/admin/registration.ts
65137
- import path29 from "node:path";
65177
+ import path30 from "node:path";
65138
65178
  function isWorkitPlugin(value) {
65139
65179
  const s = String(value).replaceAll("\\", "/");
65140
65180
  const url = s.startsWith("file://") || s.startsWith("git+file://");
@@ -65167,11 +65207,11 @@ function mergeCursorEnabledPlugins(enabled) {
65167
65207
  }
65168
65208
  function mergeCursorPluginDirs(pluginDirs, pluginDir) {
65169
65209
  const strip = (p) => {
65170
- const j = path29.join(p);
65171
- return path29.dirname(j) === j ? j : j.replace(/[\\/]+$/, "");
65210
+ const j = path30.join(p);
65211
+ return path30.dirname(j) === j ? j : j.replace(/[\\/]+$/, "");
65172
65212
  };
65173
65213
  const normalized = strip(pluginDir);
65174
- const legacy = strip(path29.join(path29.dirname(pluginDir), "workflow-toolkit"));
65214
+ const legacy = strip(path30.join(path30.dirname(pluginDir), "workflow-toolkit"));
65175
65215
  const prev = Array.isArray(pluginDirs) ? pluginDirs.map(String) : [];
65176
65216
  const kept = prev.filter((d) => strip(d) !== legacy);
65177
65217
  const exists = kept.some((d) => strip(d) === normalized);
@@ -65259,7 +65299,7 @@ function cursorMcpServerEntry(_packageDir) {
65259
65299
  function cursorHooksEntry(pluginDir) {
65260
65300
  return { command: `${cursorHookLauncher(pluginDir)} workit-cursor-session-start`, args: [] };
65261
65301
  }
65262
- var OPENCODE_NPM_PIN = "@brainervirus/workit-opencode", isRecord4 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), named = (s, name) => s === name || s.startsWith(`${name}@`), CURSOR_RUNTIME_PACKAGE = "@brainervirus/workit-cursor@latest", cursorHookLauncher = (pluginDir) => pluginDir ? `node "${shellQuotedPath(path29.join(pluginDir, "hooks", "launch.mjs"))}"` : 'node "${CURSOR_PLUGIN_ROOT}/hooks/launch.mjs"', shellQuotedPath = (file) => path29.sep === "\\" ? file : file.replace(/([$`"\\])/g, "\\$1"), CURSOR_HOOK_RUN_COMMAND, CURSOR_PRETOOLUSE_MATCHER = "Write|Edit|Delete|Shell|Remove|ApplyPatch|Apply_Patch|Patch|Rename|Mkdir|Mv|Cp|Touch", CURSOR_HOOK_EVENTS, canonicalHookEntry = (event, pluginDir) => {
65302
+ var OPENCODE_NPM_PIN = "@brainervirus/workit-opencode", isRecord4 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), named = (s, name) => s === name || s.startsWith(`${name}@`), CURSOR_RUNTIME_PACKAGE = "@brainervirus/workit-cursor@latest", cursorHookLauncher = (pluginDir) => pluginDir ? `node "${shellQuotedPath(path30.join(pluginDir, "hooks", "launch.mjs"))}"` : 'node "${CURSOR_PLUGIN_ROOT}/hooks/launch.mjs"', shellQuotedPath = (file) => path30.sep === "\\" ? file : file.replace(/([$`"\\])/g, "\\$1"), CURSOR_HOOK_RUN_COMMAND, CURSOR_PRETOOLUSE_MATCHER = "Write|Edit|Delete|Shell|Remove|ApplyPatch|Apply_Patch|Patch|Rename|Mkdir|Mv|Cp|Touch", CURSOR_HOOK_EVENTS, canonicalHookEntry = (event, pluginDir) => {
65263
65303
  const command = `${cursorHookLauncher(pluginDir)} workit-cursor-hook`;
65264
65304
  if (event === "preToolUse")
65265
65305
  return { command, matcher: CURSOR_PRETOOLUSE_MATCHER, failClosed: false };
@@ -65294,8 +65334,8 @@ var init_support_matrix = __esm(() => {
65294
65334
 
65295
65335
  // packages/workit-core/src/core/heavy-scope.ts
65296
65336
  import { spawnSync as spawnSync13 } from "node:child_process";
65297
- import fs18 from "node:fs";
65298
- import path30 from "node:path";
65337
+ import fs19 from "node:fs";
65338
+ import path31 from "node:path";
65299
65339
  function scopeSupport(env, platform = process.platform, read = readText2) {
65300
65340
  if (platform !== "linux")
65301
65341
  return { ok: false, reason: `no systemd scopes on ${platform}` };
@@ -65303,7 +65343,7 @@ function scopeSupport(env, platform = process.platform, read = readText2) {
65303
65343
  return { ok: false, reason: "systemd-run is not on PATH" };
65304
65344
  const uid = process.getuid?.() ?? 0;
65305
65345
  const runtime = env.XDG_RUNTIME_DIR || `/run/user/${uid}`;
65306
- if (!fs18.existsSync(path30.join(runtime, "systemd", "private")))
65346
+ if (!fs19.existsSync(path31.join(runtime, "systemd", "private")))
65307
65347
  return { ok: false, reason: "no user systemd manager is running" };
65308
65348
  const controllers = read(`/sys/fs/cgroup/user.slice/user-${uid}.slice/user@${uid}.service/cgroup.controllers`);
65309
65349
  if (controllers === null)
@@ -65366,13 +65406,13 @@ function probeScope(env = process.env) {
65366
65406
  }
65367
65407
  var readText2 = (file) => {
65368
65408
  try {
65369
- return fs18.readFileSync(file, "utf8");
65409
+ return fs19.readFileSync(file, "utf8");
65370
65410
  } catch {
65371
65411
  return null;
65372
65412
  }
65373
- }, onPath = (command, env) => (env.PATH ?? "").split(path30.delimiter).filter(Boolean).some((dir) => {
65413
+ }, onPath = (command, env) => (env.PATH ?? "").split(path31.delimiter).filter(Boolean).some((dir) => {
65374
65414
  try {
65375
- fs18.accessSync(path30.join(dir, command), fs18.constants.X_OK);
65415
+ fs19.accessSync(path31.join(dir, command), fs19.constants.X_OK);
65376
65416
  return true;
65377
65417
  } catch {
65378
65418
  return false;
@@ -65392,7 +65432,7 @@ import {
65392
65432
  statSync as statSync2
65393
65433
  } from "node:fs";
65394
65434
  import os8 from "node:os";
65395
- import path31 from "node:path";
65435
+ import path32 from "node:path";
65396
65436
  function hostCommand(name, args, options = {}) {
65397
65437
  const executable = findHostExecutable(name, options);
65398
65438
  if (!executable)
@@ -65409,11 +65449,11 @@ function hostCommand(name, args, options = {}) {
65409
65449
  return { command: executable, args, cwd: options.cwd, purpose: `${name} CLI` };
65410
65450
  }
65411
65451
  function resolveWindowsShimEntry(contents, shim, exists = existsSync11) {
65412
- const root = path31.win32.dirname(shim);
65452
+ const root = path32.win32.dirname(shim);
65413
65453
  const matches = contents.matchAll(/(["']?)([^\r\n"']*node_modules[\\/][^\r\n"']+?\.js)\1/gi);
65414
65454
  for (const match of matches) {
65415
65455
  const raw = match[2].replace(/%~?dp0%?/gi, root);
65416
- const candidate = path31.win32.isAbsolute(raw) ? raw : path31.win32.resolve(root, raw);
65456
+ const candidate = path32.win32.isAbsolute(raw) ? raw : path32.win32.resolve(root, raw);
65417
65457
  if (exists(candidate))
65418
65458
  return candidate;
65419
65459
  }
@@ -65423,22 +65463,22 @@ function findHostExecutable(name, options = {}) {
65423
65463
  const env = options.env ?? process.env;
65424
65464
  const home = options.home ?? env.HOME ?? os8.homedir();
65425
65465
  const suffixes = process.platform === "win32" ? ["", ".exe", ".cmd", ".bat"] : [""];
65426
- const dirs = (env.PATH ?? "").split(path31.delimiter).filter(Boolean);
65427
- dirs.push(path31.join(home, ".local", "bin"), path31.join(home, ".asdf", "shims"));
65466
+ const dirs = (env.PATH ?? "").split(path32.delimiter).filter(Boolean);
65467
+ dirs.push(path32.join(home, ".local", "bin"), path32.join(home, ".asdf", "shims"));
65428
65468
  for (const [base, tail] of [
65429
- [path31.join(home, ".local", "share", "fnm", "node-versions"), path31.join("installation", "bin")],
65430
- [path31.join(home, ".nvm", "versions", "node"), "bin"]
65469
+ [path32.join(home, ".local", "share", "fnm", "node-versions"), path32.join("installation", "bin")],
65470
+ [path32.join(home, ".nvm", "versions", "node"), "bin"]
65431
65471
  ]) {
65432
65472
  try {
65433
65473
  for (const entry of readdirSync6(base, { withFileTypes: true })) {
65434
65474
  if (entry.isDirectory())
65435
- dirs.push(path31.join(base, entry.name, tail));
65475
+ dirs.push(path32.join(base, entry.name, tail));
65436
65476
  }
65437
65477
  } catch {}
65438
65478
  }
65439
65479
  for (const dir of dirs) {
65440
65480
  for (const suffix of suffixes) {
65441
- const candidate = path31.join(dir, `${name}${suffix}`);
65481
+ const candidate = path32.join(dir, `${name}${suffix}`);
65442
65482
  try {
65443
65483
  if (statSync2(candidate).isFile()) {
65444
65484
  if (process.platform === "win32")
@@ -65453,7 +65493,7 @@ function findHostExecutable(name, options = {}) {
65453
65493
  }
65454
65494
  function installedHostApp(host, home, env = process.env, platform = process.platform, exists = existsSync11) {
65455
65495
  const candidates = [];
65456
- const pathApi = platform === "win32" ? path31.win32 : path31;
65496
+ const pathApi = platform === "win32" ? path32.win32 : path32;
65457
65497
  if (platform === "darwin") {
65458
65498
  const app = host === "cursor" ? "Cursor.app" : host === "codex" ? "Codex.app" : host === "opencode" ? "OpenCode.app" : "";
65459
65499
  if (app)
@@ -65558,8 +65598,8 @@ function planHostInstall(host, options = {}) {
65558
65598
  const npmCli = npm ? findNpmCli(npm) : null;
65559
65599
  if (!npmCli)
65560
65600
  throw new Error("npm CLI could not be resolved; install Node.js 24+ and npm, then retry");
65561
- const stage = path31.join(home, ".cursor", "plugins", "local", ".workit-package-bootstrap");
65562
- const target = options.targetDir ?? path31.join(home, ".cursor", "plugins", "local", "workit");
65601
+ const stage = path32.join(home, ".cursor", "plugins", "local", ".workit-package-bootstrap");
65602
+ const target = options.targetDir ?? path32.join(home, ".cursor", "plugins", "local", "workit");
65563
65603
  return [
65564
65604
  nodePrerequisite({ home, cwd, env }),
65565
65605
  {
@@ -65575,7 +65615,7 @@ function planHostInstall(host, options = {}) {
65575
65615
  ],
65576
65616
  cwd,
65577
65617
  purpose: upgrading ? "Download the current Workit Cursor adapter for the managed local plugin directory" : "Download the Workit Cursor adapter package for the managed local plugin directory",
65578
- packageRoot: path31.join(stage, "node_modules", "@brainervirus", "workit-cursor"),
65618
+ packageRoot: path32.join(stage, "node_modules", "@brainervirus", "workit-cursor"),
65579
65619
  packageTarget: target
65580
65620
  }
65581
65621
  ];
@@ -65657,10 +65697,10 @@ function runHostCommand(step, context = {}) {
65657
65697
  env: (() => {
65658
65698
  const home = context.home ?? context.env?.HOME ?? os8.homedir();
65659
65699
  const env = { ...process.env, ...context.env, HOME: home };
65660
- env.CODEX_HOME = context.env?.CODEX_HOME ?? path31.join(home, ".codex");
65661
- env.PI_CODING_AGENT_DIR = context.env?.PI_CODING_AGENT_DIR ?? path31.join(home, ".pi", "agent");
65662
- env.CLAUDE_CONFIG_DIR = context.env?.CLAUDE_CONFIG_DIR ?? path31.join(home, ".claude");
65663
- env.XDG_CONFIG_HOME = context.env?.XDG_CONFIG_HOME ?? path31.join(home, ".config");
65700
+ env.CODEX_HOME = context.env?.CODEX_HOME ?? path32.join(home, ".codex");
65701
+ env.PI_CODING_AGENT_DIR = context.env?.PI_CODING_AGENT_DIR ?? path32.join(home, ".pi", "agent");
65702
+ env.CLAUDE_CONFIG_DIR = context.env?.CLAUDE_CONFIG_DIR ?? path32.join(home, ".claude");
65703
+ env.XDG_CONFIG_HOME = context.env?.XDG_CONFIG_HOME ?? path32.join(home, ".config");
65664
65704
  return env;
65665
65705
  })(),
65666
65706
  encoding: "utf8",
@@ -65695,7 +65735,7 @@ var resolveWindowsShimScript = (shim) => {
65695
65735
  purpose: "Check the Node.js 24+ package runtime requirement"
65696
65736
  };
65697
65737
  }, isPiWorkitInstalled = (home, env = process.env) => {
65698
- const settings = path31.join(env.PI_CODING_AGENT_DIR ?? path31.join(home, ".pi", "agent"), "settings.json");
65738
+ const settings = path32.join(env.PI_CODING_AGENT_DIR ?? path32.join(home, ".pi", "agent"), "settings.json");
65699
65739
  try {
65700
65740
  const document2 = JSON.parse(readFileSync11(settings, "utf8"));
65701
65741
  return (document2.packages ?? []).some((entry) => {
@@ -65708,7 +65748,7 @@ var resolveWindowsShimScript = (shim) => {
65708
65748
  }
65709
65749
  }, OPENCODE_PLUGIN_SCOPE = "@brainervirus", OPENCODE_PLUGIN_NAME = "workit-opencode", packageVersionAt = (root, name) => {
65710
65750
  try {
65711
- const pkg = JSON.parse(readFileSync11(path31.join(root, "package.json"), "utf8"));
65751
+ const pkg = JSON.parse(readFileSync11(path32.join(root, "package.json"), "utf8"));
65712
65752
  return pkg.name === name && typeof pkg.version === "string" ? pkg.version : null;
65713
65753
  } catch {
65714
65754
  return null;
@@ -65722,17 +65762,17 @@ var resolveWindowsShimScript = (shim) => {
65722
65762
  return d;
65723
65763
  }
65724
65764
  return 0;
65725
- }, openCodeCacheDir = (home, env = process.env) => path31.join(env.XDG_CACHE_HOME || path31.join(home, ".cache"), "opencode"), subdirs = (dir) => {
65765
+ }, openCodeCacheDir = (home, env = process.env) => path32.join(env.XDG_CACHE_HOME || path32.join(home, ".cache"), "opencode"), subdirs = (dir) => {
65726
65766
  try {
65727
- return readdirSync6(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path31.join(dir, entry.name));
65767
+ return readdirSync6(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path32.join(dir, entry.name));
65728
65768
  } catch {
65729
65769
  return [];
65730
65770
  }
65731
65771
  }, openCodeInstalledPlugin = (home, env = process.env) => {
65732
65772
  const name = `${OPENCODE_PLUGIN_SCOPE}/${OPENCODE_PLUGIN_NAME}`;
65733
65773
  const cache = openCodeCacheDir(home, env);
65734
- const specDirs = (layout) => subdirs(path31.join(cache, layout, OPENCODE_PLUGIN_SCOPE)).filter((dir) => path31.basename(dir) === `${OPENCODE_PLUGIN_NAME}@latest`);
65735
- const installs = [...specDirs("npm").flatMap(subdirs), ...specDirs("packages")].map((dir) => path31.join(dir, "node_modules", OPENCODE_PLUGIN_SCOPE, OPENCODE_PLUGIN_NAME));
65774
+ const specDirs = (layout) => subdirs(path32.join(cache, layout, OPENCODE_PLUGIN_SCOPE)).filter((dir) => path32.basename(dir) === `${OPENCODE_PLUGIN_NAME}@latest`);
65775
+ const installs = [...specDirs("npm").flatMap(subdirs), ...specDirs("packages")].map((dir) => path32.join(dir, "node_modules", OPENCODE_PLUGIN_SCOPE, OPENCODE_PLUGIN_NAME));
65736
65776
  let best = null;
65737
65777
  for (const root of installs) {
65738
65778
  const version = packageVersionAt(root, name);
@@ -65742,8 +65782,8 @@ var resolveWindowsShimScript = (shim) => {
65742
65782
  return best;
65743
65783
  }, isCanonicalCodexPackage = (root) => {
65744
65784
  for (const file of [
65745
- path31.join(root, ".codex-plugin", "plugin.json"),
65746
- path31.join(root, "package.json")
65785
+ path32.join(root, ".codex-plugin", "plugin.json"),
65786
+ path32.join(root, "package.json")
65747
65787
  ]) {
65748
65788
  try {
65749
65789
  const manifest = JSON.parse(readFileSync11(file, "utf8"));
@@ -65754,47 +65794,47 @@ var resolveWindowsShimScript = (shim) => {
65754
65794
  }
65755
65795
  return false;
65756
65796
  }, isCodexWorkitInstalled = (home, env = process.env) => {
65757
- const codexHome = env.CODEX_HOME ?? path31.join(home, ".codex");
65797
+ const codexHome = env.CODEX_HOME ?? path32.join(home, ".codex");
65758
65798
  const isPackageOrVersionDirectory = (root) => {
65759
65799
  if (isCanonicalCodexPackage(root))
65760
65800
  return true;
65761
65801
  try {
65762
- return readdirSync6(root, { withFileTypes: true }).some((entry) => entry.isDirectory() && isCanonicalCodexPackage(path31.join(root, entry.name)));
65802
+ return readdirSync6(root, { withFileTypes: true }).some((entry) => entry.isDirectory() && isCanonicalCodexPackage(path32.join(root, entry.name)));
65763
65803
  } catch {
65764
65804
  return false;
65765
65805
  }
65766
65806
  };
65767
- if (isPackageOrVersionDirectory(path31.join(codexHome, "plugins", "workit")))
65807
+ if (isPackageOrVersionDirectory(path32.join(codexHome, "plugins", "workit")))
65768
65808
  return true;
65769
- const root = path31.join(codexHome, "plugins", "cache");
65809
+ const root = path32.join(codexHome, "plugins", "cache");
65770
65810
  try {
65771
65811
  for (const marketplace of readdirSync6(root, { withFileTypes: true })) {
65772
65812
  if (!marketplace.isDirectory())
65773
65813
  continue;
65774
- if (isPackageOrVersionDirectory(path31.join(root, marketplace.name, "workit")))
65814
+ if (isPackageOrVersionDirectory(path32.join(root, marketplace.name, "workit")))
65775
65815
  return true;
65776
65816
  }
65777
65817
  } catch {
65778
65818
  return false;
65779
65819
  }
65780
65820
  return false;
65781
- }, claudeConfigDir = (home, env = process.env) => env.CLAUDE_CONFIG_DIR ?? path31.join(home, ".claude"), CLAUDE_SCOPES, appliesTo = (install, cwd) => {
65821
+ }, claudeConfigDir = (home, env = process.env) => env.CLAUDE_CONFIG_DIR ?? path32.join(home, ".claude"), CLAUDE_SCOPES, appliesTo = (install, cwd) => {
65782
65822
  if (install.scope === "user")
65783
65823
  return true;
65784
65824
  if (cwd === null || install.projectPath === null)
65785
65825
  return false;
65786
- const relative = path31.relative(path31.resolve(install.projectPath), path31.resolve(cwd));
65787
- return relative === "" || !relative.startsWith("..") && !path31.isAbsolute(relative);
65826
+ const relative = path32.relative(path32.resolve(install.projectPath), path32.resolve(cwd));
65827
+ return relative === "" || !relative.startsWith("..") && !path32.isAbsolute(relative);
65788
65828
  }, isCanonicalClaudePlugin = (root) => {
65789
65829
  try {
65790
- const manifest = JSON.parse(readFileSync11(path31.join(root, ".claude-plugin", "plugin.json"), "utf8"));
65830
+ const manifest = JSON.parse(readFileSync11(path32.join(root, ".claude-plugin", "plugin.json"), "utf8"));
65791
65831
  const repository = typeof manifest.repository === "string" ? manifest.repository : manifest.repository?.url;
65792
65832
  return manifest.name === "workit" && repository?.replace(/\.git$/, "").toLowerCase() === "https://github.com/brainervirus/workit";
65793
65833
  } catch {
65794
65834
  return false;
65795
65835
  }
65796
65836
  }, claudeWorkitInstalls = (home, env = process.env, cwd = process.cwd()) => {
65797
- const file = path31.join(claudeConfigDir(home, env), "plugins", "installed_plugins.json");
65837
+ const file = path32.join(claudeConfigDir(home, env), "plugins", "installed_plugins.json");
65798
65838
  let registry;
65799
65839
  try {
65800
65840
  registry = JSON.parse(readFileSync11(file, "utf8"));
@@ -65829,14 +65869,14 @@ var resolveWindowsShimScript = (shim) => {
65829
65869
  }, isClaudeWorkitInstalled = (home, env = process.env, cwd = process.cwd()) => claudeWorkitInstalls(home, env, cwd).length > 0, findNpmCli = (npm) => {
65830
65870
  try {
65831
65871
  const resolved = realpathSync6(npm);
65832
- if (path31.basename(resolved) === "npm-cli.js")
65872
+ if (path32.basename(resolved) === "npm-cli.js")
65833
65873
  return resolved;
65834
65874
  } catch {}
65835
- const dir = path31.dirname(npm);
65875
+ const dir = path32.dirname(npm);
65836
65876
  const candidates = [
65837
- path31.join(dir, "node_modules", "npm", "bin", "npm-cli.js"),
65838
- path31.join(dir, "..", "node_modules", "npm", "bin", "npm-cli.js"),
65839
- path31.join(dir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
65877
+ path32.join(dir, "node_modules", "npm", "bin", "npm-cli.js"),
65878
+ path32.join(dir, "..", "node_modules", "npm", "bin", "npm-cli.js"),
65879
+ path32.join(dir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
65840
65880
  ];
65841
65881
  return candidates.find((candidate) => existsSync11(candidate)) ?? null;
65842
65882
  };
@@ -65847,21 +65887,21 @@ var init_host_install = __esm(() => {
65847
65887
 
65848
65888
  // packages/workit-core/src/core/skill-manifests.ts
65849
65889
  import { cpSync as cpSync3, existsSync as existsSync12, readFileSync as readFileSync12, readdirSync as readdirSync7, statSync as statSync3, writeFileSync as writeFileSync5 } from "node:fs";
65850
- import path32 from "node:path";
65851
- var WORKIT_METHOD_SKILLS, skillManifestNames = (root) => existsSync12(root) ? readdirSync7(root).filter((name) => existsSync12(path32.join(root, name, "SKILL.md"))).toSorted() : [], validateSkillManifests = (root, expected, label) => {
65890
+ import path33 from "node:path";
65891
+ var WORKIT_METHOD_SKILLS, skillManifestNames = (root) => existsSync12(root) ? readdirSync7(root).filter((name) => existsSync12(path33.join(root, name, "SKILL.md"))).toSorted() : [], validateSkillManifests = (root, expected, label) => {
65852
65892
  const actual = skillManifestNames(root);
65853
65893
  const missing = expected.filter((name) => !actual.includes(name));
65854
65894
  const extra = actual.filter((name) => !expected.includes(name));
65855
65895
  return missing.length === 0 && extra.length === 0 ? null : `${label} mismatch at ${root} (missing: ${missing.join(", ") || "none"}; extra: ${extra.join(", ") || "none"})`;
65856
65896
  }, validateCursorSkills = (pluginDir, expected = WORKIT_METHOD_SKILLS) => {
65857
- const workit = validateSkillManifests(path32.join(pluginDir, "skills"), expected, "Cursor Workit skills");
65897
+ const workit = validateSkillManifests(path33.join(pluginDir, "skills"), expected, "Cursor Workit skills");
65858
65898
  if (workit)
65859
65899
  return workit;
65860
- const pending = [path32.join(pluginDir, "skills")];
65900
+ const pending = [path33.join(pluginDir, "skills")];
65861
65901
  while (pending.length > 0) {
65862
65902
  const dir = pending.pop();
65863
65903
  for (const entry of readdirSync7(dir, { withFileTypes: true })) {
65864
- const file = path32.join(dir, entry.name);
65904
+ const file = path33.join(dir, entry.name);
65865
65905
  if (entry.isDirectory())
65866
65906
  pending.push(file);
65867
65907
  else if ((statSync3(file).mode & 73) !== 0 || readFileSync12(file).subarray(0, 2).toString("latin1") === "#!") {
@@ -65903,7 +65943,7 @@ import {
65903
65943
  statSync as statSync4,
65904
65944
  writeFileSync as writeFileSync6
65905
65945
  } from "node:fs";
65906
- import path33 from "node:path";
65946
+ import path34 from "node:path";
65907
65947
  function inspectSessionHook(cwd, env = process.env) {
65908
65948
  const none = { hooksDir: null, hookPath: null, helperPath: null, helperCurrent: false };
65909
65949
  if (!existsSync13(cwd))
@@ -65915,8 +65955,8 @@ function inspectSessionHook(cwd, env = process.env) {
65915
65955
  const [commonDir, hooksDir] = paths.out.split(/\r?\n/);
65916
65956
  if (!paths.ok || !commonDir || !hooksDir)
65917
65957
  return { state: "not_git", ...none };
65918
- const hookPath = path33.join(hooksDir, SESSION_HOOK_NAME);
65919
- const helperPath = path33.join(commonDir, ...HELPER);
65958
+ const hookPath = path34.join(hooksDir, SESSION_HOOK_NAME);
65959
+ const helperPath = path34.join(commonDir, ...HELPER);
65920
65960
  const helperCurrent = readText3(helperPath) === SESSION_TRAILER_SCRIPT;
65921
65961
  const leftover = leftoverOf(hooksDir);
65922
65962
  const base = { hooksDir, hookPath, helperPath, helperCurrent, ...leftover ? { leftover } : {} };
@@ -65955,7 +65995,7 @@ function inspectSessionHook(cwd, env = process.env) {
65955
65995
  return blocked(`${hookPath} belongs to ${owner === "other" ? "another hook" : owner}; Workit never replaces it`, owner, text);
65956
65996
  }
65957
65997
  if (!inside2(hooksDir, commonDir)) {
65958
- const rel = path33.relative(top.out, hookPath).split(path33.sep).join("/");
65998
+ const rel = path34.relative(top.out, hookPath).split(path34.sep).join("/");
65959
65999
  if (!run2(top.out, ["check-ignore", "-q", "--", rel], env).ok)
65960
66000
  return blocked(`${hooksDir} is in the working tree and not ignored; the hook would show up as a new file`, "other");
65961
66001
  }
@@ -66096,8 +66136,8 @@ exit 0
66096
66136
  });
66097
66137
  return { ok: r.status === 0, out: (r.stdout ?? "").trim() };
66098
66138
  }, inside2 = (child, parent) => {
66099
- const rel = path33.relative(path33.resolve(parent), path33.resolve(child));
66100
- return rel === "" || !rel.startsWith("..") && !path33.isAbsolute(rel);
66139
+ const rel = path34.relative(path34.resolve(parent), path34.resolve(child));
66140
+ return rel === "" || !rel.startsWith("..") && !path34.isAbsolute(rel);
66101
66141
  }, readText3 = (file) => {
66102
66142
  try {
66103
66143
  return readFileSync13(file, "utf8");
@@ -66111,7 +66151,7 @@ exit 0
66111
66151
  } catch {
66112
66152
  return false;
66113
66153
  }
66114
- }, LEFTHOOK_CONFIGS, lefthookConfig = (top) => LEFTHOOK_CONFIGS.map((name) => path33.join(top, name)).find((file) => existsSync13(file)) ?? null, isComment = (line) => /^\s*#/.test(line), COMMAND_SH, DIRECT_CALL, VAR_CALL, runsHelperText = (text) => {
66154
+ }, LEFTHOOK_CONFIGS, lefthookConfig = (top) => LEFTHOOK_CONFIGS.map((name) => path34.join(top, name)).find((file) => existsSync13(file)) ?? null, isComment = (line) => /^\s*#/.test(line), COMMAND_SH, DIRECT_CALL, VAR_CALL, runsHelperText = (text) => {
66115
66155
  const lines = text.split(/\r?\n/).filter((line) => !isComment(line));
66116
66156
  const assigned = lines.some((line) => /(?:^|[\s;])h=/.test(line) && line.includes(HELPER_REF));
66117
66157
  return lines.some((line) => DIRECT_CALL.test(line) || assigned && VAR_CALL.test(line));
@@ -66156,14 +66196,14 @@ exit 0
66156
66196
  }, manualInPlace = (input, target) => {
66157
66197
  if (input.owner === "lefthook")
66158
66198
  return LEFTHOOK_YAML.some((name) => {
66159
- const text = readText3(path33.join(input.top, name));
66199
+ const text = readText3(path34.join(input.top, name));
66160
66200
  return text !== null && lefthookRunsHelper(text);
66161
66201
  });
66162
66202
  const text = readText3(target);
66163
66203
  if (text === null || !runsHelperText(text))
66164
66204
  return false;
66165
66205
  return input.owner === "husky" && target !== input.hookPath || isExecutable(target);
66166
- }, isHuskyV9 = (text, hooksDir) => /\$\(dirname (?:-- )?"\$0"\)\/h"/.test(text) && existsSync13(path33.join(hooksDir, "h")), ownerOf = (text, hooksDir, top) => {
66206
+ }, isHuskyV9 = (text, hooksDir) => /\$\(dirname (?:-- )?"\$0"\)\/h"/.test(text) && existsSync13(path34.join(hooksDir, "h")), ownerOf = (text, hooksDir, top) => {
66167
66207
  if (text.includes("husky.sh") || isHuskyV9(text, hooksDir))
66168
66208
  return "husky";
66169
66209
  if (/lefthook/i.test(text) || lefthookConfig(top))
@@ -66171,9 +66211,9 @@ exit 0
66171
66211
  return "other";
66172
66212
  }, manualTargetOf = ({ owner, text, hooksDir, hookPath, top }) => {
66173
66213
  if (owner === "husky" && isHuskyV9(text, hooksDir))
66174
- return path33.join(path33.dirname(hooksDir), SESSION_HOOK_NAME);
66214
+ return path34.join(path34.dirname(hooksDir), SESSION_HOOK_NAME);
66175
66215
  if (owner === "lefthook")
66176
- return lefthookConfig(top) ?? path33.join(top, "lefthook.yml");
66216
+ return lefthookConfig(top) ?? path34.join(top, "lefthook.yml");
66177
66217
  return hookPath;
66178
66218
  }, manualFor = (input) => {
66179
66219
  const { owner, displaced } = input;
@@ -66192,8 +66232,8 @@ exit 0
66192
66232
  `);
66193
66233
  return `add this line to ${target} (a new file needs \`#!/bin/sh\` as its first line and \`chmod +x\`)${stale}: ${manualTrailerLine()}`;
66194
66234
  }, leftoverOf = (hooksDir) => {
66195
- const chained = path33.join(hooksDir, LEGACY_CHAINED);
66196
- const commitMsg = path33.join(hooksDir, "commit-msg");
66235
+ const chained = path34.join(hooksDir, LEGACY_CHAINED);
66236
+ const commitMsg = path34.join(hooksDir, "commit-msg");
66197
66237
  const oldOurs = readText3(commitMsg)?.includes(SESSION_HOOK_MARKER) ?? false;
66198
66238
  if (exists(chained))
66199
66239
  return oldOurs ? `${chained} was left by an earlier Workit build: move it back to ${commitMsg} (replacing Workit's old hook there)` : `${chained} was left by an earlier Workit build and nothing runs it: if it is your original commit-msg hook, move it back to ${commitMsg}; otherwise delete it`;
@@ -66201,7 +66241,7 @@ exit 0
66201
66241
  return `${commitMsg} is a hook from an earlier Workit build; delete it (the trailer now comes from ${SESSION_HOOK_NAME})`;
66202
66242
  return;
66203
66243
  }, writeExecutable = (file, content) => {
66204
- mkdirSync5(path33.dirname(file), { recursive: true });
66244
+ mkdirSync5(path34.dirname(file), { recursive: true });
66205
66245
  const staged = `${file}.workit-new`;
66206
66246
  try {
66207
66247
  writeFileSync6(staged, content, { mode: 493 });
@@ -66264,13 +66304,13 @@ import {
66264
66304
  writeFileSync as writeFileSync7
66265
66305
  } from "node:fs";
66266
66306
  import os9 from "node:os";
66267
- import path34 from "node:path";
66307
+ import path35 from "node:path";
66268
66308
  var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66269
- let dir = path34.resolve(cwd);
66309
+ let dir = path35.resolve(cwd);
66270
66310
  while (true) {
66271
- if (existsSync14(path34.join(dir, "packages", "workit-core", "package.json")))
66311
+ if (existsSync14(path35.join(dir, "packages", "workit-core", "package.json")))
66272
66312
  return dir;
66273
- const parent = path34.dirname(dir);
66313
+ const parent = path35.dirname(dir);
66274
66314
  if (parent === dir)
66275
66315
  return null;
66276
66316
  dir = parent;
@@ -66278,8 +66318,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66278
66318
  }, resolve = (options) => {
66279
66319
  const env = options.env ?? process.env;
66280
66320
  const home = options.home ?? env.HOME ?? os9.homedir();
66281
- const configDir = options.configDir ?? env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path34.join(home, ".config", "workit");
66282
- const stateDir = options.stateDir ?? env.WORKFLOW_TOOLKIT_STATE ?? path34.join(home, ".local", "state", "workit");
66321
+ const configDir = options.configDir ?? env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path35.join(home, ".config", "workit");
66322
+ const stateDir = options.stateDir ?? env.WORKFLOW_TOOLKIT_STATE ?? path35.join(home, ".local", "state", "workit");
66283
66323
  const cwd = options.cwd ?? process.cwd();
66284
66324
  const dev = options.dev?.trim() || env.WORKFLOW_TOOLKIT_DEV?.trim() || findDevFromCwd(cwd);
66285
66325
  return {
@@ -66290,11 +66330,11 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66290
66330
  cwd,
66291
66331
  workspaceRoot: options.workspaceRoot ?? env.WORKFLOW_WORKSPACE_ROOT ?? cwd,
66292
66332
  dev,
66293
- opencodeConfig: options.opencodeConfig ?? path34.join(home, ".config", "opencode", "opencode.json"),
66333
+ opencodeConfig: options.opencodeConfig ?? path35.join(home, ".config", "opencode", "opencode.json"),
66294
66334
  opencodePackageCacheDir: options.opencodePackageCacheDir ?? null,
66295
- cursorSettings: options.cursorSettings ?? path34.join(home, ".cursor", "settings.json"),
66296
- cursorMcp: options.cursorMcp ?? path34.join(home, ".cursor", "mcp.json"),
66297
- cursorPluginDir: options.cursorPluginDir ?? path34.join(home, ".cursor", "plugins", "local", "workit"),
66335
+ cursorSettings: options.cursorSettings ?? path35.join(home, ".cursor", "settings.json"),
66336
+ cursorMcp: options.cursorMcp ?? path35.join(home, ".cursor", "mcp.json"),
66337
+ cursorPluginDir: options.cursorPluginDir ?? path35.join(home, ".cursor", "plugins", "local", "workit"),
66298
66338
  cursorHeartbeatDir: options.stateDir ?? (env.WORKFLOW_TOOLKIT_STATE || resolveStateDir()),
66299
66339
  hookStateDir: options.stateDir ?? (env.WORKFLOW_TOOLKIT_STATE || resolveStateDir()),
66300
66340
  codexHome: options.codexHome,
@@ -66323,12 +66363,12 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66323
66363
  ...new Set(entries.filter((entry) => typeof entry === "string" && isWorkitPlugin(entry)))
66324
66364
  ];
66325
66365
  }, commandOnPath = (name, env) => findOnPath(process.platform === "win32" ? [name, `${name}.exe`] : [name], env) !== null, pathextNames = (name, env) => process.platform === "win32" ? (env.PATHEXT ?? process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean).map((ext) => `${name}${ext.toLowerCase()}`) : [name], findOnPath = (names, env) => {
66326
- const dirs = (env.PATH ?? process.env.PATH ?? "").split(path34.delimiter);
66366
+ const dirs = (env.PATH ?? process.env.PATH ?? "").split(path35.delimiter);
66327
66367
  for (const dir of dirs) {
66328
66368
  if (!dir)
66329
66369
  continue;
66330
66370
  for (const candidateName of names) {
66331
- const candidate = path34.join(dir, candidateName);
66371
+ const candidate = path35.join(dir, candidateName);
66332
66372
  try {
66333
66373
  const st = statSync5(candidate);
66334
66374
  if (process.platform !== "win32" && (st.mode & 73) === 0)
@@ -66357,7 +66397,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66357
66397
  if (env.BUN && existsSync14(env.BUN))
66358
66398
  return env.BUN;
66359
66399
  for (const candidate of [
66360
- path34.join(env.HOME || os9.homedir(), ".bun/bin/bun"),
66400
+ path35.join(env.HOME || os9.homedir(), ".bun/bin/bun"),
66361
66401
  "/usr/local/bin/bun",
66362
66402
  "/usr/bin/bun"
66363
66403
  ]) {
@@ -66412,7 +66452,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66412
66452
  detail: "installed package, not a dev checkout — version parity applies to checkouts only"
66413
66453
  };
66414
66454
  }
66415
- const corePkg = readJson(path34.join(res.dev, "packages/workit-core/package.json"));
66455
+ const corePkg = readJson(path35.join(res.dev, "packages/workit-core/package.json"));
66416
66456
  if (!corePkg) {
66417
66457
  return {
66418
66458
  id: "versions",
@@ -66422,7 +66462,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66422
66462
  }
66423
66463
  const refs = new Set;
66424
66464
  for (const name of ["workit-opencode", "workit-cursor", "workit-cli"]) {
66425
- const pkg = readJson(path34.join(res.dev, "packages", name, "package.json"));
66465
+ const pkg = readJson(path35.join(res.dev, "packages", name, "package.json"));
66426
66466
  const dep = pkg?.dependencies?.["@brainervirus/workit-core"] ?? pkg?.devDependencies?.["@brainervirus/workit-core"];
66427
66467
  if (typeof dep === "string")
66428
66468
  refs.add(dep);
@@ -66438,7 +66478,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66438
66478
  if (refs.size > 1) {
66439
66479
  problems.push(`adapters pin different core versions: ${[...refs].join(", ")}`);
66440
66480
  }
66441
- const opencodePkg = readJson(path34.join(res.dev, "packages/workit-opencode/package.json"));
66481
+ const opencodePkg = readJson(path35.join(res.dev, "packages/workit-opencode/package.json"));
66442
66482
  const sdk = opencodePkg?.dependencies?.["@opencode/plugin"] ?? opencodePkg?.devDependencies?.["@opencode/plugin"];
66443
66483
  const sdkVersion = typeof sdk === "string" ? (sdk.match(/^\d+(?:\.\d+){0,2}/) ?? [])[0] : null;
66444
66484
  if (sdkVersion && !semverAtLeast(sdkVersion, SUPPORT_MATRIX.opencode.minimum)) {
@@ -66465,14 +66505,14 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66465
66505
  status: "pass",
66466
66506
  detail: "opencode CLI not on PATH — skipping version check"
66467
66507
  };
66468
- const scratch = mkdtempSync(path34.join(os9.tmpdir(), "workit-doctor-opencode-"));
66508
+ const scratch = mkdtempSync(path35.join(os9.tmpdir(), "workit-doctor-opencode-"));
66469
66509
  let raw;
66470
66510
  try {
66471
66511
  raw = versionOf("opencode", {
66472
66512
  ...res.env,
66473
- XDG_DATA_HOME: path34.join(scratch, "data"),
66474
- XDG_STATE_HOME: path34.join(scratch, "state"),
66475
- XDG_CACHE_HOME: path34.join(scratch, "cache")
66513
+ XDG_DATA_HOME: path35.join(scratch, "data"),
66514
+ XDG_STATE_HOME: path35.join(scratch, "state"),
66515
+ XDG_CACHE_HOME: path35.join(scratch, "cache")
66476
66516
  }, 5000);
66477
66517
  } finally {
66478
66518
  rmSync3(scratch, { recursive: true, force: true });
@@ -66574,19 +66614,19 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66574
66614
  current[unquote(pair[1])] = value === "true" ? true : value === "false" ? false : unquote(value);
66575
66615
  }
66576
66616
  return tables;
66577
- }, codexHomeOf = (res) => res.codexHome ?? (res.env.CODEX_HOME || path34.join(res.home, ".codex")), codexWorkitInstalls = (res) => {
66617
+ }, codexHomeOf = (res) => res.codexHome ?? (res.env.CODEX_HOME || path35.join(res.home, ".codex")), codexWorkitInstalls = (res) => {
66578
66618
  const codexHome = codexHomeOf(res);
66579
- const configFile = path34.join(codexHome, "config.toml");
66619
+ const configFile = path35.join(codexHome, "config.toml");
66580
66620
  const installs = [];
66581
66621
  for (const [key, table] of readTomlTables(configFile)) {
66582
66622
  const [kind, id, ...rest] = key.split("\x00");
66583
66623
  if (kind !== "plugins" || rest.length > 0 || !id?.startsWith("workit@") || table.enabled === false)
66584
66624
  continue;
66585
66625
  const marketplace = id.slice("workit@".length);
66586
- const dir = path34.join(codexHome, "plugins", "cache", marketplace, "workit");
66626
+ const dir = path35.join(codexHome, "plugins", "cache", marketplace, "workit");
66587
66627
  let versions = [];
66588
66628
  try {
66589
- versions = readdirSync8(dir).filter((v) => existsSync14(path34.join(dir, v, ".codex-plugin")));
66629
+ versions = readdirSync8(dir).filter((v) => existsSync14(path35.join(dir, v, ".codex-plugin")));
66590
66630
  } catch {
66591
66631
  versions = [];
66592
66632
  }
@@ -66594,7 +66634,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66594
66634
  installs.push({
66595
66635
  id,
66596
66636
  marketplace,
66597
- root: version ? path34.join(dir, version) : null,
66637
+ root: version ? path35.join(dir, version) : null,
66598
66638
  version,
66599
66639
  configFile
66600
66640
  });
@@ -66616,7 +66656,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66616
66656
  };
66617
66657
  return `sha256:${createHash14("sha256").update(JSON.stringify(body)).digest("hex")}`;
66618
66658
  }, codexHookTrust = (install, tables) => {
66619
- const hooks = install.root ? readJson(path34.join(install.root, "hooks", "hooks.json"))?.hooks : null;
66659
+ const hooks = install.root ? readJson(path35.join(install.root, "hooks", "hooks.json"))?.hooks : null;
66620
66660
  if (!hooks || typeof hooks !== "object")
66621
66661
  return null;
66622
66662
  const result = [];
@@ -66689,25 +66729,25 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66689
66729
  status: "pass",
66690
66730
  detail: "no Workit Codex plugin enabled — skipping"
66691
66731
  };
66692
- const agentsDir = path34.join(codexHomeOf(res), "agents");
66732
+ const agentsDir = path35.join(codexHomeOf(res), "agents");
66693
66733
  const problems = [];
66694
66734
  const fixes = [];
66695
66735
  const installed = [];
66696
66736
  for (const install of installs) {
66697
- const source = install.root ? path34.join(install.root, "agents") : null;
66737
+ const source = install.root ? path35.join(install.root, "agents") : null;
66698
66738
  const files = source && existsSync14(source) ? readdirSync8(source).filter((f) => f.endsWith(".toml")).toSorted() : [];
66699
66739
  if (files.length === 0) {
66700
66740
  problems.push(`${install.id} ${install.version ?? "?"} bundles no agents`);
66701
66741
  fixes.push(`codex plugin remove ${install.id} && codex plugin add ${install.id}`);
66702
66742
  continue;
66703
66743
  }
66704
- const install_fix = `node ${JSON.stringify(path34.join(install.root, "dist", "launch-mcp.js"))} --install-agents, then start a new Codex session`;
66705
- const pluginVersion = readJson(path34.join(install.root, "package.json"))?.version;
66744
+ const install_fix = `node ${JSON.stringify(path35.join(install.root, "dist", "launch-mcp.js"))} --install-agents, then start a new Codex session`;
66745
+ const pluginVersion = readJson(path35.join(install.root, "package.json"))?.version;
66706
66746
  const version = typeof pluginVersion === "string" ? pluginVersion.match(SEMVER)?.[0] ?? null : null;
66707
66747
  let stale = false;
66708
66748
  for (const file of files) {
66709
- const dest = path34.join(agentsDir, file);
66710
- const want = stampCodexAgent(readFileSync14(path34.join(source, file), "utf8"), version);
66749
+ const dest = path35.join(agentsDir, file);
66750
+ const want = stampCodexAgent(readFileSync14(path35.join(source, file), "utf8"), version);
66711
66751
  let link = false;
66712
66752
  try {
66713
66753
  link = lstatSync5(dest).isSymbolicLink();
@@ -66760,7 +66800,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66760
66800
  const env = res.env.PI_CODING_AGENT_DIR;
66761
66801
  if (env)
66762
66802
  return env === "~" ? res.home : env.replace(/^~(?=\/|\\)/, res.home);
66763
- return path34.join(res.home, ".pi", "agent");
66803
+ return path35.join(res.home, ".pi", "agent");
66764
66804
  }, npmSpecName = (spec) => {
66765
66805
  const at = spec.indexOf("@", spec.startsWith("@") ? 1 : 0);
66766
66806
  return at > 0 ? { name: spec.slice(0, at), pinned: true } : { name: spec, pinned: false };
@@ -66768,10 +66808,10 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66768
66808
  const scopes = [
66769
66809
  {
66770
66810
  scope: "project",
66771
- settingsFile: path34.join(res.cwd, ".pi", "settings.json"),
66772
- base: path34.join(res.cwd, ".pi")
66811
+ settingsFile: path35.join(res.cwd, ".pi", "settings.json"),
66812
+ base: path35.join(res.cwd, ".pi")
66773
66813
  },
66774
- { scope: "user", settingsFile: path34.join(agentDir, "settings.json"), base: agentDir }
66814
+ { scope: "user", settingsFile: path35.join(agentDir, "settings.json"), base: agentDir }
66775
66815
  ];
66776
66816
  for (const { scope, settingsFile, base } of scopes) {
66777
66817
  const packages = readJson(settingsFile)?.packages;
@@ -66786,13 +66826,13 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66786
66826
  const spec = npmSpecName(source.slice(4).trim());
66787
66827
  if (spec.name !== PI_PACKAGE)
66788
66828
  continue;
66789
- const root = path34.join(base, "npm", "node_modules", ...PI_PACKAGE.split("/"));
66829
+ const root = path35.join(base, "npm", "node_modules", ...PI_PACKAGE.split("/"));
66790
66830
  return { scope, settingsFile, source, filter, root, npm: { pinned: spec.pinned } };
66791
66831
  }
66792
66832
  if (/^(git:|https?:|ssh:|git@)/.test(source))
66793
66833
  continue;
66794
- const local = path34.resolve(base, source.replace(/^~(?=\/|\\)/, res.home));
66795
- if (readJson(path34.join(local, "package.json"))?.name === PI_PACKAGE)
66834
+ const local = path35.resolve(base, source.replace(/^~(?=\/|\\)/, res.home));
66835
+ if (readJson(path35.join(local, "package.json"))?.name === PI_PACKAGE)
66796
66836
  return { scope, settingsFile, source, filter, root: local, npm: null };
66797
66837
  }
66798
66838
  }
@@ -66803,7 +66843,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66803
66843
  const list = patterns.filter((p) => typeof p === "string");
66804
66844
  if (list.length === 0)
66805
66845
  return false;
66806
- const name = path34.posix.basename(file);
66846
+ const name = path35.posix.basename(file);
66807
66847
  const matches = (p) => {
66808
66848
  const re = globToRegExp3(p);
66809
66849
  return re.test(file) || re.test(name);
@@ -66828,12 +66868,12 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66828
66868
  return {
66829
66869
  id: "pi_extension",
66830
66870
  status: "warn",
66831
- detail: `Workit Pi extension missing: no ${PI_PACKAGE} entry in ${path34.join(agentDir, "settings.json")} or ${path34.join(res.cwd, ".pi", "settings.json")}`,
66871
+ detail: `Workit Pi extension missing: no ${PI_PACKAGE} entry in ${path35.join(agentDir, "settings.json")} or ${path35.join(res.cwd, ".pi", "settings.json")}`,
66832
66872
  fix: installCmd("user")
66833
66873
  };
66834
66874
  const where = `${entry.source} (${entry.scope}, ${entry.settingsFile})`;
66835
66875
  const rebuild = `cd ${JSON.stringify(entry.root)} && bun run build`;
66836
- const pkg = readJson(path34.join(entry.root, "package.json"));
66876
+ const pkg = readJson(path35.join(entry.root, "package.json"));
66837
66877
  if (!pkg)
66838
66878
  return {
66839
66879
  id: "pi_extension",
@@ -66842,7 +66882,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66842
66882
  fix: entry.npm ? installCmd(entry.scope, entry.source) : `restore ${entry.root}, then ${rebuild}`
66843
66883
  };
66844
66884
  const declared = Array.isArray(pkg.pi?.extensions) ? pkg.pi.extensions.some((e) => typeof e === "string" && e.replace(/^\.\//, "") === PI_EXTENSION) : false;
66845
- if (!declared || !existsSync14(path34.join(entry.root, PI_EXTENSION)))
66885
+ if (!declared || !existsSync14(path35.join(entry.root, PI_EXTENSION)))
66846
66886
  return {
66847
66887
  id: "pi_extension",
66848
66888
  status: "warn",
@@ -66895,21 +66935,21 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66895
66935
  detail: `Workit Pi extension ${version ?? "?"} from ${where} loads ${PI_EXTENSION}`
66896
66936
  };
66897
66937
  }, assetPathsFor = (host, dev) => {
66898
- const pkg = path34.join(dev, "packages", `workit-${host}`);
66938
+ const pkg = path35.join(dev, "packages", `workit-${host}`);
66899
66939
  switch (host) {
66900
66940
  case "opencode": {
66901
- const packaged = path34.join(pkg, "assets", "skills");
66902
- const root = existsSync14(packaged) ? packaged : path34.join(dev, "packages", "workit-core", "skills");
66903
- return WORKIT_METHOD_SKILLS.map((skill) => path34.join(root, skill, "SKILL.md"));
66941
+ const packaged = path35.join(pkg, "assets", "skills");
66942
+ const root = existsSync14(packaged) ? packaged : path35.join(dev, "packages", "workit-core", "skills");
66943
+ return WORKIT_METHOD_SKILLS.map((skill) => path35.join(root, skill, "SKILL.md"));
66904
66944
  }
66905
66945
  case "cursor":
66906
66946
  return [
66907
- path34.join(pkg, "assets", "templates", "workit-contract.md"),
66908
- path34.join(pkg, "mcp.json"),
66909
- path34.join(pkg, ".cursor-plugin")
66947
+ path35.join(pkg, "assets", "templates", "workit-contract.md"),
66948
+ path35.join(pkg, "mcp.json"),
66949
+ path35.join(pkg, ".cursor-plugin")
66910
66950
  ];
66911
66951
  case "cli":
66912
- return [path34.join(pkg, "assets", "templates", "spec-template.md")];
66952
+ return [path35.join(pkg, "assets", "templates", "spec-template.md")];
66913
66953
  }
66914
66954
  }, hostsFor = (host) => host === "cli" ? ["opencode", "cursor", "cli"] : [host], checkAssets = (res) => {
66915
66955
  const dev = res.dev;
@@ -66940,17 +66980,17 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66940
66980
  fix: "Reinstall or rebuild the workit package (missing assets under packages/workit-<host>)"
66941
66981
  };
66942
66982
  }, launcherSlotsFor = (host, dev) => {
66943
- const pkg = path34.join(dev, "packages", `workit-${host}`);
66983
+ const pkg = path35.join(dev, "packages", `workit-${host}`);
66944
66984
  switch (host) {
66945
66985
  case "opencode":
66946
- return [[path34.join(pkg, "src", "plugin.ts"), path34.join(pkg, "dist", "plugin.js")]];
66986
+ return [[path35.join(pkg, "src", "plugin.ts"), path35.join(pkg, "dist", "plugin.js")]];
66947
66987
  case "cursor":
66948
66988
  return [
66949
- [path34.join(pkg, "dist", "mcp-server.js")],
66950
- [path34.join(pkg, "dist", "cursor-session-start.js")]
66989
+ [path35.join(pkg, "dist", "mcp-server.js")],
66990
+ [path35.join(pkg, "dist", "cursor-session-start.js")]
66951
66991
  ];
66952
66992
  case "cli":
66953
- return [[path34.join(pkg, "src", "index.tsx"), path34.join(pkg, "dist", "index.js")]];
66993
+ return [[path35.join(pkg, "src", "index.tsx"), path35.join(pkg, "dist", "index.js")]];
66954
66994
  }
66955
66995
  }, validNodeEntry = (entry, runtime, env) => {
66956
66996
  try {
@@ -66977,7 +67017,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66977
67017
  if (typeof command !== "string" || !Array.isArray(args) || typeof args[0] !== "string") {
66978
67018
  return "invalid";
66979
67019
  }
66980
- const executable = path34.basename(command).toLowerCase();
67020
+ const executable = path35.basename(command).toLowerCase();
66981
67021
  const canonical = cursorMcpServerEntry("").args;
66982
67022
  if (executable === "npx" || executable === "npx.exe" || executable === "npx.cmd") {
66983
67023
  if (args.length !== canonical.length || args.some((a, i) => a !== canonical[i]))
@@ -66989,10 +67029,10 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
66989
67029
  return {
66990
67030
  kind: "node",
66991
67031
  runtime: command,
66992
- entry: path34.isAbsolute(args[0]) ? args[0] : path34.resolve(path34.dirname(res.cursorMcp), args[0])
67032
+ entry: path35.isAbsolute(args[0]) ? args[0] : path35.resolve(path35.dirname(res.cursorMcp), args[0])
66993
67033
  };
66994
67034
  }, canonicalCursorHook, isCanonicalCursorHook = (command, res) => command === canonicalCursorHook || command === cursorHooksEntry(res.cursorPluginDir).command, registeredCursorHook = (res) => {
66995
- const hooksFile = path34.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
67035
+ const hooksFile = path35.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
66996
67036
  if (!existsSync14(hooksFile))
66997
67037
  return "invalid";
66998
67038
  const config = readJson(hooksFile);
@@ -67010,9 +67050,9 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67010
67050
  if (!m)
67011
67051
  return false;
67012
67052
  const entry = m[1].trim();
67013
- if (!path34.isAbsolute(entry))
67053
+ if (!path35.isAbsolute(entry))
67014
67054
  return false;
67015
- if (path34.resolve(entry) !== path34.resolve(path34.join(res.cursorPluginDir, "dist", "cursor-session-start.js"))) {
67055
+ if (path35.resolve(entry) !== path35.resolve(path35.join(res.cursorPluginDir, "dist", "cursor-session-start.js"))) {
67016
67056
  return false;
67017
67057
  }
67018
67058
  return validNodeEntry(entry, "node", res.env);
@@ -67021,7 +67061,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67021
67061
  const hosts = hostsFor(res.host);
67022
67062
  const registered = hosts.includes("cursor") ? registeredCursorLauncher(res) : null;
67023
67063
  const runtime = registered && registered !== "invalid" && registered.kind === "node" ? registered.runtime : "node";
67024
- const missing = hosts.includes("cursor") ? ["dist/mcp-server.js", "dist/cursor-session-start.js"].map((rel) => path34.join(res.cursorPluginDir, rel)).filter((p) => !validNodeEntry(p, runtime, res.env)).map((p) => `cursor: ${p}`) : [];
67064
+ const missing = hosts.includes("cursor") ? ["dist/mcp-server.js", "dist/cursor-session-start.js"].map((rel) => path35.join(res.cursorPluginDir, rel)).filter((p) => !validNodeEntry(p, runtime, res.env)).map((p) => `cursor: ${p}`) : [];
67025
67065
  if (hosts.includes("cursor")) {
67026
67066
  if (registered === "invalid") {
67027
67067
  missing.push(`cursor: canonical workit MCP launcher in ${res.cursorMcp}`);
@@ -67030,9 +67070,9 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67030
67070
  }
67031
67071
  const hook = registeredCursorHook(res);
67032
67072
  if (hook === "invalid") {
67033
- missing.push(`cursor: canonical session-start hook in ${path34.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")}`);
67073
+ missing.push(`cursor: canonical session-start hook in ${path35.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")}`);
67034
67074
  } else if (hook !== null && !isCanonicalCursorHook(hook, res) && !validLocalDistHook(hook, res)) {
67035
- missing.push(`cursor: canonical session-start hook in ${path34.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")} (registered ${hook})`);
67075
+ missing.push(`cursor: canonical session-start hook in ${path35.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")} (registered ${hook})`);
67036
67076
  }
67037
67077
  }
67038
67078
  if (dev) {
@@ -67067,7 +67107,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67067
67107
  status: "pass",
67068
67108
  detail: "no Cursor plugin install — hook launcher not inspected"
67069
67109
  };
67070
- const launcher = path34.join(res.cursorPluginDir, "hooks", "launch.mjs");
67110
+ const launcher = path35.join(res.cursorPluginDir, "hooks", "launch.mjs");
67071
67111
  if (!existsSync14(launcher))
67072
67112
  return {
67073
67113
  id: "cursor_hook",
@@ -67075,7 +67115,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67075
67115
  detail: `cursor hook launcher mode: missing — ${launcher} is absent (an install from before the pinned launcher)`,
67076
67116
  fix: CURSOR_HOOK_FIX
67077
67117
  };
67078
- const hooksFile = path34.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
67118
+ const hooksFile = path35.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
67079
67119
  const registered = readJson(hooksFile);
67080
67120
  const sessionCommand = registered?.hooks?.sessionStart?.[0]?.command;
67081
67121
  const offLauncher = [
@@ -67142,10 +67182,10 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67142
67182
  return null;
67143
67183
  }
67144
67184
  }, silentCursorHooks = (res) => {
67145
- const session = mtimeMs(path34.join(res.cursorHeartbeatDir, "cursor-session-last-start"));
67185
+ const session = mtimeMs(path35.join(res.cursorHeartbeatDir, "cursor-session-last-start"));
67146
67186
  if (session === null || Date.now() - session < SILENT_HOOK_GRACE_MS)
67147
67187
  return null;
67148
- const hook = mtimeMs(path34.join(res.cursorHeartbeatDir, "cursor-hook-last-run"));
67188
+ const hook = mtimeMs(path35.join(res.cursorHeartbeatDir, "cursor-hook-last-run"));
67149
67189
  if (hook !== null && hook >= session)
67150
67190
  return null;
67151
67191
  return `Cursor started the Workit MCP server at ${new Date(session).toISOString()} but no Workit hook has run since${hook === null ? " (none ever)" : ""} — if the agent ran in that window, Cursor is not running the plugin hooks and Workit enforcement is off`;
@@ -67241,7 +67281,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67241
67281
  }
67242
67282
  return { id: "stale_pin", status: "pass", detail: "opencode pin resolves" };
67243
67283
  }, pluginMcpSelectors = (res) => {
67244
- const p = path34.join(res.cursorPluginDir, "mcp.json");
67284
+ const p = path35.join(res.cursorPluginDir, "mcp.json");
67245
67285
  if (!existsSync14(p))
67246
67286
  return null;
67247
67287
  const cfg = readJson(p);
@@ -67275,19 +67315,19 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67275
67315
  return null;
67276
67316
  }
67277
67317
  }, installedPluginVersion = (res) => {
67278
- const pkg = readJson(path34.join(res.cursorPluginDir, "package.json"));
67318
+ const pkg = readJson(path35.join(res.cursorPluginDir, "package.json"));
67279
67319
  return typeof pkg?.version === "string" && pkg.version ? pkg.version : null;
67280
67320
  }, installedOpenCodeCache = (res) => {
67281
67321
  if (res.opencodePackageCacheDir !== null) {
67282
- const pkg = readJson(path34.join(res.opencodePackageCacheDir, "node_modules", "@brainervirus", "workit-opencode", "package.json"));
67322
+ const pkg = readJson(path35.join(res.opencodePackageCacheDir, "node_modules", "@brainervirus", "workit-opencode", "package.json"));
67283
67323
  return typeof pkg?.version === "string" && pkg.version ? { version: pkg.version, dir: res.opencodePackageCacheDir } : null;
67284
67324
  }
67285
67325
  const found = openCodeInstalledPlugin(res.home, res.env);
67286
67326
  if (!found)
67287
67327
  return null;
67288
- let dir = path34.dirname(path34.dirname(path34.dirname(found.root)));
67289
- if (path34.basename(dir) !== "workit-opencode@latest")
67290
- dir = path34.dirname(dir);
67328
+ let dir = path35.dirname(path35.dirname(path35.dirname(found.root)));
67329
+ if (path35.basename(dir) !== "workit-opencode@latest")
67330
+ dir = path35.dirname(dir);
67291
67331
  return { version: found.version, dir };
67292
67332
  }, checkOpenCodePackageCache = (res) => {
67293
67333
  if (!existsSync14(res.opencodeConfig)) {
@@ -67391,7 +67431,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67391
67431
  fix: "Re-run install-cursor-plugin.sh — it rewrites the workit MCP entry to the canonical @latest selector"
67392
67432
  };
67393
67433
  }
67394
- const hooksFile = path34.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
67434
+ const hooksFile = path35.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
67395
67435
  const hookCmd = readJson(hooksFile)?.hooks?.sessionStart?.[0]?.command ?? null;
67396
67436
  const canonicalHook = canonicalCursorHook;
67397
67437
  const staleHook = hookCmd !== null && !isCanonicalCursorHook(hookCmd, res) && !hookCmd.startsWith("node ") && hookCmd.includes("@brainervirus/workit-cursor@");
@@ -67413,7 +67453,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67413
67453
  };
67414
67454
  }
67415
67455
  const installed = installedPluginVersion(res);
67416
- const source = res.dev ? readJson(path34.join(res.dev, "packages/workit-cursor/package.json"))?.version ?? null : readJson(path34.join(packageRoot(), "package.json"))?.version ?? null;
67456
+ const source = res.dev ? readJson(path35.join(res.dev, "packages/workit-cursor/package.json"))?.version ?? null : readJson(path35.join(packageRoot(), "package.json"))?.version ?? null;
67417
67457
  const localDist = mcpSelectors === null && hookCmd !== null && !isCanonicalCursorHook(hookCmd, res) && hookCmd.startsWith("node ");
67418
67458
  if (localDist && installed !== null && source !== null && !semverAtLeast(installed, source)) {
67419
67459
  return {
@@ -67425,7 +67465,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67425
67465
  }
67426
67466
  if (localDist && installed !== null && source !== null && res.dev) {
67427
67467
  const entry = /^node\s+(.+)$/.exec((hookCmd ?? "").trim())?.[1]?.trim() ?? "";
67428
- const sourceBundle = entry && path34.isAbsolute(entry) ? path34.join(res.dev, "packages", "workit-cursor", "dist", path34.basename(entry)) : "";
67468
+ const sourceBundle = entry && path35.isAbsolute(entry) ? path35.join(res.dev, "packages", "workit-cursor", "dist", path35.basename(entry)) : "";
67429
67469
  if (entry && sourceBundle) {
67430
67470
  const installedHash = bundleHashOfFile(entry);
67431
67471
  const sourceHash = bundleHashOfFile(sourceBundle);
@@ -67433,7 +67473,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67433
67473
  return {
67434
67474
  id: "stale_install",
67435
67475
  status: "fail",
67436
- detail: `stale_install: installed workit-cursor ${installed} runs different bytes than the current runtime build (${path34.basename(entry)} hash mismatch)`,
67476
+ detail: `stale_install: installed workit-cursor ${installed} runs different bytes than the current runtime build (${path35.basename(entry)} hash mismatch)`,
67437
67477
  fix: "Re-run install-cursor-plugin.sh — it refreshes the plugin directory with the current build"
67438
67478
  };
67439
67479
  }
@@ -67533,7 +67573,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67533
67573
  }, checkMalformedConfig = (res) => {
67534
67574
  const files = [];
67535
67575
  for (const name of ["config.json", "youtrack.json", "vcs.json", "workspaces.json"]) {
67536
- const p = path34.join(res.configDir, name);
67576
+ const p = path35.join(res.configDir, name);
67537
67577
  if (existsSync14(p))
67538
67578
  files.push(p);
67539
67579
  }
@@ -67731,11 +67771,11 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67731
67771
  }
67732
67772
  }, checkCredentialMetadata = (res) => {
67733
67773
  const tokenPaths = [];
67734
- const youtrackJson = readJson(path34.join(res.configDir, "youtrack.json"));
67774
+ const youtrackJson = readJson(path35.join(res.configDir, "youtrack.json"));
67735
67775
  if (youtrackJson) {
67736
- tokenPaths.push(typeof youtrackJson.tokenFile === "string" ? youtrackJson.tokenFile : path34.join(res.configDir, "youtrack.token"));
67737
- } else if (existsSync14(path34.join(res.configDir, "youtrack.token"))) {
67738
- tokenPaths.push(path34.join(res.configDir, "youtrack.token"));
67776
+ tokenPaths.push(typeof youtrackJson.tokenFile === "string" ? youtrackJson.tokenFile : path35.join(res.configDir, "youtrack.token"));
67777
+ } else if (existsSync14(path35.join(res.configDir, "youtrack.token"))) {
67778
+ tokenPaths.push(path35.join(res.configDir, "youtrack.token"));
67739
67779
  }
67740
67780
  if (tokenPaths.length === 0) {
67741
67781
  return {
@@ -67746,7 +67786,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67746
67786
  }
67747
67787
  const problems = [];
67748
67788
  for (const raw of tokenPaths) {
67749
- const p = path34.isAbsolute(raw) ? raw : path34.resolve(res.configDir, raw);
67789
+ const p = path35.isAbsolute(raw) ? raw : path35.resolve(res.configDir, raw);
67750
67790
  if (!existsSync14(p)) {
67751
67791
  problems.push(`${p} is missing`);
67752
67792
  continue;
@@ -67862,7 +67902,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67862
67902
  const remoteHost = githubHostFromRemote(probes.origin(res.cwd) ?? "");
67863
67903
  if (!remoteHost)
67864
67904
  return { id: "github_identity", status: "pass", detail: "no GitHub remote configured" };
67865
- const vcsJson = readJson(res.env.WORKFLOW_VCS_CONFIG ?? path34.join(res.configDir, "vcs.json"));
67905
+ const vcsJson = readJson(res.env.WORKFLOW_VCS_CONFIG ?? path35.join(res.configDir, "vcs.json"));
67866
67906
  const workspace = workspaceProviderForIdentity(res.cwd, res.configDir, res.env);
67867
67907
  if (workspace.error)
67868
67908
  return {
@@ -67890,7 +67930,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67890
67930
  const remoteHost = githubHostFromRemote(probes.origin(res.cwd) ?? "");
67891
67931
  if (!remoteHost)
67892
67932
  return { id: "gitlab_identity", status: "pass", detail: "no GitLab remote configured" };
67893
- const vcsJson = readJson(res.env.WORKFLOW_VCS_CONFIG ?? path34.join(res.configDir, "vcs.json"));
67933
+ const vcsJson = readJson(res.env.WORKFLOW_VCS_CONFIG ?? path35.join(res.configDir, "vcs.json"));
67894
67934
  const workspace = workspaceProviderForIdentity(res.cwd, res.configDir, res.env);
67895
67935
  if (workspace.error)
67896
67936
  return {
@@ -67916,8 +67956,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67916
67956
  { surface: "SSH", login: probes.sshLogin(remoteHost) }
67917
67957
  ]);
67918
67958
  }, checkLogWritable = (res) => {
67919
- const logsDir = path34.join(res.stateDir, "logs");
67920
- const probe = path34.join(logsDir, "doctor-probe.tmp");
67959
+ const logsDir = path35.join(res.stateDir, "logs");
67960
+ const probe = path35.join(logsDir, "doctor-probe.tmp");
67921
67961
  try {
67922
67962
  mkdirSync6(logsDir, { recursive: true, mode: 448 });
67923
67963
  writeFileSync7(probe, `{"probe":true}
@@ -67995,7 +68035,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67995
68035
  const counts = { skip: 0, late: 0 };
67996
68036
  let text = "";
67997
68037
  try {
67998
- text = readFileSync14(path34.join(stateDir, HOOK_SKIPS_FILE), "utf8");
68038
+ text = readFileSync14(path35.join(stateDir, HOOK_SKIPS_FILE), "utf8");
67999
68039
  } catch {
68000
68040
  return counts;
68001
68041
  }
@@ -68013,7 +68053,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
68013
68053
  }
68014
68054
  return counts;
68015
68055
  }, checkHookDeadline = (res) => {
68016
- const file = path34.join(res.hookStateDir, HOOK_SKIPS_FILE);
68056
+ const file = path35.join(res.hookStateDir, HOOK_SKIPS_FILE);
68017
68057
  const { skip, late } = countHookSkips(res.hookStateDir, Date.now() - DAY_MS);
68018
68058
  const lateText = late > 0 ? `; ${late} answered past it in full` : "";
68019
68059
  if (skip > 0)
@@ -68036,8 +68076,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
68036
68076
  };
68037
68077
  }, checkChecksConfig = (res) => {
68038
68078
  const root = checkRoot(res.cwd);
68039
- const current = existsSync14(path34.join(root, CHECKS_FILE));
68040
- const legacy = existsSync14(path34.join(root, LEGACY_CHECKS_FILE));
68079
+ const current = existsSync14(path35.join(root, CHECKS_FILE));
68080
+ const legacy = existsSync14(path35.join(root, LEGACY_CHECKS_FILE));
68041
68081
  if (!legacy)
68042
68082
  return {
68043
68083
  id: "checks_config",
@@ -68052,8 +68092,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
68052
68092
  };
68053
68093
  }, fixChecksConfig = (options = {}) => {
68054
68094
  const root = checkRoot(resolve(options).cwd);
68055
- const from = path34.join(root, LEGACY_CHECKS_FILE);
68056
- const to = path34.join(root, CHECKS_FILE);
68095
+ const from = path35.join(root, LEGACY_CHECKS_FILE);
68096
+ const to = path35.join(root, CHECKS_FILE);
68057
68097
  if (!existsSync14(from))
68058
68098
  return { action: "none", detail: `no ${LEGACY_CHECKS_FILE} at ${root}` };
68059
68099
  if (existsSync14(to))
@@ -68101,7 +68141,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
68101
68141
  }, HOOK_ISSUED_MARKER = "workit-issued-sessions/3", hookRecordsIssued = (root) => {
68102
68142
  let files;
68103
68143
  try {
68104
- files = readdirSync8(path34.join(root, "dist")).filter((f) => f.endsWith(".js"));
68144
+ files = readdirSync8(path35.join(root, "dist")).filter((f) => f.endsWith(".js"));
68105
68145
  } catch {
68106
68146
  return null;
68107
68147
  }
@@ -68109,7 +68149,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
68109
68149
  return null;
68110
68150
  return files.some((file) => {
68111
68151
  try {
68112
- return readFileSync14(path34.join(root, "dist", file), "utf8").includes(HOOK_ISSUED_MARKER);
68152
+ return readFileSync14(path35.join(root, "dist", file), "utf8").includes(HOOK_ISSUED_MARKER);
68113
68153
  } catch {
68114
68154
  return false;
68115
68155
  }
@@ -68325,7 +68365,7 @@ import {
68325
68365
  } from "node:fs";
68326
68366
  import { createRequire as createRequire2 } from "node:module";
68327
68367
  import os10 from "node:os";
68328
- import path35 from "node:path";
68368
+ import path36 from "node:path";
68329
68369
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
68330
68370
  function parseList(raw) {
68331
68371
  return raw.split(",").map((s) => s.trim()).filter(Boolean);
@@ -68370,7 +68410,7 @@ function buildSetupPreview(values, opts = {}) {
68370
68410
  const current = readConfigFromDir(state.configDir);
68371
68411
  mutations.push({
68372
68412
  type: "merge-json",
68373
- path: path35.join(state.configDir, "config.json"),
68413
+ path: path36.join(state.configDir, "config.json"),
68374
68414
  value: {
68375
68415
  locale: values.locale,
68376
68416
  localeOptions: current.localeOptions,
@@ -68396,17 +68436,17 @@ function buildSetupPreview(values, opts = {}) {
68396
68436
  if (blocked.length === 0) {
68397
68437
  mutations.push({
68398
68438
  type: "update-workspaces",
68399
- path: path35.join(state.configDir, "workspaces.json"),
68439
+ path: path36.join(state.configDir, "workspaces.json"),
68400
68440
  entries: values.workspaces,
68401
68441
  expectedRevision: diskWorkspaceResult.revision
68402
68442
  });
68403
68443
  }
68404
68444
  }
68405
68445
  if (values.baseUrl.trim()) {
68406
- const ytPath = path35.join(state.configDir, "youtrack.json");
68446
+ const ytPath = path36.join(state.configDir, "youtrack.json");
68407
68447
  const ytExisting = readConfigRecord(ytPath);
68408
68448
  const ytConfigured = configuredTokenPath(ytExisting, "tokenFile");
68409
- const tokenPath = resolveTokenPath(ytConfigured, path35.join(state.configDir, "youtrack.token"), values.tokenPaths?.youtrack);
68449
+ const tokenPath = resolveTokenPath(ytConfigured, path36.join(state.configDir, "youtrack.token"), values.tokenPaths?.youtrack);
68410
68450
  const draft = youtrackDraft(values, tokenPath);
68411
68451
  if (ytConfigured !== null && tokenPath !== ytConfigured) {
68412
68452
  delete draft.tokenFile;
@@ -68434,7 +68474,7 @@ function buildSetupPreview(values, opts = {}) {
68434
68474
  });
68435
68475
  }
68436
68476
  if (values.vcsProvider !== "skip") {
68437
- const vcsPath = path35.join(state.configDir, "vcs.json");
68477
+ const vcsPath = path36.join(state.configDir, "vcs.json");
68438
68478
  mutations.push({
68439
68479
  type: "merge-json",
68440
68480
  path: vcsPath,
@@ -68463,7 +68503,7 @@ function buildSetupPreview(values, opts = {}) {
68463
68503
  mutations.push({
68464
68504
  type: "install-host",
68465
68505
  platform: "cursor",
68466
- path: path35.join(paths.home, ".cursor", "plugins", "local", ".workit-package-bootstrap"),
68506
+ path: path36.join(paths.home, ".cursor", "plugins", "local", ".workit-package-bootstrap"),
68467
68507
  commands
68468
68508
  });
68469
68509
  }
@@ -68476,7 +68516,7 @@ function buildSetupPreview(values, opts = {}) {
68476
68516
  mutations.push({
68477
68517
  type: "install-host",
68478
68518
  platform,
68479
- path: platform === "claude-code" ? claudeInstallRecord(paths.home, env) : platform === "codex" ? path35.join(env.CODEX_HOME ?? path35.join(paths.home, ".codex"), "plugins", "cache", "workflow-toolkit", "workit") : path35.join(env.PI_CODING_AGENT_DIR ?? path35.join(paths.home, ".pi", "agent"), "settings.json"),
68519
+ path: platform === "claude-code" ? claudeInstallRecord(paths.home, env) : platform === "codex" ? path36.join(env.CODEX_HOME ?? path36.join(paths.home, ".codex"), "plugins", "cache", "workflow-toolkit", "workit") : path36.join(env.PI_CODING_AGENT_DIR ?? path36.join(paths.home, ".pi", "agent"), "settings.json"),
68480
68520
  commands
68481
68521
  });
68482
68522
  }
@@ -68488,7 +68528,7 @@ function buildSetupPreview(values, opts = {}) {
68488
68528
  projectRefused = target.refused;
68489
68529
  if (target?.ok) {
68490
68530
  const root = target.root;
68491
- const gitignorePath = path35.join(root, ".gitignore");
68531
+ const gitignorePath = path36.join(root, ".gitignore");
68492
68532
  const existing = existsSync15(gitignorePath) ? readFileSync15(gitignorePath, "utf8") : "";
68493
68533
  const existingLines = new Set(existing.split(`
68494
68534
  `).map((l) => l.trim()).filter(Boolean));
@@ -68526,7 +68566,7 @@ function deepMerge(base, patch) {
68526
68566
  return out;
68527
68567
  }
68528
68568
  function applyMutation(m) {
68529
- const dir = path35.dirname(m.path);
68569
+ const dir = path36.dirname(m.path);
68530
68570
  switch (m.type) {
68531
68571
  case "create-file": {
68532
68572
  mkdirSync7(dir, { recursive: true });
@@ -68675,7 +68715,7 @@ function applyMutation(m) {
68675
68715
  detail: "already configured"
68676
68716
  };
68677
68717
  }
68678
- mkdirSync7(path35.dirname(m.path), { recursive: true });
68718
+ mkdirSync7(path36.dirname(m.path), { recursive: true });
68679
68719
  writeFileSync8(m.path, JSON.stringify(merged, null, 2) + `
68680
68720
  `, "utf8");
68681
68721
  return existing.kind === "record" ? { platform: "core", file: m.path, status: "Configured" } : { platform: "core", file: m.path, status: "Installed" };
@@ -68684,11 +68724,11 @@ function applyMutation(m) {
68684
68724
  }
68685
68725
  function adapterRoot(platform, res, preferInstalledAdapter = false) {
68686
68726
  const candidates = [];
68687
- const stagedCursor = path35.join(res.home, ".cursor", "plugins", "local", ".workit-package-bootstrap", "node_modules", "@brainervirus", "workit-cursor");
68727
+ const stagedCursor = path36.join(res.home, ".cursor", "plugins", "local", ".workit-package-bootstrap", "node_modules", "@brainervirus", "workit-cursor");
68688
68728
  if (platform === "cursor" && preferInstalledAdapter)
68689
68729
  candidates.push(stagedCursor);
68690
68730
  if (res.dev) {
68691
- candidates.push(path35.join(res.dev, "packages", `workit-${platform}`));
68731
+ candidates.push(path36.join(res.dev, "packages", `workit-${platform}`));
68692
68732
  } else {
68693
68733
  candidates.push(...nodeResolvedAdapters(platform));
68694
68734
  if (platform === "cursor")
@@ -68698,10 +68738,10 @@ function adapterRoot(platform, res, preferInstalledAdapter = false) {
68698
68738
  if (cached)
68699
68739
  candidates.push(cached.root);
68700
68740
  }
68701
- let dir = path35.resolve(res.cwd);
68741
+ let dir = path36.resolve(res.cwd);
68702
68742
  while (true) {
68703
- candidates.push(path35.join(dir, "packages", `workit-${platform}`));
68704
- const parent = path35.dirname(dir);
68743
+ candidates.push(path36.join(dir, "packages", `workit-${platform}`));
68744
+ const parent = path36.dirname(dir);
68705
68745
  if (parent === dir)
68706
68746
  break;
68707
68747
  dir = parent;
@@ -68723,7 +68763,7 @@ function applyOpenCode(root, res) {
68723
68763
  detail: "workit-opencode package has no loadable plugin entry (src/plugin.ts or dist/plugin.js)"
68724
68764
  };
68725
68765
  }
68726
- mkdirSync7(path35.dirname(res.opencodeConfig), { recursive: true });
68766
+ mkdirSync7(path36.dirname(res.opencodeConfig), { recursive: true });
68727
68767
  const existing = readExisting(res.opencodeConfig);
68728
68768
  if (existing.kind === "malformed") {
68729
68769
  return {
@@ -68768,31 +68808,31 @@ function applyOpenCode(root, res) {
68768
68808
  }
68769
68809
  function copyPluginDir(src, dest) {
68770
68810
  const realSrc = realpathSync7(src);
68771
- const marker = path35.join(dest, ".workit-root");
68811
+ const marker = path36.join(dest, ".workit-root");
68772
68812
  const destIsLink = existsSync15(dest) && lstatSync6(dest).isSymbolicLink();
68773
68813
  const synced = !destIsLink && readFileSafe(marker)?.trim() === realSrc && samePluginContent(realSrc, dest, dest);
68774
68814
  if (synced)
68775
68815
  return "Skipped";
68776
68816
  const hadDir = existsSync15(dest);
68777
68817
  const rules = preservedCursorRules(realSrc, dest);
68778
- const parent = path35.dirname(dest);
68818
+ const parent = path36.dirname(dest);
68779
68819
  mkdirSync7(parent, { recursive: true });
68780
- const swap = mkdtempSync2(path35.join(parent, `.${path35.basename(dest)}.swap-`));
68781
- const stage = path35.join(swap, "stage");
68782
- const backup = path35.join(swap, "backup");
68820
+ const swap = mkdtempSync2(path36.join(parent, `.${path36.basename(dest)}.swap-`));
68821
+ const stage = path36.join(swap, "stage");
68822
+ const backup = path36.join(swap, "backup");
68783
68823
  try {
68784
68824
  cpSync4(realSrc, stage, {
68785
68825
  recursive: true,
68786
- filter: (entry) => !path35.relative(realSrc, entry).split(path35.sep).includes("node_modules")
68826
+ filter: (entry) => !path36.relative(realSrc, entry).split(path36.sep).includes("node_modules")
68787
68827
  });
68788
- const stagedHooks = path35.join(stage, CURSOR_HOOKS_FILE);
68828
+ const stagedHooks = path36.join(stage, CURSOR_HOOKS_FILE);
68789
68829
  if (existsSync15(stagedHooks))
68790
68830
  writeFileSync8(stagedHooks, localizedCursorHooks(readFileSync15(stagedHooks), dest));
68791
68831
  for (const [name, content] of rules) {
68792
- mkdirSync7(path35.join(stage, "rules"), { recursive: true });
68793
- writeFileSync8(path35.join(stage, "rules", name), content);
68832
+ mkdirSync7(path36.join(stage, "rules"), { recursive: true });
68833
+ writeFileSync8(path36.join(stage, "rules", name), content);
68794
68834
  }
68795
- writeFileSync8(path35.join(stage, ".workit-root"), realSrc + `
68835
+ writeFileSync8(path36.join(stage, ".workit-root"), realSrc + `
68796
68836
  `, "utf8");
68797
68837
  if (!samePluginContent(realSrc, stage, dest))
68798
68838
  throw new Error("staged adapter content is incomplete");
@@ -68815,7 +68855,7 @@ function copyPluginDir(src, dest) {
68815
68855
  return hadDir ? "Configured" : "Installed";
68816
68856
  }
68817
68857
  function applyCursorSettings(root, res) {
68818
- mkdirSync7(path35.dirname(res.cursorSettings), { recursive: true });
68858
+ mkdirSync7(path36.dirname(res.cursorSettings), { recursive: true });
68819
68859
  const settingsExisting = readExisting(res.cursorSettings);
68820
68860
  if (settingsExisting.kind === "malformed") {
68821
68861
  return {
@@ -68843,7 +68883,7 @@ function applyCursorSettings(root, res) {
68843
68883
  };
68844
68884
  }
68845
68885
  function applyCursorMcp(root, res) {
68846
- mkdirSync7(path35.dirname(res.cursorMcp), { recursive: true });
68886
+ mkdirSync7(path36.dirname(res.cursorMcp), { recursive: true });
68847
68887
  const mcpExisting = readExisting(res.cursorMcp);
68848
68888
  if (mcpExisting.kind === "malformed") {
68849
68889
  return {
@@ -68949,7 +68989,7 @@ function applySetupPreview(preview, options = {}) {
68949
68989
  let cursorCopyOk = false;
68950
68990
  for (const mutation of preview.mutations) {
68951
68991
  if (mutation.type === "install-host") {
68952
- const expectedPath = mutation.platform === "cursor" ? path35.join(res.home, ".cursor", "plugins", "local", ".workit-package-bootstrap") : mutation.platform === "codex" ? path35.join(res.env.CODEX_HOME ?? path35.join(res.home, ".codex"), "plugins", "cache", "workflow-toolkit", "workit") : mutation.platform === "pi" ? path35.join(res.env.PI_CODING_AGENT_DIR ?? path35.join(res.home, ".pi", "agent"), "settings.json") : mutation.platform === "claude-code" ? claudeInstallRecord(res.home, res.env) : "";
68992
+ const expectedPath = mutation.platform === "cursor" ? path36.join(res.home, ".cursor", "plugins", "local", ".workit-package-bootstrap") : mutation.platform === "codex" ? path36.join(res.env.CODEX_HOME ?? path36.join(res.home, ".codex"), "plugins", "cache", "workflow-toolkit", "workit") : mutation.platform === "pi" ? path36.join(res.env.PI_CODING_AGENT_DIR ?? path36.join(res.home, ".pi", "agent"), "settings.json") : mutation.platform === "claude-code" ? claudeInstallRecord(res.home, res.env) : "";
68953
68993
  if (mutation.path !== expectedPath) {
68954
68994
  entries.push({
68955
68995
  platform: mutation.platform,
@@ -69061,7 +69101,7 @@ function applySetupPreview(preview, options = {}) {
69061
69101
  if (preview.projectRefused) {
69062
69102
  entries.push({
69063
69103
  platform: "core",
69064
- file: path35.resolve(res.cwd),
69104
+ file: path36.resolve(res.cwd),
69065
69105
  status: "Skipped",
69066
69106
  detail: preview.projectRefused
69067
69107
  });
@@ -69147,7 +69187,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
69147
69187
  } catch {
69148
69188
  return null;
69149
69189
  }
69150
- }, claudeInstallRecord = (home, env) => path35.join(claudeConfigDir(home, env), "plugins", "installed_plugins.json"), resolveSetupPaths = (options, resolvedConfigDir) => {
69190
+ }, claudeInstallRecord = (home, env) => path36.join(claudeConfigDir(home, env), "plugins", "installed_plugins.json"), resolveSetupPaths = (options, resolvedConfigDir) => {
69151
69191
  const env = options.env ?? process.env;
69152
69192
  const home = options.home ?? env.HOME ?? os10.homedir();
69153
69193
  return {
@@ -69155,10 +69195,10 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
69155
69195
  configDir: resolvedConfigDir,
69156
69196
  cwd: options.cwd ?? process.cwd(),
69157
69197
  env,
69158
- opencodeConfig: options.opencodeConfig ?? path35.join(home, ".config", "opencode", "opencode.json"),
69159
- cursorSettings: options.cursorSettings ?? path35.join(home, ".cursor", "settings.json"),
69160
- cursorMcp: options.cursorMcp ?? path35.join(home, ".cursor", "mcp.json"),
69161
- cursorPluginDir: options.cursorPluginDir ?? path35.join(home, ".cursor", "plugins", "local", "workit")
69198
+ opencodeConfig: options.opencodeConfig ?? path36.join(home, ".config", "opencode", "opencode.json"),
69199
+ cursorSettings: options.cursorSettings ?? path36.join(home, ".cursor", "settings.json"),
69200
+ cursorMcp: options.cursorMcp ?? path36.join(home, ".cursor", "mcp.json"),
69201
+ cursorPluginDir: options.cursorPluginDir ?? path36.join(home, ".cursor", "plugins", "local", "workit")
69162
69202
  };
69163
69203
  }, isRecord5 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), readExisting = (p) => {
69164
69204
  let raw;
@@ -69195,15 +69235,15 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
69195
69235
  }
69196
69236
  }, isAdapter = (root, platform) => {
69197
69237
  try {
69198
- const pkg = JSON.parse(readFileSync15(path35.join(root, "package.json"), "utf8"));
69238
+ const pkg = JSON.parse(readFileSync15(path36.join(root, "package.json"), "utf8"));
69199
69239
  return pkg.name === `@brainervirus/workit-${platform}`;
69200
69240
  } catch {
69201
69241
  return false;
69202
69242
  }
69203
69243
  }, nodeResolvedAdapters = (platform) => {
69204
69244
  const name = `@brainervirus/workit-${platform}`;
69205
- const require2 = createRequire2(path35.join(packageRoot(), "package.json"));
69206
- return (require2.resolve.paths(name) ?? []).map((dir) => path35.join(dir, name));
69245
+ const require2 = createRequire2(path36.join(packageRoot(), "package.json"));
69246
+ return (require2.resolve.paths(name) ?? []).map((dir) => path36.join(dir, name));
69207
69247
  }, realRoot = (root) => {
69208
69248
  try {
69209
69249
  return realpathSync7(root);
@@ -69219,7 +69259,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
69219
69259
  if (!isDevOpenCodeAdapterRoot(root, opts.dev))
69220
69260
  return OPENCODE_NPM_PIN;
69221
69261
  for (const rel of ["src/plugin.ts", "dist/plugin.js"]) {
69222
- const entry = path35.join(root, rel);
69262
+ const entry = path36.join(root, rel);
69223
69263
  if (existsSync15(entry))
69224
69264
  return `file://${entry}`;
69225
69265
  }
@@ -69237,9 +69277,9 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
69237
69277
  for (const entry of readdirSync9(src, { withFileTypes: true })) {
69238
69278
  if (entry.name === "node_modules")
69239
69279
  continue;
69240
- const source = path35.join(src, entry.name);
69241
- const installed = path35.join(dest, entry.name);
69242
- const rel = path35.join(relative, entry.name);
69280
+ const source = path36.join(src, entry.name);
69281
+ const installed = path36.join(dest, entry.name);
69282
+ const rel = path36.join(relative, entry.name);
69243
69283
  if (entry.isDirectory()) {
69244
69284
  if (!statSync6(installed).isDirectory() || !samePluginContent(source, installed, pluginDir, rel))
69245
69285
  return false;
@@ -69250,9 +69290,9 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
69250
69290
  }
69251
69291
  }
69252
69292
  for (const entry of readdirSync9(dest, { withFileTypes: true })) {
69253
- if (existsSync15(path35.join(src, entry.name)))
69293
+ if (existsSync15(path36.join(src, entry.name)))
69254
69294
  continue;
69255
- const rel = path35.join(relative, entry.name);
69295
+ const rel = path36.join(relative, entry.name);
69256
69296
  if (rel === ".workit-root")
69257
69297
  continue;
69258
69298
  if (relative === "rules" && entry.isFile() && entry.name.endsWith(".mdc"))
@@ -69265,32 +69305,32 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
69265
69305
  }
69266
69306
  }, preservedCursorRules = (src, dest) => {
69267
69307
  const preserved = new Map;
69268
- const sourceRules = path35.join(src, "rules");
69269
- const installedRules = path35.join(dest, "rules");
69308
+ const sourceRules = path36.join(src, "rules");
69309
+ const installedRules = path36.join(dest, "rules");
69270
69310
  try {
69271
69311
  for (const entry of readdirSync9(installedRules, { withFileTypes: true })) {
69272
69312
  if (!entry.isFile() || !entry.name.endsWith(".mdc"))
69273
69313
  continue;
69274
- if (existsSync15(path35.join(sourceRules, entry.name)))
69314
+ if (existsSync15(path36.join(sourceRules, entry.name)))
69275
69315
  continue;
69276
- preserved.set(entry.name, readFileSync15(path35.join(installedRules, entry.name)));
69316
+ preserved.set(entry.name, readFileSync15(path36.join(installedRules, entry.name)));
69277
69317
  }
69278
69318
  } catch {}
69279
69319
  return preserved;
69280
69320
  }, removeLegacyCursorDir = (res) => {
69281
- const legacy = path35.join(res.home, ".cursor", "plugins", "local", "workflow-toolkit");
69321
+ const legacy = path36.join(res.home, ".cursor", "plugins", "local", "workflow-toolkit");
69282
69322
  if (legacy === res.cursorPluginDir || !existsSync15(legacy))
69283
69323
  return;
69284
- const legacyRules = path35.join(legacy, "rules");
69324
+ const legacyRules = path36.join(legacy, "rules");
69285
69325
  if (existsSync15(legacyRules)) {
69286
69326
  try {
69287
- mkdirSync7(path35.join(res.cursorPluginDir, "rules"), { recursive: true });
69327
+ mkdirSync7(path36.join(res.cursorPluginDir, "rules"), { recursive: true });
69288
69328
  for (const entry of readdirSync9(legacyRules, { withFileTypes: true })) {
69289
69329
  if (!entry.isFile() || !entry.name.endsWith(".mdc"))
69290
69330
  continue;
69291
- const target = path35.join(res.cursorPluginDir, "rules", entry.name);
69331
+ const target = path36.join(res.cursorPluginDir, "rules", entry.name);
69292
69332
  if (!existsSync15(target))
69293
- copyFileSync4(path35.join(legacyRules, entry.name), target);
69333
+ copyFileSync4(path36.join(legacyRules, entry.name), target);
69294
69334
  }
69295
69335
  } catch {}
69296
69336
  }
@@ -69324,16 +69364,16 @@ var init_setup = __esm(() => {
69324
69364
  { envKey: "WORKFLOW_GITHUB_HOST", affects: "vcs.json github.host" }
69325
69365
  ];
69326
69366
  SETUP_OVERRIDES = [...YT_OVERRIDES, ...VCS_OVERRIDES];
69327
- CURSOR_HOOKS_FILE = path35.join("hooks", "hooks-cursor.json");
69367
+ CURSOR_HOOKS_FILE = path36.join("hooks", "hooks-cursor.json");
69328
69368
  });
69329
69369
 
69330
69370
  // packages/workit-core/src/core/workspace-branch-policy.ts
69331
69371
  import { mkdirSync as mkdirSync8, readFileSync as readFileSync16, renameSync as renameSync6, rmSync as rmSync5, writeFileSync as writeFileSync9 } from "node:fs";
69332
- import path36 from "node:path";
69372
+ import path37 from "node:path";
69333
69373
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
69334
69374
  function applyWorkspaceBranchPolicy(opts) {
69335
69375
  const { workspace_root, env = process.env } = opts;
69336
- const dir = path36.join(env.WORKFLOW_TOOLKIT_CONFIG ?? configDir());
69376
+ const dir = path37.join(env.WORKFLOW_TOOLKIT_CONFIG ?? configDir());
69337
69377
  const {
69338
69378
  status,
69339
69379
  path: wsPath,
@@ -69345,7 +69385,7 @@ function applyWorkspaceBranchPolicy(opts) {
69345
69385
  if (status === "malformed" || status === "invalid")
69346
69386
  return { ok: false, error: workspacesError ?? `invalid workspaces.json: ${wsPath}` };
69347
69387
  const detection = detectBranchPolicy(workspace_root);
69348
- const name = String(env.WORKFLOW_BP_NAME ?? path36.basename(workspace_root));
69388
+ const name = String(env.WORKFLOW_BP_NAME ?? path37.basename(workspace_root));
69349
69389
  const integration = env.WORKFLOW_BP_INTEGRATION ?? detection.integration;
69350
69390
  const policy = {
69351
69391
  preset: detection.preset,
@@ -69394,7 +69434,7 @@ function applyWorkspaceBranchPolicy(opts) {
69394
69434
  ok: false,
69395
69435
  error: `workspaces.json changed while applying the branch policy: ${wsPath}`
69396
69436
  };
69397
- mkdirSync8(path36.dirname(wsPath), { recursive: true });
69437
+ mkdirSync8(path37.dirname(wsPath), { recursive: true });
69398
69438
  const tmp = `${wsPath}.${process.pid}.tmp`;
69399
69439
  try {
69400
69440
  writeFileSync9(tmp, JSON.stringify({ ...document2, workspaces: next }, null, 2) + `
@@ -69679,7 +69719,7 @@ var init_logic = __esm(() => {
69679
69719
 
69680
69720
  // packages/workit-cli/src/wizard-state.ts
69681
69721
  import { existsSync as existsSync16, statSync as statSync7 } from "node:fs";
69682
- import path37 from "node:path";
69722
+ import path38 from "node:path";
69683
69723
  import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
69684
69724
  function resolveBasePath(values, env = process.env) {
69685
69725
  return env.WORKFLOW_WORKSPACE_ROOT?.trim() || values.basePath.trim();
@@ -70206,8 +70246,8 @@ var NEXT, PREV, skipsCustomBranch = (screen, preset) => (screen === "branchAllow
70206
70246
  const p = value.trim();
70207
70247
  if (!p)
70208
70248
  return "workspace root path is required";
70209
- return !path37.isAbsolute(p) || !isDirectory(p) ? `invalid workspace root "${p}" — enter an existing absolute directory` : null;
70210
- }, skipsBranchPolicy = (screen, basePath) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !existsSync16(path37.join(basePath, ".git")), decodeBranchPreset = (value, fallback) => value === "gitflow" || value === "github-flow" || value === "trunk-based" || value === "custom" ? value : fallback, decodeVcsProvider = (value, fallback) => value === "gitlab" || value === "github" || value === "skip" ? value : fallback, decodeIssueTracker = (value, fallback) => value === "youtrack" || value === "github" || value === "gitlab" || value === "none" ? value : fallback, GITHUB_ISSUES, withGithubIssues = (draft, tracker) => tracker === "github" ? { ...draft, issues: { ...GITHUB_ISSUES } } : draft;
70249
+ return !path38.isAbsolute(p) || !isDirectory(p) ? `invalid workspace root "${p}" — enter an existing absolute directory` : null;
70250
+ }, skipsBranchPolicy = (screen, basePath) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !existsSync16(path38.join(basePath, ".git")), decodeBranchPreset = (value, fallback) => value === "gitflow" || value === "github-flow" || value === "trunk-based" || value === "custom" ? value : fallback, decodeVcsProvider = (value, fallback) => value === "gitlab" || value === "github" || value === "skip" ? value : fallback, decodeIssueTracker = (value, fallback) => value === "youtrack" || value === "github" || value === "gitlab" || value === "none" ? value : fallback, GITHUB_ISSUES, withGithubIssues = (draft, tracker) => tracker === "github" ? { ...draft, issues: { ...GITHUB_ISSUES } } : draft;
70211
70251
  var init_wizard_state = __esm(() => {
70212
70252
  init_config();
70213
70253
  init_workspaces();
@@ -70268,7 +70308,7 @@ var init_wizard_state = __esm(() => {
70268
70308
  // packages/workit-cli/src/admin/uninstall.ts
70269
70309
  import { existsSync as existsSync17, readFileSync as readFileSync17, realpathSync as realpathSync8, rmSync as rmSync6, writeFileSync as writeFileSync10 } from "node:fs";
70270
70310
  import os11 from "node:os";
70271
- import path38 from "node:path";
70311
+ import path39 from "node:path";
70272
70312
  function cleanCursorSettings(settings, pluginDir) {
70273
70313
  const next = { ...settings };
70274
70314
  let changed = false;
@@ -70443,8 +70483,8 @@ function applyUninstall(plan, paths = {}) {
70443
70483
  status = outcome.status;
70444
70484
  detail = outcome.detail;
70445
70485
  } else if (action.kind === "remove-dir") {
70446
- const resolved = path38.resolve(action.path);
70447
- const allowed = canonicalRemoveDirAllowed(resolved, res) || resolved === path38.resolve(res.codexPluginDir) && path38.basename(resolved) === "workit" && path38.basename(path38.dirname(resolved)) === "plugins";
70486
+ const resolved = path39.resolve(action.path);
70487
+ const allowed = canonicalRemoveDirAllowed(resolved, res) || resolved === path39.resolve(res.codexPluginDir) && path39.basename(resolved) === "workit" && path39.basename(path39.dirname(resolved)) === "plugins";
70448
70488
  if (!allowed) {
70449
70489
  status = "failed";
70450
70490
  detail = `refusing to remove non-canonical plugin directory: ${resolved}`;
@@ -70479,12 +70519,12 @@ function applyUninstall(plan, paths = {}) {
70479
70519
  var resolveUninstallPaths = (options = {}) => {
70480
70520
  const home = options.home ?? options.env?.HOME ?? os11.homedir();
70481
70521
  return {
70482
- opencodeConfig: options.opencodeConfig ?? path38.join(home, ".config", "opencode", "opencode.json"),
70483
- cursorSettings: options.cursorSettings ?? path38.join(home, ".cursor", "settings.json"),
70484
- cursorMcp: options.cursorMcp ?? path38.join(home, ".cursor", "mcp.json"),
70485
- cursorPluginDir: options.cursorPluginDir ?? path38.join(home, ".cursor", "plugins", "local", "workit"),
70486
- codexPluginDir: path38.join(home, ".codex", "plugins", "workit"),
70487
- piConfig: path38.join(home, ".pi", "config.json")
70522
+ opencodeConfig: options.opencodeConfig ?? path39.join(home, ".config", "opencode", "opencode.json"),
70523
+ cursorSettings: options.cursorSettings ?? path39.join(home, ".cursor", "settings.json"),
70524
+ cursorMcp: options.cursorMcp ?? path39.join(home, ".cursor", "mcp.json"),
70525
+ cursorPluginDir: options.cursorPluginDir ?? path39.join(home, ".cursor", "plugins", "local", "workit"),
70526
+ codexPluginDir: path39.join(home, ".codex", "plugins", "workit"),
70527
+ piConfig: path39.join(home, ".pi", "config.json")
70488
70528
  };
70489
70529
  }, isRecord6 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), readJsonRecord = (file) => {
70490
70530
  let raw;
@@ -70502,8 +70542,8 @@ var resolveUninstallPaths = (options = {}) => {
70502
70542
  return { kind: "malformed", error: `${file} is not valid JSON` };
70503
70543
  }
70504
70544
  }, stripTrailingSep = (p) => {
70505
- const j = path38.join(p);
70506
- return path38.dirname(j) === j ? j : j.replace(/[\\/]+$/, "");
70545
+ const j = path39.join(p);
70546
+ return path39.dirname(j) === j ? j : j.replace(/[\\/]+$/, "");
70507
70547
  }, CURSOR_LEGACY_IDENTITIES, jsonCleanerFor = (target, res) => {
70508
70548
  if (target === res.opencodeConfig)
70509
70549
  return cleanOpenCodeConfig;
@@ -70515,8 +70555,8 @@ var resolveUninstallPaths = (options = {}) => {
70515
70555
  return cleanPiConfig;
70516
70556
  return null;
70517
70557
  }, canonicalRemoveDirAllowed = (actionPath, res) => {
70518
- const expected = path38.resolve(res.cursorPluginDir);
70519
- if (!(actionPath === expected && path38.basename(expected) === "workit" && path38.basename(path38.dirname(expected)) === "local" && path38.basename(path38.dirname(path38.dirname(expected))) === "plugins")) {
70558
+ const expected = path39.resolve(res.cursorPluginDir);
70559
+ if (!(actionPath === expected && path39.basename(expected) === "workit" && path39.basename(path39.dirname(expected)) === "local" && path39.basename(path39.dirname(path39.dirname(expected))) === "plugins")) {
70520
70560
  return false;
70521
70561
  }
70522
70562
  try {
@@ -70568,7 +70608,7 @@ var resolveUninstallPaths = (options = {}) => {
70568
70608
  };
70569
70609
  const home = paths.home ?? paths.env?.HOME ?? os11.homedir();
70570
70610
  const env = paths.env ?? process.env;
70571
- const recorded = claudeWorkitInstalls(home, env, action.cwd).some((install) => install.id === id && install.scope === scope && (install.projectPath === null ? action.cwd === null : path38.resolve(install.projectPath) === path38.resolve(action.cwd ?? "")));
70611
+ const recorded = claudeWorkitInstalls(home, env, action.cwd).some((install) => install.id === id && install.scope === scope && (install.projectPath === null ? action.cwd === null : path39.resolve(install.projectPath) === path39.resolve(action.cwd ?? "")));
70572
70612
  if (!recorded)
70573
70613
  return { status: "skipped", detail: `${id} (${scope} scope) is no longer installed` };
70574
70614
  const executable = findHostExecutable("claude", { home, env });
@@ -73124,7 +73164,7 @@ import {
73124
73164
  cpSync as cpSync5,
73125
73165
  lstatSync as lstatSync7
73126
73166
  } from "node:fs";
73127
- import path39 from "node:path";
73167
+ import path40 from "node:path";
73128
73168
  import os13 from "node:os";
73129
73169
  import { createHash as createHash15 } from "node:crypto";
73130
73170
  function previewUpgrade(hosts = HOSTS2, deps = {}) {
@@ -73148,9 +73188,9 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
73148
73188
  for (const file of [
73149
73189
  paths.opencodeConfig,
73150
73190
  paths.opencodeConfig + "c",
73151
- path39.join(home, ".cursor/settings.json"),
73152
- path39.join(home, ".cursor/mcp.json"),
73153
- path39.join(home, ".cursor/plugins/local/workit/package.json"),
73191
+ path40.join(home, ".cursor/settings.json"),
73192
+ path40.join(home, ".cursor/mcp.json"),
73193
+ path40.join(home, ".cursor/plugins/local/workit/package.json"),
73154
73194
  paths.codexConfig,
73155
73195
  paths.piSettings
73156
73196
  ])
@@ -73165,16 +73205,16 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
73165
73205
  });
73166
73206
  const installedSources = sources(paths, run, hosts);
73167
73207
  if (installedSources.some((source) => source.host === "opencode")) {
73168
- const scratch = mkdtempSync3(path39.join(os13.tmpdir(), "workit-upgrade-opencode-"));
73208
+ const scratch = mkdtempSync3(path40.join(os13.tmpdir(), "workit-upgrade-opencode-"));
73169
73209
  let probe;
73170
73210
  try {
73171
73211
  probe = runner({
73172
73212
  ...deps,
73173
73213
  env: {
73174
73214
  ...deps.env,
73175
- XDG_DATA_HOME: path39.join(scratch, "data"),
73176
- XDG_STATE_HOME: path39.join(scratch, "state"),
73177
- XDG_CACHE_HOME: path39.join(scratch, "cache")
73215
+ XDG_DATA_HOME: path40.join(scratch, "data"),
73216
+ XDG_STATE_HOME: path40.join(scratch, "state"),
73217
+ XDG_CACHE_HOME: path40.join(scratch, "cache")
73178
73218
  }
73179
73219
  })("opencode", ["--version"]);
73180
73220
  } finally {
@@ -73220,7 +73260,7 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
73220
73260
  env: deps.env,
73221
73261
  cwd: home,
73222
73262
  packageVersion: latest.stdout.trim(),
73223
- targetDir: path39.join(home, ".cursor/plugins/local/workit")
73263
+ targetDir: path40.join(home, ".cursor/plugins/local/workit")
73224
73264
  });
73225
73265
  plan.entries.push({
73226
73266
  host: source.host,
@@ -73250,11 +73290,11 @@ function applyUpgrade(plan, deps = {}) {
73250
73290
  ok: false,
73251
73291
  error: "Stop the selected running hosts before upgrading their loaded plugins"
73252
73292
  };
73253
- const backup = path39.join(home, ".local/state/workit/upgrades", new Date().toISOString().replaceAll(":", "-"));
73293
+ const backup = path40.join(home, ".local/state/workit/upgrades", new Date().toISOString().replaceAll(":", "-"));
73254
73294
  mkdirSync9(backup, { recursive: true, mode: 448 });
73255
73295
  for (const file of Object.keys(plan.configDigests))
73256
73296
  if (existsSync18(file)) {
73257
- const target = path39.join(backup, createHash15("sha256").update(file).digest("hex").slice(0, 12) + "-" + path39.basename(file));
73297
+ const target = path40.join(backup, createHash15("sha256").update(file).digest("hex").slice(0, 12) + "-" + path40.basename(file));
73258
73298
  copyFileSync5(file, target);
73259
73299
  chmodSync2(target, 384);
73260
73300
  }
@@ -73271,9 +73311,9 @@ function applyUpgrade(plan, deps = {}) {
73271
73311
  `, 384);
73272
73312
  }
73273
73313
  const run = runner(deps);
73274
- const cursorRoot = path39.join(home, ".cursor/plugins/local/workit");
73314
+ const cursorRoot = path40.join(home, ".cursor/plugins/local/workit");
73275
73315
  if (plan.entries.some((entry) => entry.host === "cursor") && existsSync18(cursorRoot))
73276
- cpSync5(cursorRoot, path39.join(backup, "cursor-package"), { recursive: true });
73316
+ cpSync5(cursorRoot, path40.join(backup, "cursor-package"), { recursive: true });
73277
73317
  for (const entry of plan.entries) {
73278
73318
  if (entry.host === "opencode")
73279
73319
  return {
@@ -73293,7 +73333,7 @@ function applyUpgrade(plan, deps = {}) {
73293
73333
  {
73294
73334
  type: "install-host",
73295
73335
  platform: "cursor",
73296
- path: path39.join(home, ".cursor/plugins/local/.workit-package-bootstrap"),
73336
+ path: path40.join(home, ".cursor/plugins/local/.workit-package-bootstrap"),
73297
73337
  commands: entry.commands.map((command) => ({
73298
73338
  ...command,
73299
73339
  purpose: command.purpose ?? "Upgrade Cursor"
@@ -73302,7 +73342,7 @@ function applyUpgrade(plan, deps = {}) {
73302
73342
  {
73303
73343
  type: "install-adapter",
73304
73344
  platform: "cursor",
73305
- path: path39.join(home, ".cursor/plugins/local/workit")
73345
+ path: path40.join(home, ".cursor/plugins/local/workit")
73306
73346
  }
73307
73347
  ]
73308
73348
  };
@@ -73316,7 +73356,7 @@ function applyUpgrade(plan, deps = {}) {
73316
73356
  return { exitCode: outcome.status ?? 1, stdout: outcome.stdout, stderr: "" };
73317
73357
  }
73318
73358
  });
73319
- const pkg = object2(path39.join(home, ".cursor/plugins/local/workit/package.json"));
73359
+ const pkg = object2(path40.join(home, ".cursor/plugins/local/workit/package.json"));
73320
73360
  if (!result.ok || pkg?.version !== entry.latest)
73321
73361
  return {
73322
73362
  ok: false,
@@ -73350,15 +73390,15 @@ function applyUpgrade(plan, deps = {}) {
73350
73390
  const currentRoot = run("npm", ["root", "--global"]);
73351
73391
  if (currentRoot.status !== 0 || currentRoot.stdout.trim() !== plan.cli.root)
73352
73392
  return { ok: false, backup, error: "Global npm location changed; preview again" };
73353
- const cliBackup = path39.join(backup, "cli-package");
73354
- cpSync5(path39.join(plan.cli.root, "@brainervirus/workit-cli"), cliBackup, { recursive: true });
73393
+ const cliBackup = path40.join(backup, "cli-package");
73394
+ cpSync5(path40.join(plan.cli.root, "@brainervirus/workit-cli"), cliBackup, { recursive: true });
73355
73395
  if (run("npm", ["install", "--global", `@brainervirus/workit-cli@${plan.cli.latest}`]).status !== 0)
73356
73396
  return {
73357
73397
  ok: false,
73358
73398
  backup,
73359
- error: `CLI update failed; preserved package at ${cliBackup}; use npm to repair or run node ${path39.join(cliBackup, "dist/index.js")}`
73399
+ error: `CLI update failed; preserved package at ${cliBackup}; use npm to repair or run node ${path40.join(cliBackup, "dist/index.js")}`
73360
73400
  };
73361
- const installed = object2(path39.join(plan.cli.root, "@brainervirus/workit-cli/package.json"));
73401
+ const installed = object2(path40.join(plan.cli.root, "@brainervirus/workit-cli/package.json"));
73362
73402
  if (installed?.name !== "@brainervirus/workit-cli" || installed.version !== plan.cli.latest)
73363
73403
  return {
73364
73404
  ok: false,
@@ -73383,12 +73423,12 @@ async function runUpgradeCommand(argv, deps = {}) {
73383
73423
  if (flags.has("--cli")) {
73384
73424
  const run = runner(deps);
73385
73425
  const root = run("npm", ["root", "--global"]);
73386
- if (root.status !== 0 || !path39.isAbsolute(root.stdout.trim())) {
73426
+ if (root.status !== 0 || !path40.isAbsolute(root.stdout.trim())) {
73387
73427
  plan.blocked.push("Global npm location could not be verified");
73388
73428
  } else {
73389
- const packageFile = path39.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
73429
+ const packageFile = path40.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
73390
73430
  const pkg = object2(packageFile);
73391
- if (pkg?.name !== "@brainervirus/workit-cli" || lstatSync7(path39.dirname(packageFile)).isSymbolicLink()) {
73431
+ if (pkg?.name !== "@brainervirus/workit-cli" || lstatSync7(path40.dirname(packageFile)).isSymbolicLink()) {
73392
73432
  plan.skipped.push({
73393
73433
  host: "cli",
73394
73434
  reason: "No managed global CLI install (local links preserved); use npx @brainervirus/workit-cli@latest"
@@ -73479,23 +73519,23 @@ var HOSTS2, upgradePaths = (deps) => {
73479
73519
  ...process.env,
73480
73520
  ...deps.home || deps.env?.HOME ? {
73481
73521
  HOME: home,
73482
- CODEX_HOME: path39.join(home, ".codex"),
73483
- PI_CODING_AGENT_DIR: path39.join(home, ".pi/agent"),
73484
- XDG_CONFIG_HOME: path39.join(home, ".config"),
73522
+ CODEX_HOME: path40.join(home, ".codex"),
73523
+ PI_CODING_AGENT_DIR: path40.join(home, ".pi/agent"),
73524
+ XDG_CONFIG_HOME: path40.join(home, ".config"),
73485
73525
  WORKFLOW_TOOLKIT_CONFIG: undefined,
73486
73526
  WORKFLOW_TOOLKIT_CONFIG_DIR: undefined
73487
73527
  } : {},
73488
73528
  ...deps.env,
73489
73529
  HOME: home
73490
73530
  };
73491
- const xdg = env.XDG_CONFIG_HOME || path39.join(home, ".config");
73531
+ const xdg = env.XDG_CONFIG_HOME || path40.join(home, ".config");
73492
73532
  return {
73493
73533
  home,
73494
73534
  env,
73495
- configDir: env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path39.join(xdg, "workit"),
73496
- opencodeConfig: path39.join(xdg, "opencode/opencode.json"),
73497
- piSettings: path39.join(env.PI_CODING_AGENT_DIR ?? path39.join(home, ".pi/agent"), "settings.json"),
73498
- codexConfig: path39.join(env.CODEX_HOME ?? path39.join(home, ".codex"), "config.toml")
73535
+ configDir: env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path40.join(xdg, "workit"),
73536
+ opencodeConfig: path40.join(xdg, "opencode/opencode.json"),
73537
+ piSettings: path40.join(env.PI_CODING_AGENT_DIR ?? path40.join(home, ".pi/agent"), "settings.json"),
73538
+ codexConfig: path40.join(env.CODEX_HOME ?? path40.join(home, ".codex"), "config.toml")
73499
73539
  };
73500
73540
  }, object2 = (file) => {
73501
73541
  if (!existsSync18(file))
@@ -73535,9 +73575,9 @@ var HOSTS2, upgradePaths = (deps) => {
73535
73575
  for (const pin of plugins)
73536
73576
  if (typeof pin === "string" && isWorkitPlugin(pin))
73537
73577
  result.push(classify("opencode", pin));
73538
- const cursor = hosts.includes("cursor") ? object2(path39.join(home, ".cursor/plugins/local/workit/package.json")) : null;
73578
+ const cursor = hosts.includes("cursor") ? object2(path40.join(home, ".cursor/plugins/local/workit/package.json")) : null;
73539
73579
  if (cursor?.name === "@brainervirus/workit-cursor") {
73540
- const mcp = object2(path39.join(home, ".cursor/mcp.json"));
73580
+ const mcp = object2(path40.join(home, ".cursor/mcp.json"));
73541
73581
  const args = mcp?.mcpServers?.workit?.args ?? [];
73542
73582
  const selector = args.find((arg) => typeof arg === "string" && arg.startsWith("--package="));
73543
73583
  result.push(classify("cursor", typeof selector === "string" ? selector.slice(10) : "local"));
@@ -73550,7 +73590,7 @@ var HOSTS2, upgradePaths = (deps) => {
73550
73590
  if (typeof source !== "string")
73551
73591
  continue;
73552
73592
  const npm = /^(?:npm:)?@brainervirus\/workit-pi(?:@[^/]+)?$/.test(source);
73553
- const local = path39.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path39.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
73593
+ const local = path40.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path40.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
73554
73594
  if (npm || local)
73555
73595
  result.push(classify("pi", source));
73556
73596
  }
@@ -73597,9 +73637,9 @@ var HOSTS2, upgradePaths = (deps) => {
73597
73637
  }, piInstalledVersion = (listing, selector) => {
73598
73638
  const lines = listing.split(/\r?\n/).map((line) => line.trim());
73599
73639
  const index = lines.indexOf(selector);
73600
- if (index < 0 || !lines[index + 1] || !path39.isAbsolute(lines[index + 1]))
73640
+ if (index < 0 || !lines[index + 1] || !path40.isAbsolute(lines[index + 1]))
73601
73641
  return;
73602
- const pkg = object2(path39.join(lines[index + 1], "package.json"));
73642
+ const pkg = object2(path40.join(lines[index + 1], "package.json"));
73603
73643
  return pkg?.name === "@brainervirus/workit-pi" ? pkg.version : undefined;
73604
73644
  }, versionAtLeast = (installed, latest) => {
73605
73645
  if (!/^\d+\.\d+\.\d+$/.test(installed))
@@ -73651,8 +73691,8 @@ var init_launch = __esm(() => {
73651
73691
 
73652
73692
  // packages/workit-core/src/knowledge.ts
73653
73693
  import { spawnSync as spawnSync18 } from "node:child_process";
73654
- import fs19 from "node:fs";
73655
- import path40 from "node:path";
73694
+ import fs20 from "node:fs";
73695
+ import path41 from "node:path";
73656
73696
  function lintKnowledge(root) {
73657
73697
  const seen = new Set;
73658
73698
  const unreadable = [];
@@ -73756,17 +73796,17 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
73756
73796
  const end = lines.indexOf("---", 1);
73757
73797
  return end === -1 ? lines : [...lines.slice(0, end + 1).map(() => ""), ...lines.slice(end + 1)];
73758
73798
  }, read = (root, file) => {
73759
- const full = path40.join(root, file);
73799
+ const full = path41.join(root, file);
73760
73800
  try {
73761
- fs19.lstatSync(full);
73801
+ fs20.lstatSync(full);
73762
73802
  } catch {
73763
73803
  return null;
73764
73804
  }
73765
73805
  try {
73766
- if (!fs19.statSync(full).isFile())
73806
+ if (!fs20.statSync(full).isFile())
73767
73807
  return null;
73768
- const text = fs19.readFileSync(full, "utf8");
73769
- return { file, text, lines: text.split(/\r?\n/), real: fs19.realpathSync(full) };
73808
+ const text = fs20.readFileSync(full, "utf8");
73809
+ return { file, text, lines: text.split(/\r?\n/), real: fs20.realpathSync(full) };
73770
73810
  } catch {
73771
73811
  return "unreadable";
73772
73812
  }
@@ -73783,7 +73823,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
73783
73823
  return new Set(run.stdout.split("\x00").filter(Boolean).map((file) => file.split("/")[0]));
73784
73824
  }, exists2 = (target) => {
73785
73825
  try {
73786
- fs19.statSync(target);
73826
+ fs20.statSync(target);
73787
73827
  return true;
73788
73828
  } catch {
73789
73829
  return false;
@@ -73797,7 +73837,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
73797
73837
  }
73798
73838
  }, brokenLinks = (root, doc, tracked) => {
73799
73839
  const findings = [];
73800
- const base = path40.dirname(path40.join(root, doc.file));
73840
+ const base = path41.dirname(path41.join(root, doc.file));
73801
73841
  const missing = (target, line, how) => findings.push({
73802
73842
  rule: "broken-link",
73803
73843
  file: doc.file,
@@ -73816,7 +73856,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
73816
73856
  const local = localTarget(target);
73817
73857
  if (!local)
73818
73858
  continue;
73819
- const resolved = local.startsWith("/") ? path40.join(root, local) : path40.resolve(base, local);
73859
+ const resolved = local.startsWith("/") ? path41.join(root, local) : path41.resolve(base, local);
73820
73860
  if (!exists2(resolved))
73821
73861
  missing(target, index + 1, "link");
73822
73862
  }
@@ -73826,9 +73866,9 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
73826
73866
  continue;
73827
73867
  const relative = /^\.\.?\//.test(candidate);
73828
73868
  const first = candidate.split("/")[0];
73829
- if (!relative && !(tracked ? tracked.has(first) : exists2(path40.join(root, first))))
73869
+ if (!relative && !(tracked ? tracked.has(first) : exists2(path41.join(root, first))))
73830
73870
  continue;
73831
- const resolved = relative ? path40.resolve(base, candidate) : path40.join(root, candidate);
73871
+ const resolved = relative ? path41.resolve(base, candidate) : path41.join(root, candidate);
73832
73872
  if (!exists2(resolved))
73833
73873
  missing(span, index + 1, "pointer");
73834
73874
  }
@@ -74190,9 +74230,9 @@ var init_redact = __esm(() => {
74190
74230
  // packages/workit-core/src/checks.ts
74191
74231
  import { spawn, spawnSync as spawnSync19 } from "node:child_process";
74192
74232
  import { createHash as createHash16 } from "node:crypto";
74193
- import fs20 from "node:fs";
74233
+ import fs21 from "node:fs";
74194
74234
  import os14 from "node:os";
74195
- import path41 from "node:path";
74235
+ import path42 from "node:path";
74196
74236
  import { StringDecoder } from "node:string_decoder";
74197
74237
  function tailLines(text, lines = TAIL_LINES) {
74198
74238
  const all = text.replace(/\r\n?/gu, `
@@ -74312,10 +74352,10 @@ function planSpawn(argv, options) {
74312
74352
  return { file: argv[0], args: [], verbatim: false, shell: true };
74313
74353
  if (options.platform !== "win32")
74314
74354
  return { file: argv[0], args: argv.slice(1), verbatim: false, shell: false };
74315
- const win = path41.win32;
74355
+ const win = path42.win32;
74316
74356
  const isFile = options.isFile ?? ((file) => {
74317
74357
  try {
74318
- return fs20.statSync(file).isFile();
74358
+ return fs21.statSync(file).isFile();
74319
74359
  } catch {
74320
74360
  return false;
74321
74361
  }
@@ -74474,13 +74514,13 @@ function runCheckCommand(argv, options) {
74474
74514
  function storeLog(storeRoot, log) {
74475
74515
  const digest = logDigest(log);
74476
74516
  const ref = `blobs/logs/${digest.slice("sha256:".length)}.log`;
74477
- const file = path41.join(storeRoot, ref);
74517
+ const file = path42.join(storeRoot, ref);
74478
74518
  try {
74479
- if (!fs20.existsSync(file)) {
74480
- fs20.mkdirSync(path41.dirname(file), { recursive: true });
74519
+ if (!fs21.existsSync(file)) {
74520
+ fs21.mkdirSync(path42.dirname(file), { recursive: true });
74481
74521
  const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
74482
- fs20.writeFileSync(temp, log, { mode: 384 });
74483
- fs20.renameSync(temp, file);
74522
+ fs21.writeFileSync(temp, log, { mode: 384 });
74523
+ fs21.renameSync(temp, file);
74484
74524
  }
74485
74525
  return { digest, ref };
74486
74526
  } catch {
@@ -74490,17 +74530,17 @@ function storeLog(storeRoot, log) {
74490
74530
  function pruneCheckLogs(storeRoot, options = {}) {
74491
74531
  const limits = { ...LOG_RETENTION, ...options.retention };
74492
74532
  const now = options.now ?? Date.now();
74493
- const dir = path41.join(storeRoot, "blobs", "logs");
74533
+ const dir = path42.join(storeRoot, "blobs", "logs");
74494
74534
  const report = { removed: 0, removedBytes: 0, kept: 0 };
74495
74535
  let names;
74496
74536
  try {
74497
- names = fs20.readdirSync(dir);
74537
+ names = fs21.readdirSync(dir);
74498
74538
  } catch {
74499
74539
  return report;
74500
74540
  }
74501
74541
  const files = names.flatMap((name) => {
74502
74542
  try {
74503
- const stat = fs20.statSync(path41.join(dir, name));
74543
+ const stat = fs21.statSync(path42.join(dir, name));
74504
74544
  return stat.isFile() ? [{ name, size: stat.size, mtimeMs: stat.mtimeMs }] : [];
74505
74545
  } catch {
74506
74546
  return [];
@@ -74519,7 +74559,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
74519
74559
  continue;
74520
74560
  if (!options.dryRun)
74521
74561
  try {
74522
- fs20.rmSync(path41.join(dir, file.name), { force: true });
74562
+ fs21.rmSync(path42.join(dir, file.name), { force: true });
74523
74563
  } catch {
74524
74564
  continue;
74525
74565
  }
@@ -74769,13 +74809,13 @@ var init_grant = __esm(() => {
74769
74809
  });
74770
74810
 
74771
74811
  // packages/workit-core/src/core/heavy-rules.ts
74772
- import fs21 from "node:fs";
74773
- import path42 from "node:path";
74812
+ import fs22 from "node:fs";
74813
+ import path43 from "node:path";
74774
74814
  function gitTop(cwd) {
74775
- for (let dir = path42.resolve(cwd);; dir = path42.dirname(dir)) {
74776
- if (fs21.existsSync(path42.join(dir, ".git")))
74815
+ for (let dir = path43.resolve(cwd);; dir = path43.dirname(dir)) {
74816
+ if (fs22.existsSync(path43.join(dir, ".git")))
74777
74817
  return dir;
74778
- if (path42.dirname(dir) === dir)
74818
+ if (path43.dirname(dir) === dir)
74779
74819
  return null;
74780
74820
  }
74781
74821
  }
@@ -74815,20 +74855,20 @@ var baseName = (word) => (word.split(/[\\/]/u).at(-1) ?? "").toLowerCase().repla
74815
74855
  var init_heavy_rules = () => {};
74816
74856
 
74817
74857
  // packages/workit-core/src/core/heavy.ts
74818
- import fs22 from "node:fs";
74858
+ import fs23 from "node:fs";
74819
74859
  import os15 from "node:os";
74820
- import path43 from "node:path";
74860
+ import path44 from "node:path";
74821
74861
  function stateDir(env, platform = process.platform) {
74822
74862
  if (env.WORKFLOW_TOOLKIT_STATE)
74823
74863
  return env.WORKFLOW_TOOLKIT_STATE;
74824
74864
  if (env.XDG_STATE_HOME)
74825
- return path43.join(env.XDG_STATE_HOME, "workit");
74865
+ return path44.join(env.XDG_STATE_HOME, "workit");
74826
74866
  const home = env.HOME || os15.homedir();
74827
74867
  if (platform === "darwin")
74828
- return path43.join(home, "Library", "Application Support", "workit");
74868
+ return path44.join(home, "Library", "Application Support", "workit");
74829
74869
  if (platform === "win32")
74830
- return path43.join(env.LOCALAPPDATA ?? path43.join(home, "AppData", "Local"), "workit");
74831
- return path43.join(home, ".local", "state", "workit");
74870
+ return path44.join(env.LOCALAPPDATA ?? path44.join(home, "AppData", "Local"), "workit");
74871
+ return path44.join(home, ".local", "state", "workit");
74832
74872
  }
74833
74873
  function positional(words, from, values = PM_VALUES) {
74834
74874
  let index = from;
@@ -74968,7 +75008,7 @@ function machinePatterns(env) {
74968
75008
  return isRecord7(value) ? stringList(value.patterns) : [];
74969
75009
  }
74970
75010
  function repoPatterns(cwd) {
74971
- return repoHeavyCommands(gitTop(cwd) ?? path43.resolve(cwd));
75011
+ return repoHeavyCommands(gitTop(cwd) ?? path44.resolve(cwd));
74972
75012
  }
74973
75013
  function heavyLines(lines, options) {
74974
75014
  const found = [];
@@ -75047,9 +75087,9 @@ function leaseRewrite(command) {
75047
75087
  return null;
75048
75088
  return `${prefix}workit check --heavy -- ${rest}`;
75049
75089
  }
75050
- var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path43.join(stateDir(env), HEAVY_COMMANDS_FILE), HEAVY_SCRIPT, INFO_FLAGS, WATCH_FLAG, WATCH_SCRIPT, sub = (...names) => new Set(names), TOOLS, PM_VALUES, baseName2 = (word) => (word?.split(/[\\/]/u).at(-1) ?? "").toLowerCase().replace(/\.(?:exe|cmd|bat|ps1)$/u, ""), WORKIT, PYTHONS, NPM_INSTALL, NPM_RUN, NPM_TEST, EXEC, globWord = (word) => new RegExp(`^${word.replace(/[.+?^${}()|[\]\\]/gu, "\\$&").replaceAll("*", ".*")}$`, "u"), matches2 = (matchers, words) => matchers.length <= words.length && matchers.every((matcher, index) => index === 0 ? matcher.test(words[0]) || matcher.test(baseName2(words[0])) : matcher.test(words[index])), readJson2 = (file) => {
75090
+ var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path44.join(stateDir(env), HEAVY_COMMANDS_FILE), HEAVY_SCRIPT, INFO_FLAGS, WATCH_FLAG, WATCH_SCRIPT, sub = (...names) => new Set(names), TOOLS, PM_VALUES, baseName2 = (word) => (word?.split(/[\\/]/u).at(-1) ?? "").toLowerCase().replace(/\.(?:exe|cmd|bat|ps1)$/u, ""), WORKIT, PYTHONS, NPM_INSTALL, NPM_RUN, NPM_TEST, EXEC, globWord = (word) => new RegExp(`^${word.replace(/[.+?^${}()|[\]\\]/gu, "\\$&").replaceAll("*", ".*")}$`, "u"), matches2 = (matchers, words) => matchers.length <= words.length && matchers.every((matcher, index) => index === 0 ? matcher.test(words[0]) || matcher.test(baseName2(words[0])) : matcher.test(words[index])), readJson2 = (file) => {
75051
75091
  try {
75052
- return JSON.parse(fs22.readFileSync(file, "utf8"));
75092
+ return JSON.parse(fs23.readFileSync(file, "utf8"));
75053
75093
  } catch {
75054
75094
  return;
75055
75095
  }
@@ -75192,9 +75232,9 @@ var init_heavy = __esm(() => {
75192
75232
 
75193
75233
  // packages/workit-core/src/core/resources.ts
75194
75234
  import { randomUUID as randomUUID5 } from "node:crypto";
75195
- import fs23 from "node:fs";
75235
+ import fs24 from "node:fs";
75196
75236
  import os16 from "node:os";
75197
- import path44 from "node:path";
75237
+ import path45 from "node:path";
75198
75238
  function memoryValue(value, host) {
75199
75239
  const text = typeof value === "number" ? String(value) : typeof value === "string" ? value : "";
75200
75240
  const percent = PERCENT.exec(text.trim());
@@ -75347,27 +75387,27 @@ function staleReason(lease, probe = {}) {
75347
75387
  function reclaim(file, stale) {
75348
75388
  const guard = `${file}.reclaim`;
75349
75389
  try {
75350
- fs23.mkdirSync(guard);
75390
+ fs24.mkdirSync(guard);
75351
75391
  } catch {
75352
75392
  try {
75353
- if (Date.now() - fs23.statSync(guard).mtimeMs > GUARD_TTL_MS)
75354
- fs23.rmSync(guard, { force: true, recursive: true });
75393
+ if (Date.now() - fs24.statSync(guard).mtimeMs > GUARD_TTL_MS)
75394
+ fs24.rmSync(guard, { force: true, recursive: true });
75355
75395
  } catch {}
75356
75396
  return false;
75357
75397
  }
75358
75398
  try {
75359
75399
  let ageMs = 0;
75360
75400
  try {
75361
- ageMs = Date.now() - fs23.statSync(file).mtimeMs;
75401
+ ageMs = Date.now() - fs24.statSync(file).mtimeMs;
75362
75402
  } catch {
75363
75403
  return true;
75364
75404
  }
75365
75405
  if (!stale(parseLease(readText4(file)), ageMs))
75366
75406
  return false;
75367
- fs23.rmSync(file, { force: true });
75407
+ fs24.rmSync(file, { force: true });
75368
75408
  return true;
75369
75409
  } finally {
75370
- fs23.rmSync(guard, { force: true, recursive: true });
75410
+ fs24.rmSync(guard, { force: true, recursive: true });
75371
75411
  }
75372
75412
  }
75373
75413
  function tryOnce(options, record, reclaimed) {
@@ -75375,14 +75415,14 @@ function tryOnce(options, record, reclaimed) {
75375
75415
  const text = `${JSON.stringify(record)}
75376
75416
  `;
75377
75417
  for (let slot = 0;slot < options.slots; slot += 1) {
75378
- const file = path44.join(options.dir, `slot-${slot}.json`);
75418
+ const file = path45.join(options.dir, `slot-${slot}.json`);
75379
75419
  for (let attempt = 0;attempt < 2; attempt += 1) {
75380
75420
  try {
75381
- const fd = fs23.openSync(file, "wx", 384);
75421
+ const fd = fs24.openSync(file, "wx", 384);
75382
75422
  try {
75383
- fs23.writeSync(fd, text);
75423
+ fs24.writeSync(fd, text);
75384
75424
  } finally {
75385
- fs23.closeSync(fd);
75425
+ fs24.closeSync(fd);
75386
75426
  }
75387
75427
  return { slot, file };
75388
75428
  } catch (error) {
@@ -75409,7 +75449,7 @@ function tryOnce(options, record, reclaimed) {
75409
75449
  }
75410
75450
  function removeOwn(file, id) {
75411
75451
  if (parseLease(readText4(file))?.id === id)
75412
- fs23.rmSync(file, { force: true });
75452
+ fs24.rmSync(file, { force: true });
75413
75453
  }
75414
75454
  async function acquireLease(options) {
75415
75455
  const pid = options.pid ?? process.pid;
@@ -75429,7 +75469,7 @@ async function acquireLease(options) {
75429
75469
  scope: null
75430
75470
  };
75431
75471
  try {
75432
- fs23.mkdirSync(options.dir, { recursive: true, mode: 448 });
75472
+ fs24.mkdirSync(options.dir, { recursive: true, mode: 448 });
75433
75473
  } catch (error) {
75434
75474
  return { ok: false, reason: "unavailable", error: error.message };
75435
75475
  }
@@ -75483,9 +75523,9 @@ function updateLease(lease, patch) {
75483
75523
  if (parseLease(readText4(lease.file))?.id !== lease.record.id)
75484
75524
  return;
75485
75525
  const temp = `${lease.file}.${process.pid}.tmp`;
75486
- fs23.writeFileSync(temp, `${JSON.stringify(lease.record)}
75526
+ fs24.writeFileSync(temp, `${JSON.stringify(lease.record)}
75487
75527
  `, { mode: 384 });
75488
- fs23.renameSync(temp, lease.file);
75528
+ fs24.renameSync(temp, lease.file);
75489
75529
  } catch {}
75490
75530
  }
75491
75531
  function heldLease(dir, id, options = {}) {
@@ -75493,14 +75533,14 @@ function heldLease(dir, id, options = {}) {
75493
75533
  return null;
75494
75534
  let names;
75495
75535
  try {
75496
- names = fs23.readdirSync(dir);
75536
+ names = fs24.readdirSync(dir);
75497
75537
  } catch {
75498
75538
  return null;
75499
75539
  }
75500
75540
  for (const name of names) {
75501
75541
  if (!/^slot-\d+\.json$/u.test(name))
75502
75542
  continue;
75503
- const lease = parseLease(readText4(path44.join(dir, name)));
75543
+ const lease = parseLease(readText4(path45.join(dir, name)));
75504
75544
  if (lease?.id === id && !staleReason(lease, options.probe) && (options.ancestor ?? isAncestor)(lease.pid))
75505
75545
  return lease;
75506
75546
  }
@@ -75555,10 +75595,10 @@ async function runScoped(run, wrapper, sinks) {
75555
75595
  }
75556
75596
  function firstNotice(env, session, key, now = Date.now()) {
75557
75597
  const id = (session ?? `ppid-${process.ppid}`).replace(/[^A-Za-z0-9_.-]/gu, "_").slice(0, 120);
75558
- const dir = path44.join(stateDir(env), "notices");
75598
+ const dir = path45.join(stateDir(env), "notices");
75559
75599
  try {
75560
- fs23.mkdirSync(dir, { recursive: true, mode: 448 });
75561
- fs23.writeFileSync(path44.join(dir, `${key}-${id}`), `${new Date(now).toISOString()}
75600
+ fs24.mkdirSync(dir, { recursive: true, mode: 448 });
75601
+ fs24.writeFileSync(path45.join(dir, `${key}-${id}`), `${new Date(now).toISOString()}
75562
75602
  `, {
75563
75603
  flag: "wx",
75564
75604
  mode: 384
@@ -75567,10 +75607,10 @@ function firstNotice(env, session, key, now = Date.now()) {
75567
75607
  return error.code !== "EEXIST";
75568
75608
  }
75569
75609
  try {
75570
- for (const name of fs23.readdirSync(dir)) {
75571
- const file = path44.join(dir, name);
75572
- if (now - fs23.statSync(file).mtimeMs > NOTICE_TTL_MS)
75573
- fs23.rmSync(file, { force: true });
75610
+ for (const name of fs24.readdirSync(dir)) {
75611
+ const file = path45.join(dir, name);
75612
+ if (now - fs24.statSync(file).mtimeMs > NOTICE_TTL_MS)
75613
+ fs24.rmSync(file, { force: true });
75574
75614
  }
75575
75615
  } catch {}
75576
75616
  return true;
@@ -75578,7 +75618,7 @@ function firstNotice(env, session, key, now = Date.now()) {
75578
75618
  function leaseSlots(dir, slots, probe = {}) {
75579
75619
  const states = [];
75580
75620
  for (let slot = 0;slot < slots; slot += 1) {
75581
- const lease = parseLease(readText4(path44.join(dir, `slot-${slot}.json`)));
75621
+ const lease = parseLease(readText4(path45.join(dir, `slot-${slot}.json`)));
75582
75622
  states.push({
75583
75623
  slot,
75584
75624
  holder: lease ? holderOf(lease) : null,
@@ -75590,9 +75630,9 @@ function leaseSlots(dir, slots, probe = {}) {
75590
75630
  var DEFAULT_HEAVY_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_S = 600, DEFAULT_MEMORY_SHARE = 0.4, DEFAULT_CPU_SHARE = 0.7, MAX_SLOTS = 64, UNREADABLE_TTL_MS = 30000, GUARD_TTL_MS = 30000, hostShape = () => ({
75591
75631
  totalMemBytes: os16.totalmem(),
75592
75632
  cpus: Math.max(1, os16.availableParallelism?.() ?? os16.cpus().length)
75593
- }), isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path44.join(stateDir(env), "leases"), readText4 = (file) => {
75633
+ }), isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path45.join(stateDir(env), "leases"), readText4 = (file) => {
75594
75634
  try {
75595
- return fs23.readFileSync(file, "utf8");
75635
+ return fs24.readFileSync(file, "utf8");
75596
75636
  } catch {
75597
75637
  return null;
75598
75638
  }
@@ -75643,7 +75683,7 @@ __export(exports_check, {
75643
75683
  workspaceResources: () => workspaceResources
75644
75684
  });
75645
75685
  import os17 from "node:os";
75646
- import path45 from "node:path";
75686
+ import path46 from "node:path";
75647
75687
  function parse5(argv) {
75648
75688
  const split = argv.indexOf("--");
75649
75689
  const head = split >= 0 ? argv.slice(0, split) : [...argv];
@@ -75822,7 +75862,7 @@ function hostToolWaitCapMs(env) {
75822
75862
  }
75823
75863
  async function workspaceResources(io) {
75824
75864
  const env = io.env;
75825
- const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path45.join(env.XDG_CONFIG_HOME || path45.join(env.HOME || os17.homedir(), ".config"), "workit");
75865
+ const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path46.join(env.XDG_CONFIG_HOME || path46.join(env.HOME || os17.homedir(), ".config"), "workit");
75826
75866
  try {
75827
75867
  await Promise.resolve().then(() => init_workspaces());
75828
75868
  const workspace = resolveWorkspaceFrom(io.cwd, dir, env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
@@ -75941,7 +75981,7 @@ async function run10(argv, io) {
75941
75981
  if (options.shell && command.length !== 1)
75942
75982
  return emit(io, fail2("invalid_input", '--shell takes the command as one string: workit check --shell -- "<cmd>"'));
75943
75983
  }
75944
- const relCwd = posix(path45.relative(top, runCwd));
75984
+ const relCwd = posix(path46.relative(top, runCwd));
75945
75985
  const configured = !options.shell && matchesNamedCheck(config, name, command, relCwd);
75946
75986
  const actor = actorFromEnv(io.env);
75947
75987
  const branchKey = codeKey(io.cwd, { base: options.base });
@@ -76107,7 +76147,7 @@ async function run10(argv, io) {
76107
76147
  return recordError.code === "busy" ? 4 : recordError.code === "invalid_input" ? 2 : 5;
76108
76148
  return 0;
76109
76149
  }
76110
- var USAGE3 = 'workit check <name> [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--wait <s>] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(path45.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, HOST_TOOL_WAIT_CAP_MS = 1e5;
76150
+ var USAGE3 = 'workit check <name> [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--wait <s>] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(path46.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, HOST_TOOL_WAIT_CAP_MS = 1e5;
76111
76151
  var init_check = __esm(() => {
76112
76152
  init_check_config();
76113
76153
  init_checks3();
@@ -76132,8 +76172,8 @@ var exports_lock = {};
76132
76172
  __export(exports_lock, {
76133
76173
  run: () => run11
76134
76174
  });
76135
- import fs24 from "node:fs";
76136
- import path46 from "node:path";
76175
+ import fs25 from "node:fs";
76176
+ import path47 from "node:path";
76137
76177
  async function settingsFor(io) {
76138
76178
  const workspace = await workspaceResources(io);
76139
76179
  const config = loadCheckConfig(io.cwd);
@@ -76205,7 +76245,7 @@ async function runHeavy(args, io) {
76205
76245
  }
76206
76246
  function readPatterns(file) {
76207
76247
  try {
76208
- const value = JSON.parse(fs24.readFileSync(file, "utf8"));
76248
+ const value = JSON.parse(fs25.readFileSync(file, "utf8"));
76209
76249
  if (value && typeof value === "object" && !Array.isArray(value)) {
76210
76250
  const record = value;
76211
76251
  const patterns = Array.isArray(record.patterns) ? record.patterns.filter((item) => typeof item === "string") : [];
@@ -76215,11 +76255,11 @@ function readPatterns(file) {
76215
76255
  return { patterns: [] };
76216
76256
  }
76217
76257
  function writePatterns(file, value) {
76218
- fs24.mkdirSync(path46.dirname(file), { recursive: true, mode: 448 });
76258
+ fs25.mkdirSync(path47.dirname(file), { recursive: true, mode: 448 });
76219
76259
  const temp = `${file}.${process.pid}.tmp`;
76220
- fs24.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
76260
+ fs25.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
76221
76261
  `, { mode: 384 });
76222
- fs24.renameSync(temp, file);
76262
+ fs25.renameSync(temp, file);
76223
76263
  }
76224
76264
  async function heavy(args, io) {
76225
76265
  const [action, ...rest] = args.filter((arg) => arg !== "--json");
@@ -76406,7 +76446,7 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
76406
76446
  // packages/workit-core/src/git/ops.ts
76407
76447
  import { spawnSync as spawnSync20 } from "node:child_process";
76408
76448
  import { existsSync as existsSync19, readFileSync as readFileSync19 } from "node:fs";
76409
- import path47 from "node:path";
76449
+ import path48 from "node:path";
76410
76450
  function operationInProgress(cwd) {
76411
76451
  const markers = [
76412
76452
  ["rebase-merge", "rebase"],
@@ -76419,18 +76459,18 @@ function operationInProgress(cwd) {
76419
76459
  if (!run.ok)
76420
76460
  return null;
76421
76461
  const found = run.stdout.split(`
76422
- `).map((line) => path47.resolve(cwd, line.trim()));
76462
+ `).map((line) => path48.resolve(cwd, line.trim()));
76423
76463
  const conflicted = () => git5(cwd, ["ls-files", "-u"]).stdout.trim() !== "";
76424
76464
  for (const [index, [, operation]] of markers.entries()) {
76425
76465
  const marker = found[index];
76426
76466
  if (!marker || !existsSync19(marker))
76427
76467
  continue;
76428
- if (index === 1 && existsSync19(path47.join(marker, "applying")))
76468
+ if (index === 1 && existsSync19(path48.join(marker, "applying")))
76429
76469
  return { operation: "am", commitAllowed: false, branch: null };
76430
- if (index === 0 && existsSync19(path47.join(marker, "amend")) && !conflicted()) {
76470
+ if (index === 0 && existsSync19(path48.join(marker, "amend")) && !conflicted()) {
76431
76471
  let headName = "";
76432
76472
  try {
76433
- headName = readFileSync19(path47.join(marker, "head-name"), "utf8").trim();
76473
+ headName = readFileSync19(path48.join(marker, "head-name"), "utf8").trim();
76434
76474
  } catch {}
76435
76475
  const branch = headName.startsWith("refs/heads/") ? headName.slice("refs/heads/".length) : null;
76436
76476
  return { operation, commitAllowed: branch !== null, branch };
@@ -76758,7 +76798,7 @@ function gitCommit(cwd, input) {
76758
76798
  if (paths.some((value) => value.startsWith("-") || !value.trim()))
76759
76799
  return failure3("invalid_input", "paths must not be empty or start with -");
76760
76800
  const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
76761
- const addable = paths.filter((value) => existsSync19(path47.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
76801
+ const addable = paths.filter((value) => existsSync19(path48.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
76762
76802
  if (addable.length) {
76763
76803
  const added = git5(cwd, ["add", "-A", "--", ...addable]);
76764
76804
  if (!added.ok)
@@ -77284,11 +77324,11 @@ var init_ops = __esm(() => {
77284
77324
  });
77285
77325
 
77286
77326
  // packages/workit-core/src/forge/reruns.ts
77287
- import fs25 from "node:fs";
77288
- import path48 from "node:path";
77327
+ import fs26 from "node:fs";
77328
+ import path49 from "node:path";
77289
77329
  function rerunLogPath(cwd) {
77290
77330
  const common = gitCommonDir(cwd);
77291
- return common ? path48.join(common, "workit", "ci-reruns.jsonl") : null;
77331
+ return common ? path49.join(common, "workit", "ci-reruns.jsonl") : null;
77292
77332
  }
77293
77333
  function rerunCounts(cwd, key) {
77294
77334
  const counts = new Map;
@@ -77297,7 +77337,7 @@ function rerunCounts(cwd, key) {
77297
77337
  return counts;
77298
77338
  let text;
77299
77339
  try {
77300
- text = fs25.readFileSync(file, "utf8");
77340
+ text = fs26.readFileSync(file, "utf8");
77301
77341
  } catch {
77302
77342
  return counts;
77303
77343
  }
@@ -77323,8 +77363,8 @@ function recordReruns(cwd, rows) {
77323
77363
  if (!file)
77324
77364
  return false;
77325
77365
  try {
77326
- fs25.mkdirSync(path48.dirname(file), { recursive: true });
77327
- fs25.appendFileSync(file, rows.map((row) => `${JSON.stringify(row)}
77366
+ fs26.mkdirSync(path49.dirname(file), { recursive: true });
77367
+ fs26.appendFileSync(file, rows.map((row) => `${JSON.stringify(row)}
77328
77368
  `).join(""));
77329
77369
  return true;
77330
77370
  } catch {
@@ -77336,18 +77376,18 @@ function withRerunLock(cwd, fn) {
77336
77376
  if (!file)
77337
77377
  return fn();
77338
77378
  const lock = `${file.slice(0, -".jsonl".length)}.lock`;
77339
- fs25.mkdirSync(path48.dirname(lock), { recursive: true });
77379
+ fs26.mkdirSync(path49.dirname(lock), { recursive: true });
77340
77380
  const until = Date.now() + LOCK_WAIT_MS2;
77341
77381
  for (;; ) {
77342
77382
  try {
77343
- fs25.closeSync(fs25.openSync(lock, "wx"));
77383
+ fs26.closeSync(fs26.openSync(lock, "wx"));
77344
77384
  break;
77345
77385
  } catch (error) {
77346
77386
  if (error.code !== "EEXIST")
77347
77387
  throw error;
77348
77388
  try {
77349
- if (Date.now() - fs25.statSync(lock).mtimeMs > LOCK_STALE_MS2) {
77350
- fs25.rmSync(lock, { force: true });
77389
+ if (Date.now() - fs26.statSync(lock).mtimeMs > LOCK_STALE_MS2) {
77390
+ fs26.rmSync(lock, { force: true });
77351
77391
  continue;
77352
77392
  }
77353
77393
  } catch {
@@ -77361,7 +77401,7 @@ function withRerunLock(cwd, fn) {
77361
77401
  try {
77362
77402
  return fn();
77363
77403
  } finally {
77364
- fs25.rmSync(lock, { force: true });
77404
+ fs26.rmSync(lock, { force: true });
77365
77405
  }
77366
77406
  }
77367
77407
  var isRow = (value) => {
@@ -78228,8 +78268,8 @@ var init_pr_ops = __esm(() => {
78228
78268
  // packages/workit-core/src/stack.ts
78229
78269
  import { spawnSync as spawnSync22 } from "node:child_process";
78230
78270
  import { createHash as createHash17, randomBytes as randomBytes4 } from "node:crypto";
78231
- import fs26 from "node:fs";
78232
- import path49 from "node:path";
78271
+ import fs27 from "node:fs";
78272
+ import path50 from "node:path";
78233
78273
  function worktreeOf(cwd, branch) {
78234
78274
  const list = gitRun3(cwd, ["worktree", "list", "--porcelain"]);
78235
78275
  if (!list.ok)
@@ -78252,7 +78292,7 @@ function rebasingBranch2(dir) {
78252
78292
  if (!found.ok)
78253
78293
  continue;
78254
78294
  try {
78255
- return fs26.readFileSync(found.stdout.trim(), "utf8").trim();
78295
+ return fs27.readFileSync(found.stdout.trim(), "utf8").trim();
78256
78296
  } catch {}
78257
78297
  }
78258
78298
  return null;
@@ -78260,7 +78300,7 @@ function rebasingBranch2(dir) {
78260
78300
  function rebaseInProgress(dir) {
78261
78301
  for (const name of ["rebase-merge", "rebase-apply"]) {
78262
78302
  const found = gitRun3(dir, ["rev-parse", "--path-format=absolute", "--git-path", name]);
78263
- if (found.ok && fs26.existsSync(found.stdout.trim()))
78303
+ if (found.ok && fs27.existsSync(found.stdout.trim()))
78264
78304
  return true;
78265
78305
  }
78266
78306
  return false;
@@ -78272,8 +78312,8 @@ function gitRestack(cwd, input) {
78272
78312
  const scratch = scratchDir(cwd);
78273
78313
  if (!scratch)
78274
78314
  return { ok: false, conflict: false, worktree: cwd, error: "no store root" };
78275
- fs26.mkdirSync(scratch, { recursive: true });
78276
- dir = path49.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
78315
+ fs27.mkdirSync(scratch, { recursive: true });
78316
+ dir = path50.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
78277
78317
  const added = gitRun3(cwd, ["worktree", "add", "-q", dir, input.branch], GIT_TIMEOUTS.worktree);
78278
78318
  if (!added.ok)
78279
78319
  return { ok: false, conflict: false, worktree: cwd, error: firstLine(added) };
@@ -78311,10 +78351,10 @@ function gitRestack(cwd, input) {
78311
78351
  }
78312
78352
  function pruneScratch(cwd) {
78313
78353
  const scratch = scratchDir(cwd);
78314
- if (!scratch || !fs26.existsSync(scratch))
78354
+ if (!scratch || !fs27.existsSync(scratch))
78315
78355
  return;
78316
- for (const name of fs26.readdirSync(scratch)) {
78317
- const dir = path49.join(scratch, name);
78356
+ for (const name of fs27.readdirSync(scratch)) {
78357
+ const dir = path50.join(scratch, name);
78318
78358
  if (!rebaseInProgress(dir) && !trackedDirt(dir))
78319
78359
  gitRun3(cwd, ["worktree", "remove", "--force", dir]);
78320
78360
  }
@@ -78324,7 +78364,7 @@ function stacksDir(cwd) {
78324
78364
  const root = storeRoot(cwd);
78325
78365
  if (!root.ok)
78326
78366
  return stackFail(root.code, root.error, root.unblock);
78327
- return { ok: true, data: path49.join(root.value.root, "stacks") };
78367
+ return { ok: true, data: path50.join(root.value.root, "stacks") };
78328
78368
  }
78329
78369
  function parseStack(raw) {
78330
78370
  if (!isRecord10(raw) || !Array.isArray(raw.branches))
@@ -78376,10 +78416,10 @@ function readStack(cwd, name) {
78376
78416
  const dir = stacksDir(cwd);
78377
78417
  if (!dir.ok)
78378
78418
  return dir;
78379
- const file = path49.join(dir.data, fileFor(name));
78419
+ const file = path50.join(dir.data, fileFor(name));
78380
78420
  let text;
78381
78421
  try {
78382
- text = fs26.readFileSync(file, "utf8");
78422
+ text = fs27.readFileSync(file, "utf8");
78383
78423
  } catch (error) {
78384
78424
  if (error.code === "ENOENT")
78385
78425
  return { ok: true, data: null };
@@ -78397,17 +78437,17 @@ function writeStack(cwd, stack, now = new Date) {
78397
78437
  const dir = stacksDir(cwd);
78398
78438
  if (!dir.ok)
78399
78439
  return dir;
78400
- const file = path49.join(dir.data, fileFor(stack.name));
78440
+ const file = path50.join(dir.data, fileFor(stack.name));
78401
78441
  const temp = `${file}.${process.pid}.tmp`;
78402
78442
  try {
78403
- fs26.mkdirSync(dir.data, { recursive: true });
78443
+ fs27.mkdirSync(dir.data, { recursive: true });
78404
78444
  stack.updatedAt = now.toISOString();
78405
- fs26.writeFileSync(temp, `${JSON.stringify(stack, null, 2)}
78445
+ fs27.writeFileSync(temp, `${JSON.stringify(stack, null, 2)}
78406
78446
  `);
78407
- fs26.renameSync(temp, file);
78447
+ fs27.renameSync(temp, file);
78408
78448
  return { ok: true, data: undefined };
78409
78449
  } catch (error) {
78410
- fs26.rmSync(temp, { force: true });
78450
+ fs27.rmSync(temp, { force: true });
78411
78451
  return stackFail("unavailable", `cannot write ${file}: ${error.message}`);
78412
78452
  }
78413
78453
  }
@@ -78417,7 +78457,7 @@ function listStacks(cwd) {
78417
78457
  return dir;
78418
78458
  let names = [];
78419
78459
  try {
78420
- names = fs26.readdirSync(dir.data).filter((name) => name.endsWith(".json"));
78460
+ names = fs27.readdirSync(dir.data).filter((name) => name.endsWith(".json"));
78421
78461
  } catch {
78422
78462
  return { ok: true, data: [] };
78423
78463
  }
@@ -78425,7 +78465,7 @@ function listStacks(cwd) {
78425
78465
  for (const name of names) {
78426
78466
  let parsed = null;
78427
78467
  try {
78428
- parsed = parseStack(JSON.parse(fs26.readFileSync(path49.join(dir.data, name), "utf8")));
78468
+ parsed = parseStack(JSON.parse(fs27.readFileSync(path50.join(dir.data, name), "utf8")));
78429
78469
  } catch {
78430
78470
  parsed = null;
78431
78471
  }
@@ -78472,7 +78512,7 @@ function stackLockStale(raw, age) {
78472
78512
  }
78473
78513
  function takeLock(lock) {
78474
78514
  try {
78475
- fs26.mkdirSync(lock);
78515
+ fs27.mkdirSync(lock);
78476
78516
  } catch (error) {
78477
78517
  if (error.code === "EEXIST")
78478
78518
  return null;
@@ -78484,24 +78524,24 @@ function takeLock(lock) {
78484
78524
  host: localLockHost(),
78485
78525
  nonce: randomBytes4(8).toString("hex")
78486
78526
  };
78487
- fs26.writeFileSync(path49.join(lock, OWNER), JSON.stringify(owner));
78527
+ fs27.writeFileSync(path50.join(lock, OWNER), JSON.stringify(owner));
78488
78528
  return owner;
78489
78529
  }
78490
78530
  function reapLock(lock, observed) {
78491
78531
  const tomb = `${lock}.reap-${randomBytes4(6).toString("hex")}`;
78492
78532
  try {
78493
- fs26.renameSync(lock, tomb);
78533
+ fs27.renameSync(lock, tomb);
78494
78534
  } catch {
78495
78535
  return false;
78496
78536
  }
78497
78537
  if (readOwner(tomb).raw === observed) {
78498
- fs26.rmSync(tomb, { recursive: true, force: true });
78538
+ fs27.rmSync(tomb, { recursive: true, force: true });
78499
78539
  return true;
78500
78540
  }
78501
78541
  try {
78502
- fs26.renameSync(tomb, lock);
78542
+ fs27.renameSync(tomb, lock);
78503
78543
  } catch {
78504
- fs26.rmSync(tomb, { recursive: true, force: true });
78544
+ fs27.rmSync(tomb, { recursive: true, force: true });
78505
78545
  }
78506
78546
  return false;
78507
78547
  }
@@ -78511,8 +78551,8 @@ function releaseLock(lock, owner) {
78511
78551
  return;
78512
78552
  const tomb = `${lock}.release-${randomBytes4(6).toString("hex")}`;
78513
78553
  try {
78514
- fs26.renameSync(lock, tomb);
78515
- fs26.rmSync(tomb, { recursive: true, force: true });
78554
+ fs27.renameSync(lock, tomb);
78555
+ fs27.rmSync(tomb, { recursive: true, force: true });
78516
78556
  } catch {}
78517
78557
  }
78518
78558
  async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
@@ -78521,9 +78561,9 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
78521
78561
  return dir;
78522
78562
  if (!validName(name))
78523
78563
  return stackFail("invalid_input", "a stack name must be 1-200 printable characters");
78524
- const lock = path49.join(dir.data, `${fileFor(name)}.lock`);
78564
+ const lock = path50.join(dir.data, `${fileFor(name)}.lock`);
78525
78565
  try {
78526
- fs26.mkdirSync(dir.data, { recursive: true });
78566
+ fs27.mkdirSync(dir.data, { recursive: true });
78527
78567
  } catch (error) {
78528
78568
  return stackFail("unavailable", `cannot create ${dir.data}: ${error.message}`);
78529
78569
  }
@@ -78551,7 +78591,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
78551
78591
  const touch = () => {
78552
78592
  try {
78553
78593
  const now = new Date;
78554
- fs26.utimesSync(path49.join(lock, OWNER), now, now);
78594
+ fs27.utimesSync(path50.join(lock, OWNER), now, now);
78555
78595
  } catch {}
78556
78596
  };
78557
78597
  const beat = setInterval(touch, HEARTBEAT_MS);
@@ -79391,7 +79431,7 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
79391
79431
  return !status.ok || status.stdout.trim() !== "";
79392
79432
  }, scratchDir = (cwd) => {
79393
79433
  const dir = stacksDir(cwd);
79394
- return dir.ok ? path49.join(dir.data, "worktrees") : null;
79434
+ return dir.ok ? path50.join(dir.data, "worktrees") : null;
79395
79435
  }, firstLine = (run) => (`${run.stderr}
79396
79436
  ${run.stdout}`.split(`
79397
79437
  `).find((line) => line.trim()) ?? "git failed").trim().slice(0, 300), stackFileName = (name) => `${name.replace(/[^A-Za-z0-9._-]+/gu, "_").replace(/^[._]+/u, "").slice(0, 48).toLowerCase()}-${createHash17("sha256").update(name).digest("hex").slice(0, 12)}.json`, fileFor, validName = (name) => {
@@ -79406,14 +79446,14 @@ ${run.stdout}`.split(`
79406
79446
  }, isRecord10 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), str3 = (value) => typeof value === "string" && value ? value : null, LOCK_WAIT_MS3 = 2000, HEARTBEAT_MS = 20000, HEARTBEAT_STALE_MS, OWNERLESS_STALE_MS = 30000, OWNER = "owner", readOwner = (lock) => {
79407
79447
  let raw = null;
79408
79448
  try {
79409
- raw = fs26.readFileSync(path49.join(lock, OWNER), "utf8");
79449
+ raw = fs27.readFileSync(path50.join(lock, OWNER), "utf8");
79410
79450
  } catch {
79411
79451
  raw = null;
79412
79452
  }
79413
79453
  let age = null;
79414
- for (const target of [path49.join(lock, OWNER), lock])
79454
+ for (const target of [path50.join(lock, OWNER), lock])
79415
79455
  try {
79416
- age = Date.now() - fs26.statSync(target).mtimeMs;
79456
+ age = Date.now() - fs27.statSync(target).mtimeMs;
79417
79457
  break;
79418
79458
  } catch {}
79419
79459
  return { raw, age };
@@ -79446,8 +79486,8 @@ var init_stack = __esm(() => {
79446
79486
  // packages/workit-core/src/fanout.ts
79447
79487
  import { spawnSync as spawnSync23 } from "node:child_process";
79448
79488
  import { createHash as createHash18 } from "node:crypto";
79449
- import fs27 from "node:fs";
79450
- import path50 from "node:path";
79489
+ import fs28 from "node:fs";
79490
+ import path51 from "node:path";
79451
79491
  function expandBraces2(pattern, limit = 64) {
79452
79492
  for (let index = 0;index < pattern.length; index += 1) {
79453
79493
  if (pattern[index] === "\\") {
@@ -79693,7 +79733,7 @@ function parsePlan(raw, defaults, name) {
79693
79733
  id,
79694
79734
  branch,
79695
79735
  base: optional("base") ?? "",
79696
- worktree: path50.resolve(defaults.root, optional("worktree") ?? path50.join(defaults.worktreeRoot, id)),
79736
+ worktree: path51.resolve(defaults.root, optional("worktree") ?? path51.join(defaults.worktreeRoot, id)),
79697
79737
  tier,
79698
79738
  reason,
79699
79739
  dependsOn: [...new Set(dependsOn ?? [])],
@@ -79924,11 +79964,11 @@ function defaultTrunk(cwd) {
79924
79964
  }
79925
79965
  function mainCheckout(cwd) {
79926
79966
  const common = gitCommonDir(cwd);
79927
- return common && path50.basename(common) === ".git" ? path50.dirname(common) : path50.resolve(cwd);
79967
+ return common && path51.basename(common) === ".git" ? path51.dirname(common) : path51.resolve(cwd);
79928
79968
  }
79929
79969
  function worktreeRoot(cwd) {
79930
79970
  const main = mainCheckout(cwd);
79931
- return path50.join(path50.dirname(main), `${path50.basename(main)}-wt`);
79971
+ return path51.join(path51.dirname(main), `${path51.basename(main)}-wt`);
79932
79972
  }
79933
79973
  function sliceHash(slice) {
79934
79974
  const {
@@ -79948,7 +79988,7 @@ function fanoutsDir(cwd) {
79948
79988
  const root = storeRoot(cwd);
79949
79989
  if (!root.ok)
79950
79990
  return fanoutFail(root.code, root.error, root.unblock);
79951
- return { ok: true, data: path50.join(root.value.root, "fanouts") };
79991
+ return { ok: true, data: path51.join(root.value.root, "fanouts") };
79952
79992
  }
79953
79993
  function parseStored(raw) {
79954
79994
  if (!isRecord11(raw) || typeof raw.name !== "string" || typeof raw.trunk !== "string")
@@ -80016,10 +80056,10 @@ function readFanout(cwd, name) {
80016
80056
  const dir = fanoutsDir(cwd);
80017
80057
  if (!dir.ok)
80018
80058
  return dir;
80019
- const file = path50.join(dir.data, stackFileName(name));
80059
+ const file = path51.join(dir.data, stackFileName(name));
80020
80060
  let parsed = null;
80021
80061
  try {
80022
- parsed = parseStored(JSON.parse(fs27.readFileSync(file, "utf8")));
80062
+ parsed = parseStored(JSON.parse(fs28.readFileSync(file, "utf8")));
80023
80063
  } catch (error) {
80024
80064
  if (error.code === "ENOENT")
80025
80065
  return { ok: true, data: null };
@@ -80033,7 +80073,7 @@ function listFanouts(cwd) {
80033
80073
  return dir;
80034
80074
  let names = [];
80035
80075
  try {
80036
- names = fs27.readdirSync(dir.data).filter((entry) => entry.endsWith(".json"));
80076
+ names = fs28.readdirSync(dir.data).filter((entry) => entry.endsWith(".json"));
80037
80077
  } catch {
80038
80078
  return { ok: true, data: [] };
80039
80079
  }
@@ -80041,7 +80081,7 @@ function listFanouts(cwd) {
80041
80081
  for (const entry of names) {
80042
80082
  let parsed = null;
80043
80083
  try {
80044
- parsed = parseStored(JSON.parse(fs27.readFileSync(path50.join(dir.data, entry), "utf8")));
80084
+ parsed = parseStored(JSON.parse(fs28.readFileSync(path51.join(dir.data, entry), "utf8")));
80045
80085
  } catch {
80046
80086
  parsed = null;
80047
80087
  }
@@ -80080,16 +80120,16 @@ function writeFanout(cwd, plan) {
80080
80120
  const dir = fanoutsDir(cwd);
80081
80121
  if (!dir.ok)
80082
80122
  return dir;
80083
- const file = path50.join(dir.data, stackFileName(plan.name));
80123
+ const file = path51.join(dir.data, stackFileName(plan.name));
80084
80124
  const temp = `${file}.${process.pid}.tmp`;
80085
80125
  try {
80086
- fs27.mkdirSync(dir.data, { recursive: true });
80087
- fs27.writeFileSync(temp, `${JSON.stringify(plan, null, 2)}
80126
+ fs28.mkdirSync(dir.data, { recursive: true });
80127
+ fs28.writeFileSync(temp, `${JSON.stringify(plan, null, 2)}
80088
80128
  `);
80089
- fs27.renameSync(temp, file);
80129
+ fs28.renameSync(temp, file);
80090
80130
  return { ok: true, data: file };
80091
80131
  } catch (error) {
80092
- fs27.rmSync(temp, { force: true });
80132
+ fs28.rmSync(temp, { force: true });
80093
80133
  return fanoutFail("unavailable", `cannot write ${file}: ${error.message}`);
80094
80134
  }
80095
80135
  }
@@ -80286,16 +80326,16 @@ var init_fanout = __esm(() => {
80286
80326
 
80287
80327
  // packages/workit-core/src/forge/exec.ts
80288
80328
  import { spawnSync as spawnSync24 } from "node:child_process";
80289
- import fs28 from "node:fs";
80290
- import path51 from "node:path";
80329
+ import fs29 from "node:fs";
80330
+ import path52 from "node:path";
80291
80331
  function findExecutable(bin, env) {
80292
- const dirs = (env.PATH ?? env.Path ?? "").split(path51.delimiter).filter(Boolean);
80332
+ const dirs = (env.PATH ?? env.Path ?? "").split(path52.delimiter).filter(Boolean);
80293
80333
  const exts = process.platform === "win32" ? [".exe"] : [""];
80294
80334
  for (const dir of dirs)
80295
80335
  for (const ext of exts) {
80296
- const candidate = path51.join(dir, `${bin}${ext}`);
80336
+ const candidate = path52.join(dir, `${bin}${ext}`);
80297
80337
  try {
80298
- const stat = fs28.statSync(candidate);
80338
+ const stat = fs29.statSync(candidate);
80299
80339
  if (stat.isFile())
80300
80340
  return candidate;
80301
80341
  } catch {}
@@ -81767,7 +81807,7 @@ var init_pr_edit = __esm(() => {
81767
81807
  });
81768
81808
 
81769
81809
  // packages/workit-core/src/forge/resolve.ts
81770
- import fs29 from "node:fs";
81810
+ import fs30 from "node:fs";
81771
81811
  function memo4(scope, key, compute, now = Date.now) {
81772
81812
  let entries = memoScopes.get(scope.owner);
81773
81813
  if (!entries)
@@ -81813,14 +81853,14 @@ function resolveCredential(workspace, derived, run, scope) {
81813
81853
  if (process.platform !== "win32") {
81814
81854
  let mode = 0;
81815
81855
  try {
81816
- mode = fs29.statSync(tokenFile.trim()).mode;
81856
+ mode = fs30.statSync(tokenFile.trim()).mode;
81817
81857
  } catch {}
81818
81858
  if ((mode & 63) !== 0)
81819
81859
  return failure3("blocked", `workspace ${workspace?.name ?? "?"} vcs.tokenFile is readable by group or other (mode ${(mode & 511).toString(8).padStart(4, "0")})`, `chmod 600 ${tokenFile.trim()}`);
81820
81860
  }
81821
81861
  let token = "";
81822
81862
  try {
81823
- token = fs29.readFileSync(tokenFile.trim(), "utf8").trim();
81863
+ token = fs30.readFileSync(tokenFile.trim(), "utf8").trim();
81824
81864
  } catch {
81825
81865
  return failure3("blocked", `workspace ${workspace?.name ?? "?"} vcs.tokenFile cannot be read`, "fix vcs.tokenFile in ~/.config/workit/workspaces.json");
81826
81866
  }
@@ -82193,11 +82233,11 @@ __export(exports_pr, {
82193
82233
  run: () => run12
82194
82234
  });
82195
82235
  import { readFileSync as readFileSync21 } from "node:fs";
82196
- import path52 from "node:path";
82236
+ import path53 from "node:path";
82197
82237
  function readBodyFile(io, file) {
82198
82238
  try {
82199
82239
  return {
82200
- body: file === "-" ? forgeDeps.readStdin() : readFileSync21(path52.resolve(io.cwd, file), "utf8")
82240
+ body: file === "-" ? forgeDeps.readStdin() : readFileSync21(path53.resolve(io.cwd, file), "utf8")
82201
82241
  };
82202
82242
  } catch {
82203
82243
  return `cannot read --body-file ${file}`;
@@ -82871,7 +82911,7 @@ __export(exports_git, {
82871
82911
  run: () => run14
82872
82912
  });
82873
82913
  import { readFileSync as readFileSync22 } from "node:fs";
82874
- import path53 from "node:path";
82914
+ import path54 from "node:path";
82875
82915
  function kindHint(cwd, kind) {
82876
82916
  let kinds = [...BRANCH_KINDS];
82877
82917
  try {
@@ -82975,7 +83015,7 @@ function commitMessage(parsed, io) {
82975
83015
 
82976
83016
  `);
82977
83017
  try {
82978
- return file === "-" ? readFileSync22(0, "utf8") : readFileSync22(path53.resolve(io.cwd, file), "utf8");
83018
+ return file === "-" ? readFileSync22(0, "utf8") : readFileSync22(path54.resolve(io.cwd, file), "utf8");
82979
83019
  } catch (error) {
82980
83020
  return {
82981
83021
  error: `cannot read -F ${file}: ${error instanceof Error ? error.message : String(error)}`
@@ -84381,8 +84421,8 @@ var init_stack2 = __esm(() => {
84381
84421
 
84382
84422
  // packages/workit-core/src/fanout-worktree.ts
84383
84423
  import { randomBytes as randomBytes5 } from "node:crypto";
84384
- import fs30 from "node:fs";
84385
- import path54 from "node:path";
84424
+ import fs31 from "node:fs";
84425
+ import path55 from "node:path";
84386
84426
  function rowSample(lines) {
84387
84427
  const out = [];
84388
84428
  let bytes = 0;
@@ -84442,7 +84482,7 @@ function adminDir(worktree) {
84442
84482
  const file = dir.stdout.trim();
84443
84483
  let token = null;
84444
84484
  try {
84445
- token = fs30.readFileSync(path54.join(file, TOKEN_FILE), "utf8").trim() || null;
84485
+ token = fs31.readFileSync(path55.join(file, TOKEN_FILE), "utf8").trim() || null;
84446
84486
  } catch {
84447
84487
  token = null;
84448
84488
  }
@@ -84450,7 +84490,7 @@ function adminDir(worktree) {
84450
84490
  const stat = worktreeDeps.stat(file);
84451
84491
  return {
84452
84492
  path: file,
84453
- id: path54.basename(file),
84493
+ id: path55.basename(file),
84454
84494
  ino: stat.ino.toString(),
84455
84495
  token,
84456
84496
  birthMs: stat.birthtimeNs > 0n ? Number(stat.birthtimeMs) : null,
@@ -84466,7 +84506,7 @@ function markAdminDir(worktree) {
84466
84506
  return null;
84467
84507
  const token = randomBytes5(16).toString("hex");
84468
84508
  try {
84469
- fs30.writeFileSync(path54.join(admin.path, TOKEN_FILE), `${token}
84509
+ fs31.writeFileSync(path55.join(admin.path, TOKEN_FILE), `${token}
84470
84510
  `);
84471
84511
  } catch {
84472
84512
  return null;
@@ -84481,25 +84521,25 @@ function excludeScratch(cwd) {
84481
84521
  const common = gitCommonDir(cwd);
84482
84522
  if (!common)
84483
84523
  return;
84484
- const file = path54.join(common, "info", "exclude");
84524
+ const file = path55.join(common, "info", "exclude");
84485
84525
  let text = "";
84486
84526
  try {
84487
- text = fs30.readFileSync(file, "utf8");
84527
+ text = fs31.readFileSync(file, "utf8");
84488
84528
  } catch {
84489
84529
  text = "";
84490
84530
  }
84491
84531
  if (text.split(/\r?\n/u).includes(EXCLUDE_LINE))
84492
84532
  return;
84493
- fs30.mkdirSync(path54.dirname(file), { recursive: true });
84494
- fs30.appendFileSync(file, `${text && !text.endsWith(`
84533
+ fs31.mkdirSync(path55.dirname(file), { recursive: true });
84534
+ fs31.appendFileSync(file, `${text && !text.endsWith(`
84495
84535
  `) ? `
84496
84536
  ` : ""}# workit fanout: per-worker scratch dirs
84497
84537
  ${EXCLUDE_LINE}
84498
84538
  `);
84499
84539
  }
84500
84540
  function ensureScratch(worktree) {
84501
- const scratch = path54.join(worktree, SCRATCH_DIR);
84502
- fs30.mkdirSync(scratch, { recursive: true });
84541
+ const scratch = path55.join(worktree, SCRATCH_DIR);
84542
+ fs31.mkdirSync(scratch, { recursive: true });
84503
84543
  return scratch;
84504
84544
  }
84505
84545
  function createSliceWorktree(cwd, plan, input) {
@@ -84543,8 +84583,8 @@ function createSliceWorktree(cwd, plan, input) {
84543
84583
  return fanoutFail("blocked", `${slice.branch} is checked out at ${elsewhere.path}: never two live workers on one branch`, `stop that worker, then workit fanout worktree release ${slice.id} (or git worktree remove ${elsewhere.path})`);
84544
84584
  let dirExisted = false;
84545
84585
  try {
84546
- const stat = fs30.statSync(target);
84547
- if (!stat.isDirectory() || fs30.readdirSync(target).length > 0)
84586
+ const stat = fs31.statSync(target);
84587
+ if (!stat.isDirectory() || fs31.readdirSync(target).length > 0)
84548
84588
  return fanoutFail("blocked", `${target} exists and is ${stat.isDirectory() ? "not empty" : "not a directory"} (not a worktree of this repository)`, `move it away, or set slice ${slice.id}'s worktree to another path`);
84549
84589
  dirExisted = true;
84550
84590
  } catch (error) {
@@ -84626,7 +84666,7 @@ function releaseSliceWorktree(cwd, plan, input) {
84626
84666
  notes: []
84627
84667
  };
84628
84668
  if (index < 0) {
84629
- if (fs30.existsSync(target))
84669
+ if (fs31.existsSync(target))
84630
84670
  return fanoutFail("blocked", `${target} is not a worktree of this repository; nothing was removed`, "remove it yourself once you know what it holds");
84631
84671
  out.notes.push(`no worktree at ${target}; nothing to release`);
84632
84672
  return { ok: true, data: out };
@@ -84688,7 +84728,7 @@ function releaseSliceWorktree(cwd, plan, input) {
84688
84728
  `)[0]}`, entry.locked ? `git worktree unlock ${entry.path}, then release again` : undefined, { ...out });
84689
84729
  out.removed = true;
84690
84730
  if (made.dirExisted === true)
84691
- fs30.mkdirSync(entry.path, { recursive: true });
84731
+ fs31.mkdirSync(entry.path, { recursive: true });
84692
84732
  if (out.unpushed)
84693
84733
  out.notes.push(`${slice.branch} is kept with ${out.unpushed} commit(s) not on the remote`);
84694
84734
  return { ok: true, data: out };
@@ -84716,32 +84756,32 @@ function unpushedCount(cwd, branch) {
84716
84756
  return count.ok ? Number(count.stdout.trim()) : null;
84717
84757
  }
84718
84758
  function removeScratch(worktree) {
84719
- const scratch = path54.join(worktree, SCRATCH_DIR);
84759
+ const scratch = path55.join(worktree, SCRATCH_DIR);
84720
84760
  let stat;
84721
84761
  try {
84722
- stat = fs30.lstatSync(scratch);
84762
+ stat = fs31.lstatSync(scratch);
84723
84763
  } catch {
84724
84764
  return;
84725
84765
  }
84726
84766
  if (stat.isSymbolicLink() || !stat.isDirectory())
84727
- fs30.unlinkSync(scratch);
84767
+ fs31.unlinkSync(scratch);
84728
84768
  else
84729
- fs30.rmSync(scratch, { recursive: true, force: true, maxRetries: 2 });
84769
+ fs31.rmSync(scratch, { recursive: true, force: true, maxRetries: 2 });
84730
84770
  }
84731
84771
  var SLOW, SCRATCH_DIR = ".workit-scratch", EXCLUDE_LINE, DIRTY_ROW_BYTES = 2000, canonical2 = (target) => {
84732
84772
  try {
84733
- return fs30.realpathSync.native(target);
84773
+ return fs31.realpathSync.native(target);
84734
84774
  } catch {
84735
- return path54.resolve(target);
84775
+ return path55.resolve(target);
84736
84776
  }
84737
84777
  }, samePath = (a, b) => {
84738
84778
  const left = canonical2(a);
84739
84779
  const right = canonical2(b);
84740
84780
  return process.platform === "win32" || process.platform === "darwin" ? left.toLowerCase() === right.toLowerCase() : left === right;
84741
84781
  }, inside3 = (child, parent) => {
84742
- const relative = path54.relative(canonical2(parent), canonical2(child));
84743
- return relative === "" || !relative.startsWith("..") && !path54.isAbsolute(relative);
84744
- }, slicePath = (cwd, slice) => path54.isAbsolute(slice.worktree) ? slice.worktree : path54.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, TOKEN_FILE = "workit-fanout-token", worktreeDeps, worktreeFailed = (stderr) => fanoutFail("failed", `git worktree add failed: ${stderr.trim().split(`
84782
+ const relative = path55.relative(canonical2(parent), canonical2(child));
84783
+ return relative === "" || !relative.startsWith("..") && !path55.isAbsolute(relative);
84784
+ }, slicePath = (cwd, slice) => path55.isAbsolute(slice.worktree) ? slice.worktree : path55.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, TOKEN_FILE = "workit-fanout-token", worktreeDeps, worktreeFailed = (stderr) => fanoutFail("failed", `git worktree add failed: ${stderr.trim().split(`
84745
84785
  `)[0] || "unknown error"}`);
84746
84786
  var init_fanout_worktree = __esm(() => {
84747
84787
  init_ops();
@@ -84751,7 +84791,7 @@ var init_fanout_worktree = __esm(() => {
84751
84791
  SLOW = GIT_TIMEOUTS.worktree;
84752
84792
  EXCLUDE_LINE = `/${SCRATCH_DIR}/`;
84753
84793
  worktreeDeps = {
84754
- stat: (file) => fs30.statSync(file, { bigint: true })
84794
+ stat: (file) => fs31.statSync(file, { bigint: true })
84755
84795
  };
84756
84796
  });
84757
84797
 
@@ -85565,8 +85605,8 @@ var exports_fanout = {};
85565
85605
  __export(exports_fanout, {
85566
85606
  run: () => run18
85567
85607
  });
85568
- import fs31 from "node:fs";
85569
- import path55 from "node:path";
85608
+ import fs32 from "node:fs";
85609
+ import path56 from "node:path";
85570
85610
  function forgeFor(io, offline) {
85571
85611
  if (offline)
85572
85612
  return { forge: null, error: "--offline" };
@@ -85627,10 +85667,10 @@ function plan2(argv, io) {
85627
85667
  return usage3(io, "pass --trunk or --track, not both (--track picks the trunk)", PLAN_USAGE2);
85628
85668
  if (flags.positionals.length !== 1)
85629
85669
  return usage3(io, flags.positionals.length ? `unexpected argument ${flags.positionals[1]}` : "missing <plan.json>", PLAN_USAGE2);
85630
- const file = path55.resolve(io.cwd, flags.positionals[0]);
85670
+ const file = path56.resolve(io.cwd, flags.positionals[0]);
85631
85671
  let raw;
85632
85672
  try {
85633
- raw = JSON.parse(fs31.readFileSync(file, "utf8"));
85673
+ raw = JSON.parse(fs32.readFileSync(file, "utf8"));
85634
85674
  } catch (error) {
85635
85675
  return usage3(io, `cannot read ${file} as JSON: ${error.message}`, PLAN_USAGE2);
85636
85676
  }
@@ -86046,6 +86086,10 @@ async function standing(io, values, args) {
86046
86086
  const [action, ...rest] = args;
86047
86087
  if (action !== "add" && action !== "list" && action !== "clear")
86048
86088
  return emit(io, fail2("invalid_input", action ? `unknown standing action "${action}"` : "missing add, list or clear", { unblock: STANDING_USAGE }));
86089
+ if ((values.stop || values.clear) && action !== "add")
86090
+ return usage4(io, `--stop and --clear go with standing add, not standing ${action}`);
86091
+ if (values.stop && values.clear)
86092
+ return usage4(io, "pass --stop or --clear, not both");
86049
86093
  const target = standingFanout(io, values);
86050
86094
  if (target instanceof Error)
86051
86095
  return emit(io, fail2("invalid_input", target.message, { unblock: STANDING_USAGE }));
@@ -86080,13 +86124,18 @@ async function standing(io, values, args) {
86080
86124
  return emit(io, fail2("not_found", `no fanout plan named ${fanout}`, {
86081
86125
  unblock: "workit fanout plan <plan.json> first, or name an existing plan with --fanout"
86082
86126
  }));
86127
+ if (action === "add" && values.clear) {
86128
+ if (rest.length)
86129
+ return usage4(io, `unexpected argument: ${rest[0]}`);
86130
+ return fromResult(io, liftStop(context, { fanout, lead, leads }), (rows) => `lifted the stop line for fanout ${fanout} (cleared ${rows.map((row) => row.target).join(", ")}); running workers are told on their next tool call`);
86131
+ }
86083
86132
  if (action === "add")
86084
- return fromResult(io, recordStanding(context, { fanout, lead, what: rest.join(" ") }), (row) => `recorded standing order ${row.id} for fanout ${fanout}`);
86133
+ return fromResult(io, recordStanding(context, { fanout, lead, what: rest.join(" "), stop: values.stop === true }), (row) => row.stop ? `recorded stop line ${row.id} for fanout ${fanout}; running workers stop and report on their next tool call` : `recorded standing order ${row.id} for fanout ${fanout}; running workers get it on their next tool call`);
86085
86134
  if (rest.length > 1)
86086
86135
  return usage4(io, `unexpected argument: ${rest[1]}`);
86087
86136
  return fromResult(io, clearStanding(context, { fanout, lead, leads, target: rest[0] ?? null }), (row) => row.target ? `cleared standing order ${row.target} for fanout ${fanout}` : `cleared every standing order for fanout ${fanout}`);
86088
86137
  }
86089
- var USAGE11 = "workit ledger decision|ruling|verdict|standing|list|check ... (workit help ledger for the grammar)", STANDING_USAGE = 'workit ledger standing add "<order>" | list | clear [<id>] [--fanout <name>] [--json]', OPTIONS, SESSION_SAFE2, ROLE_SAFE, actorFor = (io, values) => {
86138
+ var USAGE11 = "workit ledger decision|ruling|verdict|standing|list|check ... (workit help ledger for the grammar)", STANDING_USAGE = 'workit ledger standing add "<order>" | add --stop ["<note>"] | add --clear | list | clear [<id>] [--fanout <name>] [--json]', OPTIONS, SESSION_SAFE2, ROLE_SAFE, actorFor = (io, values) => {
86090
86139
  const actor = actorFromEnv(io.env);
86091
86140
  if (values.session !== undefined && values.as !== undefined)
86092
86141
  return new Error("pass --session or --as, not both");
@@ -86183,6 +86232,8 @@ var init_ledger2 = __esm(() => {
86183
86232
  token: { type: "string" },
86184
86233
  as: { type: "string" },
86185
86234
  fanout: { type: "string" },
86235
+ stop: { type: "boolean" },
86236
+ clear: { type: "boolean" },
86186
86237
  json: { type: "boolean" }
86187
86238
  };
86188
86239
  SESSION_SAFE2 = /^[A-Za-z0-9_.:@/+-]{1,128}$/;
@@ -101150,7 +101201,7 @@ var init_ast = __esm(() => {
101150
101201
 
101151
101202
  // packages/workit-cli/src/test-audit/rules.ts
101152
101203
  import { builtinModules } from "node:module";
101153
- import path56 from "node:path";
101204
+ import path57 from "node:path";
101154
101205
  function testCallee(call) {
101155
101206
  let callee = call.callee;
101156
101207
  if (callee.type === "CallExpression")
@@ -101643,12 +101694,12 @@ function checkConstantsOnly(ctx, emit) {
101643
101694
  }
101644
101695
  function checkOverMocking(ctx, emit) {
101645
101696
  const { program } = ctx.parsed;
101646
- const unit = path56.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
101697
+ const unit = path57.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
101647
101698
  const mocked = find2(program, (node) => node.type === "CallExpression" && MODULE_MOCK.test(calleeName(node.callee) ?? "") && node.arguments[0]?.type === "StringLiteral");
101648
101699
  const internal = mocked.filter((call) => /^(?:\.|@\/|~\/)/.test(call.arguments[0].value));
101649
101700
  for (const call of mocked) {
101650
101701
  const spec = call.arguments[0].value;
101651
- const base = path56.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
101702
+ const base = path57.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
101652
101703
  if (base === unit)
101653
101704
  emit({
101654
101705
  rule: "over-mocking",
@@ -102038,7 +102089,7 @@ var init_rules = __esm(() => {
102038
102089
  // packages/workit-cli/src/test-audit/audit.ts
102039
102090
  import { spawnSync as spawnSync28 } from "node:child_process";
102040
102091
  import { existsSync as existsSync20, readdirSync as readdirSync10, readFileSync as readFileSync23, statSync as statSync8 } from "node:fs";
102041
- import path57 from "node:path";
102092
+ import path58 from "node:path";
102042
102093
  function git7(cwd, args) {
102043
102094
  const run = spawnSync28("git", ["-c", "core.quotepath=off", ...args], {
102044
102095
  cwd,
@@ -102051,7 +102102,7 @@ function walkTests(dir, out) {
102051
102102
  for (const entry of readdirSync10(dir, { withFileTypes: true })) {
102052
102103
  if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
102053
102104
  continue;
102054
- const full = path57.join(dir, entry.name);
102105
+ const full = path58.join(dir, entry.name);
102055
102106
  if (entry.isDirectory()) {
102056
102107
  if (!SKIP_DIRS.has(entry.name))
102057
102108
  walkTests(full, out);
@@ -102063,7 +102114,7 @@ function expandPaths(cwd, inputs) {
102063
102114
  const files = [];
102064
102115
  const missing = [];
102065
102116
  for (const input of inputs.length > 0 ? inputs : ["."]) {
102066
- const full = path57.resolve(cwd, input);
102117
+ const full = path58.resolve(cwd, input);
102067
102118
  if (!existsSync20(full))
102068
102119
  missing.push(input);
102069
102120
  else if (statSync8(full).isDirectory())
@@ -102100,11 +102151,11 @@ function changedLines(cwd, base) {
102100
102151
  for (let offset = 0;offset < count; offset += 1)
102101
102152
  lines.add(start + offset);
102102
102153
  }
102103
- changed.set(path57.join(root, file), lines);
102154
+ changed.set(path58.join(root, file), lines);
102104
102155
  }
102105
102156
  const untracked = git7(root, ["ls-files", "--others", "--exclude-standard", "-z"]);
102106
102157
  for (const file of untracked.stdout.split("\x00").filter(Boolean))
102107
- changed.set(path57.join(root, file), "all");
102158
+ changed.set(path58.join(root, file), "all");
102108
102159
  return changed;
102109
102160
  }
102110
102161
  function auditFiles(files, display) {
@@ -102166,7 +102217,7 @@ function auditFiles(files, display) {
102166
102217
  durationMs: Math.round(performance.now() - started)
102167
102218
  };
102168
102219
  }
102169
- var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path57.sep).join("/"), SEVERITY_ORDER, ruleIds;
102220
+ var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path58.sep).join("/"), SEVERITY_ORDER, ruleIds;
102170
102221
  var init_audit = __esm(() => {
102171
102222
  init_ast();
102172
102223
  init_rules();
@@ -102196,7 +102247,7 @@ import {
102196
102247
  copyFileSync as copyFileSync6
102197
102248
  } from "node:fs";
102198
102249
  import os18 from "node:os";
102199
- import path58 from "node:path";
102250
+ import path59 from "node:path";
102200
102251
  function mutantsFor(source, file, lines) {
102201
102252
  const parsed = parseSource(source, file);
102202
102253
  const out = [];
@@ -102269,7 +102320,7 @@ function relatedTests(source, testFiles) {
102269
102320
  for (const match of text.matchAll(SPECIFIER)) {
102270
102321
  const spec = match[1];
102271
102322
  if (spec.startsWith(".")) {
102272
- if (stripExt(path58.posix.join(path58.posix.dirname(file), spec)) === target)
102323
+ if (stripExt(path59.posix.join(path59.posix.dirname(file), spec)) === target)
102273
102324
  return true;
102274
102325
  } else if (spec.includes("/") && stripExt(spec).split("/").slice(-2).join("/") === tail)
102275
102326
  return true;
@@ -102289,12 +102340,12 @@ function removeStaleCopies(tmp = os18.tmpdir()) {
102289
102340
  for (const name of names) {
102290
102341
  if (!name.startsWith(TEMP_PREFIX))
102291
102342
  continue;
102292
- const dir = path58.join(tmp, name);
102343
+ const dir = path59.join(tmp, name);
102293
102344
  try {
102294
102345
  const stat = lstatSync8(dir);
102295
102346
  if (!stat.isDirectory() || uid !== undefined && stat.uid !== uid)
102296
102347
  continue;
102297
- const pid = Number(readFileSync24(path58.join(dir, PID_FILE), "utf8"));
102348
+ const pid = Number(readFileSync24(path59.join(dir, PID_FILE), "utf8"));
102298
102349
  if (Number.isInteger(pid) && pid > 0 && alive(pid))
102299
102350
  continue;
102300
102351
  } catch (error) {
@@ -102311,8 +102362,8 @@ function removeStaleCopies(tmp = os18.tmpdir()) {
102311
102362
  function linkNodeModules(origin, target, repo, copy) {
102312
102363
  mkdirSync10(target, { recursive: true });
102313
102364
  for (const entry of readdirSync11(origin, { withFileTypes: true })) {
102314
- const from = path58.join(origin, entry.name);
102315
- const to = path58.join(target, entry.name);
102365
+ const from = path59.join(origin, entry.name);
102366
+ const to = path59.join(target, entry.name);
102316
102367
  if (entry.name.startsWith("@") && entry.isDirectory()) {
102317
102368
  linkNodeModules(from, to, repo, copy);
102318
102369
  continue;
@@ -102328,9 +102379,9 @@ function linkNodeModules(origin, target, repo, copy) {
102328
102379
  } catch {
102329
102380
  continue;
102330
102381
  }
102331
- const relative = path58.relative(repo, real);
102332
- if (!relative.startsWith("..") && !path58.isAbsolute(relative) && !relative.split(path58.sep).includes("node_modules")) {
102333
- symlinkSync(path58.join(copy, relative), to, "junction");
102382
+ const relative = path59.relative(repo, real);
102383
+ if (!relative.startsWith("..") && !path59.isAbsolute(relative) && !relative.split(path59.sep).includes("node_modules")) {
102384
+ symlinkSync(path59.join(copy, relative), to, "junction");
102334
102385
  continue;
102335
102386
  }
102336
102387
  }
@@ -102346,7 +102397,7 @@ function copySymlink(repo, tree, from, to) {
102346
102397
  }
102347
102398
  const realRepo = realpathSync9(repo);
102348
102399
  if (real && inside4(realRepo, real)) {
102349
- symlinkSync(path58.relative(path58.dirname(to), path58.join(tree, path58.relative(realRepo, real))), to);
102400
+ symlinkSync(path59.relative(path59.dirname(to), path59.join(tree, path59.relative(realRepo, real))), to);
102350
102401
  return;
102351
102402
  }
102352
102403
  if (real && statSync9(real).isFile())
@@ -102355,10 +102406,10 @@ function copySymlink(repo, tree, from, to) {
102355
102406
  symlinkSync(readlinkSync3(from), to);
102356
102407
  }
102357
102408
  function writeInside(copy, file, content) {
102358
- const target = path58.join(copy, file);
102409
+ const target = path59.join(copy, file);
102359
102410
  try {
102360
102411
  const stat = lstatSync8(target);
102361
- if (!stat.isFile() || !inside4(realpathSync9(copy), realpathSync9(path58.dirname(target))))
102412
+ if (!stat.isFile() || !inside4(realpathSync9(copy), realpathSync9(path59.dirname(target))))
102362
102413
  return false;
102363
102414
  } catch {
102364
102415
  return false;
@@ -102369,9 +102420,9 @@ function writeInside(copy, file, content) {
102369
102420
  return true;
102370
102421
  }
102371
102422
  function copyWorkingTree(repo) {
102372
- const dir = mkdtempSync4(path58.join(os18.tmpdir(), TEMP_PREFIX));
102373
- writeFileSync11(path58.join(dir, PID_FILE), String(process.pid));
102374
- const tree = path58.join(dir, "tree");
102423
+ const dir = mkdtempSync4(path59.join(os18.tmpdir(), TEMP_PREFIX));
102424
+ writeFileSync11(path59.join(dir, PID_FILE), String(process.pid));
102425
+ const tree = path59.join(dir, "tree");
102375
102426
  const head = git7(repo, ["rev-parse", "--verify", "--quiet", "HEAD"]).stdout.trim();
102376
102427
  if (head && git7(dir, ["clone", "-q", "--shared", "--no-checkout", repo, tree]).ok) {
102377
102428
  const branch = git7(repo, ["symbolic-ref", "--quiet", "--short", "HEAD"]).stdout.trim();
@@ -102388,29 +102439,29 @@ function copyWorkingTree(repo) {
102388
102439
  for (const relative of listed) {
102389
102440
  if (!relative)
102390
102441
  continue;
102391
- const from = path58.join(repo, relative);
102442
+ const from = path59.join(repo, relative);
102392
102443
  let stat;
102393
102444
  try {
102394
102445
  stat = lstatSync8(from);
102395
102446
  } catch {
102396
102447
  continue;
102397
102448
  }
102398
- const to = path58.join(tree, relative);
102399
- mkdirSync10(path58.dirname(to), { recursive: true });
102449
+ const to = path59.join(tree, relative);
102450
+ mkdirSync10(path59.dirname(to), { recursive: true });
102400
102451
  if (stat.isSymbolicLink())
102401
102452
  copySymlink(repo, tree, from, to);
102402
102453
  else if (stat.isFile())
102403
102454
  copyFileSync6(from, to);
102404
- let parent = path58.dirname(relative);
102455
+ let parent = path59.dirname(relative);
102405
102456
  while (parent !== "." && !dirs.has(parent)) {
102406
102457
  dirs.add(parent);
102407
- parent = path58.dirname(parent);
102458
+ parent = path59.dirname(parent);
102408
102459
  }
102409
102460
  }
102410
102461
  for (const parent of dirs) {
102411
- const modules = path58.join(repo, parent, "node_modules");
102412
- if (existsSync21(modules) && !existsSync21(path58.join(tree, parent, "node_modules")))
102413
- linkNodeModules(modules, path58.join(tree, parent, "node_modules"), repo, tree);
102462
+ const modules = path59.join(repo, parent, "node_modules");
102463
+ if (existsSync21(modules) && !existsSync21(path59.join(tree, parent, "node_modules")))
102464
+ linkNodeModules(modules, path59.join(tree, parent, "node_modules"), repo, tree);
102414
102465
  }
102415
102466
  return { dir, tree };
102416
102467
  }
@@ -102449,14 +102500,14 @@ async function runMutation(options) {
102449
102500
  const tracked = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00").filter(Boolean);
102450
102501
  const testFiles = tracked.filter((file) => TEST_FILE.test(file)).map((file) => {
102451
102502
  try {
102452
- return { file, text: readFileSync24(path58.join(repo, file), "utf8") };
102503
+ return { file, text: readFileSync24(path59.join(repo, file), "utf8") };
102453
102504
  } catch {
102454
102505
  return { file, text: "" };
102455
102506
  }
102456
102507
  });
102457
102508
  const candidates = [];
102458
102509
  for (const [absolute, lines] of [...options.changed].toSorted(([a], [b]) => a.localeCompare(b))) {
102459
- const relative = toPosix(path58.relative(repo, absolute));
102510
+ const relative = toPosix(path59.relative(repo, absolute));
102460
102511
  if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
102461
102512
  continue;
102462
102513
  if (NOT_SOURCE.test(relative) || !existsSync21(absolute))
@@ -102470,9 +102521,9 @@ async function runMutation(options) {
102470
102521
  for (const mutant of mutants)
102471
102522
  if (!related.has(mutant.file))
102472
102523
  related.set(mutant.file, relatedTests(mutant.file, testFiles));
102473
- const cwdRelative = path58.relative(repo, options.cwd);
102524
+ const cwdRelative = path59.relative(repo, options.cwd);
102474
102525
  const asArg = (file) => {
102475
- const relative = toPosix(path58.relative(cwdRelative, file));
102526
+ const relative = toPosix(path59.relative(cwdRelative, file));
102476
102527
  return shellQuote(relative.startsWith(".") ? relative : `./${relative}`);
102477
102528
  };
102478
102529
  const commandFor = (tests) => options.command.replaceAll("{files}", () => tests.map(asArg).join(" "));
@@ -102507,7 +102558,7 @@ async function runMutation(options) {
102507
102558
  return finish3(options, 0, results, counts, started);
102508
102559
  removeStaleCopies();
102509
102560
  const { dir: copyDir, tree: copy } = copyWorkingTree(repo);
102510
- const copyCwd = path58.join(copy, cwdRelative);
102561
+ const copyCwd = path59.join(copy, cwdRelative);
102511
102562
  let current = null;
102512
102563
  const restore = () => {
102513
102564
  if (current)
@@ -102542,7 +102593,7 @@ async function runMutation(options) {
102542
102593
  record({ ...mutant, status: "skipped", durationMs: 0, tests, reason: "budget" });
102543
102594
  continue;
102544
102595
  }
102545
- const original = readFileSync24(path58.join(copy, mutant.file), "utf8");
102596
+ const original = readFileSync24(path59.join(copy, mutant.file), "utf8");
102546
102597
  const mutated = original.slice(0, mutant.start) + mutant.replacement + original.slice(mutant.end);
102547
102598
  current = { file: mutant.file, original };
102548
102599
  if (!writeInside(copy, mutant.file, mutated)) {
@@ -102599,8 +102650,8 @@ var NOT_SOURCE, FLIPS, isStringy = (node) => node.type === "StringLiteral" || no
102599
102650
  return error.code === "EPERM";
102600
102651
  }
102601
102652
  }, inside4 = (root, file) => {
102602
- const relative = path58.relative(root, file);
102603
- return relative === "" || !relative.startsWith("..") && !path58.isAbsolute(relative);
102653
+ const relative = path59.relative(root, file);
102654
+ return relative === "" || !relative.startsWith("..") && !path59.isAbsolute(relative);
102604
102655
  }, active, killTree = (child) => {
102605
102656
  try {
102606
102657
  if (child.pid && process.platform !== "win32")
@@ -102649,7 +102700,7 @@ __export(exports_test_audit, {
102649
102700
  run: () => run20
102650
102701
  });
102651
102702
  import { existsSync as existsSync22 } from "node:fs";
102652
- import path59 from "node:path";
102703
+ import path60 from "node:path";
102653
102704
  function parse7(argv) {
102654
102705
  const options = {
102655
102706
  paths: [],
@@ -102753,8 +102804,8 @@ async function run20(argv, io) {
102753
102804
  return emit(io, fail2("invalid_input", `${options}
102754
102805
  usage: ${USAGE12}`));
102755
102806
  const top = git7(io.cwd, ["rev-parse", "--show-toplevel"]);
102756
- const repo = top.ok ? path59.resolve(top.stdout.trim()) : null;
102757
- const display = (file) => toPosix(path59.relative(io.cwd, file) || file);
102807
+ const repo = top.ok ? path60.resolve(top.stdout.trim()) : null;
102808
+ const display = (file) => toPosix(path60.relative(io.cwd, file) || file);
102758
102809
  let base = null;
102759
102810
  let changed = null;
102760
102811
  if (options.diff || options.mutate) {
@@ -102893,7 +102944,7 @@ __export(exports_youtrack, {
102893
102944
  run: () => run22
102894
102945
  });
102895
102946
  import { readFileSync as readFileSync25 } from "node:fs";
102896
- import path60 from "node:path";
102947
+ import path61 from "node:path";
102897
102948
  async function run22(argv, io) {
102898
102949
  const [sub, ...rest] = argv;
102899
102950
  if (sub !== "note" && sub !== "time" && sub !== "meeting")
@@ -102939,7 +102990,7 @@ async function run22(argv, io) {
102939
102990
  let markdown = flags.values.markdown ?? "";
102940
102991
  if (flags.values.file)
102941
102992
  try {
102942
- markdown = readFileSync25(path60.resolve(io.cwd, flags.values.file), "utf8");
102993
+ markdown = readFileSync25(path61.resolve(io.cwd, flags.values.file), "utf8");
102943
102994
  } catch (error) {
102944
102995
  return usage3(io, `cannot read ${flags.values.file}: ${String(error)}`, USAGE14);
102945
102996
  }
@@ -103008,7 +103059,7 @@ __export(exports_changelog, {
103008
103059
  run: () => run23
103009
103060
  });
103010
103061
  import { readFileSync as readFileSync26 } from "node:fs";
103011
- import path61 from "node:path";
103062
+ import path62 from "node:path";
103012
103063
  async function run23(argv, io) {
103013
103064
  const [sub, ...rest] = argv;
103014
103065
  if (sub !== "apply")
@@ -103054,7 +103105,7 @@ async function run23(argv, io) {
103054
103105
  ]);
103055
103106
  }
103056
103107
  var USAGE15 = "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]", readEntries = (raw, cwd) => {
103057
- const text = raw === "-" ? readFileSync26(0, "utf8") : raw.startsWith("@") ? readFileSync26(path61.resolve(cwd, raw.slice(1)), "utf8") : raw;
103108
+ const text = raw === "-" ? readFileSync26(0, "utf8") : raw.startsWith("@") ? readFileSync26(path62.resolve(cwd, raw.slice(1)), "utf8") : raw;
103058
103109
  return JSON.parse(text);
103059
103110
  };
103060
103111
  var init_changelog2 = __esm(() => {
@@ -103150,7 +103201,7 @@ var init_handoff = __esm(() => {
103150
103201
 
103151
103202
  // packages/workit-cli/src/main.ts
103152
103203
  init_package();
103153
- import path62 from "node:path";
103204
+ import path63 from "node:path";
103154
103205
 
103155
103206
  // packages/workit-cli/src/verbs/registry.ts
103156
103207
  var TASK_FAMILY_NAMES = [
@@ -103648,8 +103699,8 @@ var VERBS = [
103648
103699
  {
103649
103700
  name: "standing",
103650
103701
  flagAliases: { name: "fanout" },
103651
- usage: `workit ledger standing add "<order>" | standing list | standing clear [<id>] [--fanout <name>] [--supersedes <id>] [--session <id> [--token <t>] | --as <role>]`,
103652
- summary: "The lead's standing orders for a fanout's workers"
103702
+ usage: `workit ledger standing add "<order>" | standing add --stop ["<note>"] | standing add --clear | standing list | standing clear [<id>] [--fanout <name>] [--supersedes <id>] [--session <id> [--token <t>] | --as <role>]`,
103703
+ summary: "The lead's standing orders for a fanout's workers; running workers get each change on their next tool call, and --stop tells them to stop and report"
103653
103704
  },
103654
103705
  {
103655
103706
  name: "add",
@@ -103979,7 +104030,7 @@ var defaultIo = (json) => ({
103979
104030
  });
103980
104031
  async function main(argv, overrides = {}, options = {}) {
103981
104032
  const parsed = parseGlobals(argv);
103982
- const cwd = path62.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
104033
+ const cwd = path63.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
103983
104034
  const io = { ...defaultIo(parsed.json), ...overrides, json: parsed.json, cwd };
103984
104035
  if (parsed.error)
103985
104036
  return emit(io, fail2("invalid_input", parsed.error));