@brainervirus/workit-claude-code 8.44.0 → 8.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/workit.js CHANGED
@@ -9431,7 +9431,7 @@ var package_default;
9431
9431
  var init_package = __esm(() => {
9432
9432
  package_default = {
9433
9433
  name: "@brainervirus/workit-cli",
9434
- version: "8.44.0",
9434
+ version: "8.44.1",
9435
9435
  private: false,
9436
9436
  description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
9437
9437
  keywords: [
@@ -9469,13 +9469,13 @@ var init_package = __esm(() => {
9469
9469
  },
9470
9470
  dependencies: {
9471
9471
  "@babel/parser": "7.29.9",
9472
- "@brainervirus/workit-cursor": "^8.44.0",
9472
+ "@brainervirus/workit-cursor": "^8.44.1",
9473
9473
  "@inkjs/ui": "2.0.0",
9474
9474
  ink: "7.1.1",
9475
9475
  react: "19.2.8"
9476
9476
  },
9477
9477
  devDependencies: {
9478
- "@brainervirus/workit-core": "^8.44.0"
9478
+ "@brainervirus/workit-core": "^8.44.1"
9479
9479
  },
9480
9480
  engines: {
9481
9481
  node: ">=24"
@@ -68214,7 +68214,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
68214
68214
  found.push({ pid: Number(m[1]), startedMs, args: m[3] });
68215
68215
  }
68216
68216
  return found;
68217
- }, listClaudeProcesses = () => listProcessesMatching((args) => /^(\S*\/)?claude(\s|$)/.test(args)), listCodexProcesses = () => listProcessesMatching((args) => /^(\S*\/)?codex(\.js)?(\s|$)|^(\S*\/)?node(js)?\s+(\S+\s+)*?\S*\/codex(\.js)?(\s|$)/.test(args) && !/\bdaemon\s+pid-update-loop\b/.test(args)), resolve = (options) => {
68217
+ }, PS_START_SLACK_MS = 2000, startedBefore = (proc, installedMs) => proc.startedMs + PS_START_SLACK_MS < installedMs, listClaudeProcesses = () => listProcessesMatching((args) => /^(\S*\/)?claude(\s|$)/.test(args)), listCodexProcesses = () => listProcessesMatching((args) => /^(\S*\/)?codex(\.js)?(\s|$)|^(\S*\/)?node(js)?\s+(\S+\s+)*?\S*\/codex(\.js)?(\s|$)/.test(args) && !/\bdaemon\s+pid-update-loop\b/.test(args)), resolve = (options) => {
68218
68218
  const env = options.env ?? process.env;
68219
68219
  const home = options.home ?? env.HOME ?? os13.homedir();
68220
68220
  const configDir = options.configDir ?? env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path40.join(home, ".config", "workit");
@@ -68230,7 +68230,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
68230
68230
  cwd,
68231
68231
  workspaceRoot: options.workspaceRoot ?? env.WORKFLOW_WORKSPACE_ROOT ?? cwd,
68232
68232
  dev,
68233
- opencodeConfig: options.opencodeConfig ?? path40.join(home, ".config", "opencode", "opencode.json"),
68233
+ opencodeConfig: options.opencodeConfig ?? path40.join(env.XDG_CONFIG_HOME || path40.join(home, ".config"), "opencode", "opencode.json"),
68234
68234
  opencodePackageCacheDir: options.opencodePackageCacheDir ?? null,
68235
68235
  cursorSettings: options.cursorSettings ?? path40.join(home, ".cursor", "settings.json"),
68236
68236
  cursorMcp: options.cursorMcp ?? path40.join(home, ".cursor", "mcp.json"),
@@ -69369,9 +69369,25 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
69369
69369
  detail: `OpenCode @latest cache workit-opencode ${installed} matches published ${expected}`
69370
69370
  };
69371
69371
  }, checkStaleInstall = (res) => {
69372
- if (res.host === "opencode") {
69372
+ if (res.host === "opencode")
69373
69373
  return checkOpenCodePackageCache(res);
69374
- }
69374
+ const cursor = checkCursorStaleInstall(res);
69375
+ if (res.host !== "cli")
69376
+ return cursor;
69377
+ const oc = checkOpenCodePackageCache(res);
69378
+ if (oc.status === "pass")
69379
+ return cursor;
69380
+ if (cursor.status === "pass")
69381
+ return oc;
69382
+ if (oc.id !== "stale_install")
69383
+ return cursor;
69384
+ return {
69385
+ ...cursor,
69386
+ registryProbed: Boolean(cursor.registryProbed || oc.registryProbed),
69387
+ detail: `${cursor.detail}; ${oc.detail}`,
69388
+ fix: [cursor.fix, oc.fix].filter(Boolean).join("; ")
69389
+ };
69390
+ }, checkCursorStaleInstall = (res) => {
69375
69391
  if (res.host !== "cursor" && res.host !== "cli") {
69376
69392
  return {
69377
69393
  id: "stale_install",
@@ -69479,11 +69495,6 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
69479
69495
  registryProbed: true,
69480
69496
  detail: `installed local-dist workit-cursor ${installed} matches the published runtime ${expected}`
69481
69497
  };
69482
- if (res.host === "cli") {
69483
- const oc = checkOpenCodePackageCache(res);
69484
- if (oc.status !== "pass")
69485
- return oc;
69486
- }
69487
69498
  return cursorOk;
69488
69499
  }
69489
69500
  const cursorOk = {
@@ -69491,11 +69502,6 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
69491
69502
  status: "pass",
69492
69503
  detail: installed === null ? "installed workit-cursor selectors are canonical" : `installed workit-cursor ${installed} on canonical selectors (hooks run this version through the pinned launcher; MCP resolves @latest at launch)`
69493
69504
  };
69494
- if (res.host === "cli") {
69495
- const oc = checkOpenCodePackageCache(res);
69496
- if (oc.status !== "pass")
69497
- return oc;
69498
- }
69499
69505
  return cursorOk;
69500
69506
  }, checkDuplicateRegistration = (res) => {
69501
69507
  const problems = [];
@@ -70223,7 +70229,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
70223
70229
  status: "info",
70224
70230
  detail: "could not list running claude processes (ps) — skipping"
70225
70231
  };
70226
- const stale = running.filter((proc) => proc.startedMs < latest.at);
70232
+ const stale = running.filter((proc) => startedBefore(proc, latest.at));
70227
70233
  if (stale.length === 0)
70228
70234
  return {
70229
70235
  id,
@@ -70271,7 +70277,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
70271
70277
  status: "info",
70272
70278
  detail: "could not list running codex processes (ps) — skipping"
70273
70279
  };
70274
- const stale = running.filter((proc) => proc.startedMs < latest.at);
70280
+ const stale = running.filter((proc) => startedBefore(proc, latest.at));
70275
70281
  if (stale.length === 0)
70276
70282
  return {
70277
70283
  id,
@@ -75828,7 +75834,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
75828
75834
  }
75829
75835
  const result = runHostCommand(step, { home, env });
75830
75836
  return { status: result.exitCode, stdout: result.stdout, stderr: result.stderr };
75831
- }), COMMAND_TIMEOUT_MS = 60000, asyncRunner = (deps) => {
75837
+ }), COMMAND_TIMEOUT_MS = 60000, asyncRunner = (deps, timeoutMs = COMMAND_TIMEOUT_MS) => {
75832
75838
  if (deps.runAsync)
75833
75839
  return deps.runAsync;
75834
75840
  const injected = deps.run;
@@ -75880,7 +75886,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
75880
75886
  const timer = setTimeout(() => {
75881
75887
  child.kill("SIGKILL");
75882
75888
  finish(1);
75883
- }, COMMAND_TIMEOUT_MS);
75889
+ }, timeoutMs);
75884
75890
  child.stdout?.setEncoding("utf8");
75885
75891
  child.stdout?.on("data", (chunk) => stdout += chunk);
75886
75892
  child.stderr?.setEncoding("utf8");
@@ -75982,7 +75988,7 @@ var init_processes = __esm(() => {
75982
75988
  import { existsSync as existsSync22, readdirSync as readdirSync12, mkdirSync as mkdirSync12, copyFileSync as copyFileSync6, chmodSync as chmodSync2, cpSync as cpSync5 } from "node:fs";
75983
75989
  import path48 from "node:path";
75984
75990
  import { createHash as createHash16 } from "node:crypto";
75985
- async function applyUpgrade(plan, deps = {}) {
75991
+ async function applyUpgrade(plan, deps = {}, options = {}) {
75986
75992
  const hosts = [...plan.failed];
75987
75993
  const done = (backup) => {
75988
75994
  const failures = hosts.filter((entry) => entry.status === "failed");
@@ -76039,6 +76045,26 @@ async function applyUpgrade(plan, deps = {}) {
76039
76045
  const runAsync = asyncRunner(deps);
76040
76046
  const progress = deps.progress ?? createProgress({ json: true });
76041
76047
  const statusOf = (outcome) => outcome?.status === "failed" ? "failed" : outcome?.status === "updated" ? "done" : "skipped";
76048
+ if (plan.cli) {
76049
+ let cli;
76050
+ try {
76051
+ cli = await progress.run("Updating the CLI", () => applyCli(plan.cli, runAsync, backup), statusOf, { signals: true });
76052
+ } catch (error) {
76053
+ cli = { host: "cli", status: "failed", reason: errorText(error), fix: CLI_FIX };
76054
+ }
76055
+ if (cli.status === "updated" && options.handoff) {
76056
+ const code = await options.handoff(cli);
76057
+ if (code !== undefined)
76058
+ return { ...done(backup), hosts: [...hosts, cli], handedOff: code };
76059
+ if (plan.entries.length)
76060
+ cli = {
76061
+ ...cli,
76062
+ reason: `${cli.reason}; the new CLI could not be started, hosts upgraded with workit ${package_default.version}`
76063
+ };
76064
+ } else if (cli.status === "failed" && plan.entries.length)
76065
+ cli = { ...cli, reason: `${cli.reason}; hosts upgraded with workit ${package_default.version}` };
76066
+ hosts.push(cli);
76067
+ }
76042
76068
  let cursorBackupError = null;
76043
76069
  if (plan.entries.some((entry) => entry.host === "cursor") && existsSync22(paths.cursorRoot))
76044
76070
  try {
@@ -76173,17 +76199,6 @@ async function applyUpgrade(plan, deps = {}) {
76173
76199
  reason: `${hosts[index].reason}; ${agents.note}`
76174
76200
  };
76175
76201
  }
76176
- if (plan.cli)
76177
- try {
76178
- hosts.push(await progress.run("Updating the CLI", () => applyCli(plan.cli, runAsync, backup), statusOf, { signals: true }));
76179
- } catch (error) {
76180
- hosts.push({
76181
- host: "cli",
76182
- status: "failed",
76183
- reason: errorText(error),
76184
- fix: CLI_FIX
76185
- });
76186
- }
76187
76202
  return done(backup);
76188
76203
  }
76189
76204
  var briefDetail = (detail) => {
@@ -76213,6 +76228,31 @@ var briefDetail = (detail) => {
76213
76228
  return version;
76214
76229
  }
76215
76230
  return;
76231
+ }, opencodeOutcome = async (before, target, runAsync) => {
76232
+ const below = (version) => target !== undefined && (version === undefined || !versionAtLeast(version, target));
76233
+ let after = await opencodeVersion(runAsync);
76234
+ if (below(after))
76235
+ after = await opencodeVersion(runAsync) ?? after;
76236
+ const live = "OpenCode V2 loads it live";
76237
+ if (before && target && versionAtLeast(before, target))
76238
+ return { host: "opencode", status: "current", reason: `already current (${before})` };
76239
+ if (after && below(after))
76240
+ return {
76241
+ host: "opencode",
76242
+ status: "updated",
76243
+ reason: `update ran, but OpenCode still lists ${after} (published ${target}); the doctor below checks its package cache`
76244
+ };
76245
+ if (before && after && after !== before)
76246
+ return { host: "opencode", status: "updated", reason: `${before} -> ${after}; ${live}` };
76247
+ if (before && after)
76248
+ return {
76249
+ host: "opencode",
76250
+ status: "current",
76251
+ reason: `unchanged (${after}); the published version could not be read`
76252
+ };
76253
+ if (after)
76254
+ return { host: "opencode", status: "updated", reason: `now ${after}; ${live}` };
76255
+ return { host: "opencode", status: "updated", reason: `scoped update ran; ${live}` };
76216
76256
  }, applyEntry = async (entry, context) => {
76217
76257
  const { runAsync, paths, configDir } = context;
76218
76258
  const { home, env } = paths;
@@ -76297,24 +76337,8 @@ ${result.stderr}`;
76297
76337
  if (result.status !== 0)
76298
76338
  return fail(failureReason(command, result));
76299
76339
  }
76300
- if (entry.host === "opencode") {
76301
- const after = await opencodeVersion(runAsync);
76302
- if (before && after)
76303
- return after === before ? {
76304
- host: "opencode",
76305
- status: "current",
76306
- reason: `already current (${after})`
76307
- } : {
76308
- host: "opencode",
76309
- status: "updated",
76310
- reason: `${before} -> ${after}; OpenCode V2 loads it live`
76311
- };
76312
- return {
76313
- host: "opencode",
76314
- status: "updated",
76315
- reason: "scoped update ran; OpenCode V2 loads it live"
76316
- };
76317
- }
76340
+ if (entry.host === "opencode")
76341
+ return opencodeOutcome(before, entry.published, runAsync);
76318
76342
  if (entry.host === "claude-code") {
76319
76343
  const after = claudeWorkitInstalls(home, env, null).find((install) => install.id === entry.selector)?.version;
76320
76344
  return after && after === entry.installedVersion ? {
@@ -76388,6 +76412,7 @@ ${result.stderr}`;
76388
76412
  };
76389
76413
  };
76390
76414
  var init_apply = __esm(() => {
76415
+ init_package();
76391
76416
  init_host_install();
76392
76417
  init_setup_state();
76393
76418
  init_setup();
@@ -76558,14 +76583,86 @@ var init_update_check = __esm(() => {
76558
76583
  ]);
76559
76584
  });
76560
76585
 
76561
- // packages/workit-cli/src/upgrade/plan.ts
76562
- import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8, lstatSync as lstatSync8, readFileSync as readFileSync25 } from "node:fs";
76563
- import path50 from "node:path";
76586
+ // packages/workit-cli/src/upgrade/probes.ts
76587
+ import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8 } from "node:fs";
76564
76588
  import os18 from "node:os";
76565
- function previewUpgrade(hosts = HOSTS2, deps = {}) {
76589
+ import path50 from "node:path";
76590
+ var PROBE_TIMEOUT_MS = 20000, probeKey = (command, args) => [command, ...args].join(" "), opencodeScratchEnv = (deps, scratch) => ({
76591
+ ...deps.env,
76592
+ XDG_DATA_HOME: path50.join(scratch, "data"),
76593
+ XDG_STATE_HOME: path50.join(scratch, "state"),
76594
+ XDG_CACHE_HOME: path50.join(scratch, "cache")
76595
+ }), registry2 = (name) => ["npm", ["view", name, "version"]], runProbes = async (hosts, cli, deps) => {
76596
+ const paths = upgradePaths(deps);
76597
+ const timeoutMs = deps.probeTimeoutMs ?? PROBE_TIMEOUT_MS;
76598
+ const run = asyncRunner(deps, timeoutMs);
76599
+ const probes = [];
76600
+ const add = (command, args, runner = run) => probes.push([command, args, runner]);
76601
+ const scratch = mkdtempSync3(path50.join(os18.tmpdir(), "workit-upgrade-opencode-"));
76602
+ try {
76603
+ if (hosts.includes("opencode") && existsSync23(paths.opencodeConfig)) {
76604
+ const opencode = asyncRunner({ ...deps, env: opencodeScratchEnv(deps, scratch) }, timeoutMs);
76605
+ add("opencode", ["--version"], opencode);
76606
+ add("opencode", ["plugin", "--help"], opencode);
76607
+ add(...registry2(OPENCODE_PACKAGE));
76608
+ }
76609
+ if (hosts.includes("cursor"))
76610
+ add(...registry2("@brainervirus/workit-cursor"));
76611
+ if (hosts.includes("codex")) {
76612
+ add("codex", ["plugin", "list", "--json"]);
76613
+ add(...registry2("@brainervirus/workit-codex"));
76614
+ }
76615
+ if (hosts.includes("pi")) {
76616
+ if (existsSync23(paths.piSettings))
76617
+ add("pi", ["list"]);
76618
+ add(...registry2("@brainervirus/workit-pi"));
76619
+ }
76620
+ if (cli) {
76621
+ add("npm", ["root", "--global"]);
76622
+ add(...registry2(CLI_PACKAGE2));
76623
+ }
76624
+ const results = await Promise.all(probes.map(async ([command, args, runner]) => {
76625
+ let timer;
76626
+ const timedOut = new Promise((resolve) => {
76627
+ timer = setTimeout(() => resolve({
76628
+ status: null,
76629
+ stdout: "",
76630
+ stderr: `\`${probeKey(command, args)}\` timed out after ${Math.round(timeoutMs / 1000)} s`,
76631
+ timedOut: true
76632
+ }), timeoutMs);
76633
+ });
76634
+ try {
76635
+ const result = await Promise.race([
76636
+ runner(command, args).catch((error) => ({
76637
+ status: 1,
76638
+ stdout: "",
76639
+ stderr: error instanceof Error ? error.message : String(error)
76640
+ })),
76641
+ timedOut
76642
+ ]);
76643
+ return [probeKey(command, args), result];
76644
+ } finally {
76645
+ clearTimeout(timer);
76646
+ }
76647
+ }));
76648
+ return new Map(results);
76649
+ } finally {
76650
+ rmSync8(scratch, { recursive: true, force: true });
76651
+ }
76652
+ };
76653
+ var init_probes = __esm(() => {
76654
+ init_update_check();
76655
+ init_shared();
76656
+ });
76657
+
76658
+ // packages/workit-cli/src/upgrade/plan.ts
76659
+ import { existsSync as existsSync24, mkdtempSync as mkdtempSync4, rmSync as rmSync9, lstatSync as lstatSync8, readFileSync as readFileSync25 } from "node:fs";
76660
+ import path51 from "node:path";
76661
+ import os19 from "node:os";
76662
+ function previewUpgrade(hosts = HOSTS2, deps = {}, probes) {
76566
76663
  const paths = upgradePaths(deps);
76567
76664
  const { home, configDir } = paths;
76568
- const run = runner(deps);
76665
+ const run = probedRunner(deps, probes);
76569
76666
  const state = readSetupState(configDir);
76570
76667
  const plan = {
76571
76668
  ok: true,
@@ -76584,9 +76681,9 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
76584
76681
  for (const file of [
76585
76682
  paths.opencodeConfig,
76586
76683
  paths.opencodeConfig + "c",
76587
- path50.join(home, ".cursor/settings.json"),
76588
- path50.join(home, ".cursor/mcp.json"),
76589
- path50.join(paths.cursorRoot, "package.json"),
76684
+ path51.join(home, ".cursor/settings.json"),
76685
+ path51.join(home, ".cursor/mcp.json"),
76686
+ path51.join(paths.cursorRoot, "package.json"),
76590
76687
  paths.codexConfig,
76591
76688
  paths.piSettings
76592
76689
  ])
@@ -76605,7 +76702,7 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
76605
76702
  const installedSources = sources(paths, run, hosts, plan.failed);
76606
76703
  let opencodeHelp;
76607
76704
  if (installedSources.some((source) => source.host === "opencode")) {
76608
- const probe = opencodeProbe(deps, ["--version"]);
76705
+ const probe = opencodeProbe(deps, ["--version"], probes);
76609
76706
  const installed = probe.status === 0 ? probe.stdout.match(/\d+\.\d+\.\d+/)?.[0] : undefined;
76610
76707
  if (installed && !versionAtLeast(installed, SUPPORT_MATRIX.opencode.minimum))
76611
76708
  (plan.warnings ??= []).push(`opencode ${installed}: ${OPENCODE_V1_FIX}`);
@@ -76646,7 +76743,17 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
76646
76743
  continue;
76647
76744
  }
76648
76745
  if (source.host === "opencode") {
76649
- opencodeHelp ??= opencodeProbe(deps, ["plugin", "--help"]).stdout;
76746
+ const help = opencodeProbe(deps, ["plugin", "--help"], probes);
76747
+ if (help.timedOut) {
76748
+ plan.failed.push({
76749
+ host: "opencode",
76750
+ status: "failed",
76751
+ reason: `could not check: ${help.stderr}`,
76752
+ fix: OPENCODE_UPDATE
76753
+ });
76754
+ continue;
76755
+ }
76756
+ opencodeHelp ??= help.stdout;
76650
76757
  if (!/^\s*(?:opencode\s+plugin\s+)?update\b/m.test(opencodeHelp)) {
76651
76758
  plan.skipped.push({
76652
76759
  host: "opencode",
@@ -76655,10 +76762,12 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
76655
76762
  });
76656
76763
  continue;
76657
76764
  }
76765
+ const published = registryVersion(run, OPENCODE_PACKAGE);
76658
76766
  plan.entries.push({
76659
76767
  host: "opencode",
76660
76768
  selector: source.selector,
76661
76769
  latest: "",
76770
+ ...published ? { published } : {},
76662
76771
  commands: [{ command: "opencode", args: ["plugin", "update", OPENCODE_PACKAGE] }],
76663
76772
  fix: OPENCODE_UPDATE
76664
76773
  });
@@ -76746,7 +76855,7 @@ var codexRegistered = (configFile) => {
76746
76855
  }
76747
76856
  };
76748
76857
  guard("opencode", () => {
76749
- if (existsSync23(paths.opencodeConfig + "c"))
76858
+ if (existsSync24(paths.opencodeConfig + "c"))
76750
76859
  throw new Error("OpenCode JSONC config is present; inspect effective native configuration before updating");
76751
76860
  const oc = object2(paths.opencodeConfig);
76752
76861
  if (oc && [oc.plugins, oc.plugin].some((value) => value !== undefined && !Array.isArray(value)))
@@ -76756,8 +76865,8 @@ var codexRegistered = (configFile) => {
76756
76865
  result.push(classify("opencode", pin));
76757
76866
  });
76758
76867
  guard("cursor", () => {
76759
- const cursor = objectOrNull(path50.join(paths.cursorRoot, "package.json"));
76760
- const mcp = objectOrNull(path50.join(home, ".cursor/mcp.json"));
76868
+ const cursor = objectOrNull(path51.join(paths.cursorRoot, "package.json"));
76869
+ const mcp = objectOrNull(path51.join(home, ".cursor/mcp.json"));
76761
76870
  const args = mcp?.mcpServers?.workit?.args ?? [];
76762
76871
  const arg = args.find((value) => typeof value === "string" && value.startsWith("--package="));
76763
76872
  const selector = typeof arg === "string" ? arg.slice(10) : "local";
@@ -76768,7 +76877,7 @@ var codexRegistered = (configFile) => {
76768
76877
  });
76769
76878
  return;
76770
76879
  }
76771
- const settings = objectOrNull(path50.join(home, ".cursor/settings.json"));
76880
+ const settings = objectOrNull(path51.join(home, ".cursor/settings.json"));
76772
76881
  const dirs = Array.isArray(settings?.plugin_dirs) ? settings.plugin_dirs : [];
76773
76882
  const registered = mcp?.mcpServers?.workit !== undefined || dirs.some((dir) => String(dir).replaceAll("\\", "/").replace(/\/+$/, "").endsWith("local/workit"));
76774
76883
  if (registered)
@@ -76783,12 +76892,14 @@ var codexRegistered = (configFile) => {
76783
76892
  if (typeof source !== "string")
76784
76893
  continue;
76785
76894
  const npm = /^(?:npm:)?@brainervirus\/workit-pi(?:@[^/]+)?$/.test(source);
76786
- const local = path50.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path50.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
76895
+ const local = path51.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path51.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
76787
76896
  if (!npm && !local)
76788
76897
  continue;
76789
76898
  const found = classify("pi", source);
76790
76899
  if (found.kind === "floating") {
76791
76900
  const inventory = run("pi", ["list"]);
76901
+ if (inventory.timedOut)
76902
+ throw new Error(`could not check: ${inventory.stderr}`);
76792
76903
  if (inventory.status === 0)
76793
76904
  found.installedVersion = piInstalledVersion(inventory.stdout, source);
76794
76905
  }
@@ -76797,13 +76908,15 @@ var codexRegistered = (configFile) => {
76797
76908
  });
76798
76909
  guard("codex", () => {
76799
76910
  const listing = run("codex", ["plugin", "list", "--json"]);
76911
+ if (listing.timedOut)
76912
+ throw new Error(`could not check: ${listing.stderr}`);
76800
76913
  if (listing.status !== 0) {
76801
76914
  let available = false;
76802
76915
  try {
76803
76916
  hostCommand("codex", [], { home, env: paths.env });
76804
76917
  available = true;
76805
76918
  } catch {}
76806
- if (available || existsSync23(paths.codexConfig))
76919
+ if (available || existsSync24(paths.codexConfig))
76807
76920
  throw new Error("Codex plugin inventory failed; inspect the native host before upgrading");
76808
76921
  return;
76809
76922
  }
@@ -76842,24 +76955,22 @@ var codexRegistered = (configFile) => {
76842
76955
  });
76843
76956
  });
76844
76957
  return result;
76845
- }, opencodeProbe = (deps, args) => {
76846
- const scratch = mkdtempSync3(path50.join(os18.tmpdir(), "workit-upgrade-opencode-"));
76958
+ }, opencodeProbe = (deps, args, probes) => {
76959
+ const cached = probes?.get(probeKey("opencode", args));
76960
+ if (cached)
76961
+ return cached;
76962
+ const scratch = mkdtempSync4(path51.join(os19.tmpdir(), "workit-upgrade-opencode-"));
76847
76963
  try {
76848
- return runner({
76849
- ...deps,
76850
- env: {
76851
- ...deps.env,
76852
- XDG_DATA_HOME: path50.join(scratch, "data"),
76853
- XDG_STATE_HOME: path50.join(scratch, "state"),
76854
- XDG_CACHE_HOME: path50.join(scratch, "cache")
76855
- }
76856
- })("opencode", args);
76964
+ return runner({ ...deps, env: opencodeScratchEnv(deps, scratch) })("opencode", args);
76857
76965
  } finally {
76858
- rmSync8(scratch, { recursive: true, force: true });
76966
+ rmSync9(scratch, { recursive: true, force: true });
76859
76967
  }
76968
+ }, probedRunner = (deps, probes) => {
76969
+ const run = runner(deps);
76970
+ return probes ? (command, args) => probes.get(probeKey(command, args)) ?? run(command, args) : run;
76860
76971
  }, planCli = (plan, run) => {
76861
76972
  const root = run("npm", ["root", "--global"]);
76862
- if (root.status !== 0 || !path50.isAbsolute(root.stdout.trim())) {
76973
+ if (root.status !== 0 || !path51.isAbsolute(root.stdout.trim())) {
76863
76974
  plan.skipped.push({
76864
76975
  host: "cli",
76865
76976
  reason: "global npm location could not be verified",
@@ -76867,9 +76978,9 @@ var codexRegistered = (configFile) => {
76867
76978
  });
76868
76979
  return;
76869
76980
  }
76870
- const packageFile = path50.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
76981
+ const packageFile = path51.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
76871
76982
  const installed = objectOrNull(packageFile);
76872
- if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(path50.dirname(packageFile)).isSymbolicLink()) {
76983
+ if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(path51.dirname(packageFile)).isSymbolicLink()) {
76873
76984
  plan.skipped.push({
76874
76985
  host: "cli",
76875
76986
  reason: "no managed global CLI install (local links preserved); use npx @brainervirus/workit-cli@latest"
@@ -76898,6 +77009,7 @@ var codexRegistered = (configFile) => {
76898
77009
  });
76899
77010
  };
76900
77011
  var init_plan = __esm(() => {
77012
+ init_probes();
76901
77013
  init_registration();
76902
77014
  init_setup_state();
76903
77015
  init_host_install();
@@ -76907,7 +77019,7 @@ var init_plan = __esm(() => {
76907
77019
  });
76908
77020
 
76909
77021
  // packages/workit-cli/src/upgrade/check.ts
76910
- import path51 from "node:path";
77022
+ import path52 from "node:path";
76911
77023
  function runUpdateCheck(json, deps) {
76912
77024
  const out = deps.out ?? process.stdout;
76913
77025
  const paths = upgradePaths(deps);
@@ -77009,7 +77121,7 @@ function runSetUpdates(value, deps) {
77009
77121
  `);
77010
77122
  return 1;
77011
77123
  }
77012
- out.write(`updates: ${value} (saved in ${path51.join(configDir, "config.json")})
77124
+ out.write(`updates: ${value} (saved in ${path52.join(configDir, "config.json")})
77013
77125
  `);
77014
77126
  return 0;
77015
77127
  }
@@ -77106,7 +77218,24 @@ __export(exports_upgrade, {
77106
77218
  runUpgradeCommand: () => runUpgradeCommand
77107
77219
  });
77108
77220
  import { spawnSync as spawnSync18 } from "node:child_process";
77221
+ import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync26, rmSync as rmSync10, writeFileSync as writeFileSync14 } from "node:fs";
77222
+ import os20 from "node:os";
77223
+ import path53 from "node:path";
77109
77224
  async function runUpgradeCommand(argv, deps = {}) {
77225
+ const { env } = upgradePaths(deps);
77226
+ const handBack = env[CONTINUE_ENV] !== undefined ? env[ROWS_ENV] : undefined;
77227
+ const handed = {};
77228
+ const code = await upgradeOnce(argv, deps, handed);
77229
+ if (!handBack)
77230
+ return code;
77231
+ try {
77232
+ writeFileSync14(handBack, JSON.stringify({ code, rows: handed.rows ?? [] }));
77233
+ return 0;
77234
+ } catch {
77235
+ return code;
77236
+ }
77237
+ }
77238
+ async function upgradeOnce(argv, deps, handed) {
77110
77239
  const out = deps.out ?? process.stdout;
77111
77240
  const setting = argv.find((arg) => arg.startsWith("--set-updates="));
77112
77241
  if (argv.includes("--check") || setting) {
@@ -77132,16 +77261,19 @@ async function runUpgradeCommand(argv, deps = {}) {
77132
77261
  }
77133
77262
  const legacy = flags.has("--apply");
77134
77263
  const json = flags.has("--json") || legacy;
77135
- const run = runner(deps);
77264
+ const { home, env } = upgradePaths(deps);
77265
+ const continued = env[CONTINUE_ENV] !== undefined ? priorRows(env[CONTINUE_ENV]) : undefined;
77136
77266
  const progress = deps.progress ?? createProgress({ stream: process.stderr, json });
77137
- const plan = progress.runSync("Planning the upgrade", () => {
77138
- const planned = previewUpgrade(raw, deps);
77139
- if (hostFlag === undefined || flags.has("--cli"))
77140
- planCli(planned, run);
77267
+ const withCli = !continued && (hostFlag === undefined || flags.has("--cli"));
77268
+ const checking = raw.length + (withCli ? 1 : 0);
77269
+ const plan = await progress.run(`Checking ${checking} ${checking === 1 ? "host" : "hosts"}`, async () => {
77270
+ const probes = await runProbes(raw, withCli, deps);
77271
+ const planned = previewUpgrade(raw, deps, probes);
77272
+ if (withCli)
77273
+ planCli(planned, probedRunner(deps, probes));
77141
77274
  return planned;
77142
77275
  });
77143
77276
  plan.ok = plan.blocked.length === 0 && plan.failed.length === 0;
77144
- const { home, env } = upgradePaths(deps);
77145
77277
  const style = createStyle({
77146
77278
  stream: out === process.stdout ? process.stdout : out === process.stderr ? process.stderr : undefined,
77147
77279
  env,
@@ -77172,7 +77304,8 @@ async function runUpgradeCommand(argv, deps = {}) {
77172
77304
  return plan.blocked.length ? 1 : 0;
77173
77305
  }
77174
77306
  if (!json)
77175
- out.write(summary(plan, permissions.changes, style));
77307
+ out.write(continued ? `Continuing the upgrade with the new CLI (workit ${package_default.version}).
77308
+ ` : summary(plan, permissions.changes, style));
77176
77309
  if (flags.has("--preview")) {
77177
77310
  out.write(nothingChanged);
77178
77311
  return plan.blocked.length ? 1 : 0;
@@ -77195,7 +77328,44 @@ Nothing changed.
77195
77328
  for (const warning of plan.warnings ?? [])
77196
77329
  out.write(`warning: ${warning}
77197
77330
  `);
77198
- const result = await applyUpgrade(plan, { ...deps, progress });
77331
+ const reexec = deps.reexec ?? (deps.run && !deps.cliEntry ? undefined : spawnUpgrade({
77332
+ entry: deps.cliEntry ?? process.argv[1],
77333
+ out,
77334
+ toStderr: out === process.stderr,
77335
+ json
77336
+ }));
77337
+ const handoff = async (cli) => {
77338
+ if (!reexec || (deps.cliOnDisk ?? runningCliVersion)() !== plan.cli?.latest)
77339
+ return;
77340
+ const scratch = mkdtempSync5(path53.join(os20.tmpdir(), "workit-upgrade-"));
77341
+ const rowsFile = path53.join(scratch, "rows.json");
77342
+ try {
77343
+ const code = await reexec([
77344
+ ...legacy ? ["--apply", "--confirm"] : ["--yes"],
77345
+ ...flags.has("--json") ? ["--json"] : [],
77346
+ `--hosts=${raw.length ? raw.join(",") : "none"}`
77347
+ ], {
77348
+ [CONTINUE_ENV]: JSON.stringify([cli]),
77349
+ [ROWS_ENV]: rowsFile,
77350
+ WORKIT_UPDATE_CHECK: "0"
77351
+ });
77352
+ if (code === undefined)
77353
+ return;
77354
+ const back = handedBack(readText5(rowsFile));
77355
+ deps.onResult?.(back?.rows.length ? back.rows : [cli]);
77356
+ return back?.code ?? code;
77357
+ } finally {
77358
+ rmSync10(scratch, { recursive: true, force: true });
77359
+ }
77360
+ };
77361
+ const result = await applyUpgrade(plan, { ...deps, progress }, continued || !reexec ? {} : { handoff });
77362
+ if (result.handedOff !== undefined)
77363
+ return result.handedOff;
77364
+ if (continued?.length) {
77365
+ result.hosts.unshift(...continued);
77366
+ if (continued.some((row) => row.status === "failed"))
77367
+ result.ok = false;
77368
+ }
77199
77369
  let permissionsOk = true;
77200
77370
  let written;
77201
77371
  if (permissions.changes.length && !permissions.refused && !result.error?.startsWith("configuration changed")) {
@@ -77210,8 +77380,9 @@ Nothing changed.
77210
77380
  });
77211
77381
  }
77212
77382
  deps.onResult?.(result.hosts);
77383
+ handed.rows = result.hosts;
77213
77384
  const failed = !result.ok || !permissionsOk;
77214
- const cliVersion = result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
77385
+ const cliVersion = plan.cli && result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
77215
77386
  const report = progress.runSync("Checking the result with workit doctor", () => (deps.doctor ?? ((version) => runDoctor({ home, env, cliVersion: version, only: "upgrade" })))(cliVersion));
77216
77387
  const left = report.checks.filter((check) => check.status === "warn" || check.status === "fail");
77217
77388
  if (json) {
@@ -77234,7 +77405,7 @@ Nothing changed.
77234
77405
  if (result.backup)
77235
77406
  out.write(`Backup: ${style.path(result.backup)}
77236
77407
  `);
77237
- out.write(left.length === 0 ? `${style.ok("Verified:")} workit doctor is clean for versions, assets, agents and permissions.
77408
+ out.write(left.length === 0 ? `${style.ok("Verified:")} workit doctor is clean for versions, assets, agents, stale installs and permissions.
77238
77409
  ` : `${style.warn("Left after upgrade (workit doctor):")}
77239
77410
  ${left.map((check) => ` ${style.bold(check.id)}: ${check.detail}${check.fix ? `
77240
77411
  fix: ${style.command(check.fix)}` : ""}`).join(`
@@ -77295,7 +77466,68 @@ async function runLaunchCommand(argv, deps = {}) {
77295
77466
  var USAGE3 = `Usage: workit upgrade [--hosts=opencode,cursor,codex,pi,claude-code|none] [--cli] [--preview | --yes | --apply --confirm] [--json]
77296
77467
  workit upgrade --check [--json]
77297
77468
  workit upgrade --set-updates=prompt|auto|off
77298
- `;
77469
+ `, CONTINUE_ENV = "WORKIT_UPGRADE_CONTINUE", ROWS_ENV = "WORKIT_UPGRADE_ROWS", readText5 = (file) => {
77470
+ try {
77471
+ return readFileSync26(file, "utf8");
77472
+ } catch {
77473
+ return;
77474
+ }
77475
+ }, priorRows = (text) => {
77476
+ if (text === undefined)
77477
+ return;
77478
+ try {
77479
+ const rows = JSON.parse(text);
77480
+ return Array.isArray(rows) ? rows.filter((row) => typeof row?.host === "string" && typeof row?.status === "string" && typeof row?.reason === "string") : [];
77481
+ } catch {
77482
+ return [];
77483
+ }
77484
+ }, handedBack = (text) => {
77485
+ if (text === undefined)
77486
+ return;
77487
+ try {
77488
+ const value = JSON.parse(text);
77489
+ return {
77490
+ code: typeof value.code === "number" ? value.code : undefined,
77491
+ rows: priorRows(JSON.stringify(value.rows ?? [])) ?? []
77492
+ };
77493
+ } catch {
77494
+ return;
77495
+ }
77496
+ }, runningCliVersion = () => {
77497
+ const script = process.argv[1];
77498
+ if (!script)
77499
+ return;
77500
+ let dir = path53.dirname(script);
77501
+ for (let depth = 0;depth < 4; depth += 1, dir = path53.dirname(dir)) {
77502
+ const found = cliPackageVersion(readText5(path53.join(dir, "package.json")));
77503
+ if (found)
77504
+ return found;
77505
+ }
77506
+ return;
77507
+ }, cliPackageVersion = (text) => {
77508
+ if (text === undefined)
77509
+ return;
77510
+ try {
77511
+ const found = JSON.parse(text);
77512
+ return found.name === package_default.name && typeof found.version === "string" ? found.version : undefined;
77513
+ } catch {
77514
+ return;
77515
+ }
77516
+ }, spawnUpgrade = (options) => (argv, extra) => {
77517
+ if (!options.entry)
77518
+ return;
77519
+ const result = spawnSync18(process.execPath, [options.entry, "upgrade", ...argv], {
77520
+ stdio: ["inherit", options.json ? "pipe" : options.toStderr ? 2 : "inherit", "inherit"],
77521
+ encoding: "utf8",
77522
+ maxBuffer: 64 * 1024 * 1024,
77523
+ env: { ...process.env, ...extra }
77524
+ });
77525
+ if (result.error)
77526
+ return;
77527
+ if (options.json && result.stdout)
77528
+ options.out.write(result.stdout);
77529
+ return result.status ?? 1;
77530
+ };
77299
77531
  var init_upgrade = __esm(() => {
77300
77532
  init_package();
77301
77533
  init_host_install();
@@ -77306,6 +77538,7 @@ var init_upgrade = __esm(() => {
77306
77538
  init_apply();
77307
77539
  init_check();
77308
77540
  init_plan();
77541
+ init_probes();
77309
77542
  init_report();
77310
77543
  init_shared();
77311
77544
  init_apply();
@@ -77336,7 +77569,7 @@ var init_launch = __esm(() => {
77336
77569
  // packages/workit-core/src/knowledge.ts
77337
77570
  import { spawnSync as spawnSync19 } from "node:child_process";
77338
77571
  import fs20 from "node:fs";
77339
- import path52 from "node:path";
77572
+ import path54 from "node:path";
77340
77573
  function lintKnowledge(root) {
77341
77574
  const seen = new Set;
77342
77575
  const unreadable = [];
@@ -77440,7 +77673,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
77440
77673
  const end = lines.indexOf("---", 1);
77441
77674
  return end === -1 ? lines : [...lines.slice(0, end + 1).map(() => ""), ...lines.slice(end + 1)];
77442
77675
  }, read = (root, file) => {
77443
- const full = path52.join(root, file);
77676
+ const full = path54.join(root, file);
77444
77677
  try {
77445
77678
  fs20.lstatSync(full);
77446
77679
  } catch {
@@ -77481,7 +77714,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
77481
77714
  }
77482
77715
  }, brokenLinks = (root, doc, tracked) => {
77483
77716
  const findings = [];
77484
- const base = path52.dirname(path52.join(root, doc.file));
77717
+ const base = path54.dirname(path54.join(root, doc.file));
77485
77718
  const missing = (target, line, how) => findings.push({
77486
77719
  rule: "broken-link",
77487
77720
  file: doc.file,
@@ -77500,7 +77733,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
77500
77733
  const local = localTarget(target);
77501
77734
  if (!local)
77502
77735
  continue;
77503
- const resolved = local.startsWith("/") ? path52.join(root, local) : path52.resolve(base, local);
77736
+ const resolved = local.startsWith("/") ? path54.join(root, local) : path54.resolve(base, local);
77504
77737
  if (!exists2(resolved))
77505
77738
  missing(target, index + 1, "link");
77506
77739
  }
@@ -77510,9 +77743,9 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
77510
77743
  continue;
77511
77744
  const relative = /^\.\.?\//.test(candidate);
77512
77745
  const first = candidate.split("/")[0];
77513
- if (!relative && !(tracked ? tracked.has(first) : exists2(path52.join(root, first))))
77746
+ if (!relative && !(tracked ? tracked.has(first) : exists2(path54.join(root, first))))
77514
77747
  continue;
77515
- const resolved = relative ? path52.resolve(base, candidate) : path52.join(root, candidate);
77748
+ const resolved = relative ? path54.resolve(base, candidate) : path54.join(root, candidate);
77516
77749
  if (!exists2(resolved))
77517
77750
  missing(span, index + 1, "pointer");
77518
77751
  }
@@ -77881,8 +78114,8 @@ var init_redact = __esm(() => {
77881
78114
  import { spawn as spawn4, spawnSync as spawnSync20 } from "node:child_process";
77882
78115
  import { createHash as createHash17 } from "node:crypto";
77883
78116
  import fs21 from "node:fs";
77884
- import os19 from "node:os";
77885
- import path53 from "node:path";
78117
+ import os21 from "node:os";
78118
+ import path55 from "node:path";
77886
78119
  import { StringDecoder } from "node:string_decoder";
77887
78120
  function tailLines(text, lines = TAIL_LINES) {
77888
78121
  const all = text.replace(/\r\n?/gu, `
@@ -78002,7 +78235,7 @@ function planSpawn(argv, options) {
78002
78235
  return { file: argv[0], args: [], verbatim: false, shell: true };
78003
78236
  if (options.platform !== "win32")
78004
78237
  return { file: argv[0], args: argv.slice(1), verbatim: false, shell: false };
78005
- const win = path53.win32;
78238
+ const win = path55.win32;
78006
78239
  const isFile = options.isFile ?? ((file) => {
78007
78240
  try {
78008
78241
  return fs21.statSync(file).isFile();
@@ -78087,7 +78320,7 @@ function runCheckCommand(argv, options) {
78087
78320
  `);
78088
78321
  redactor.end();
78089
78322
  resolve({
78090
- exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ? os19.constants.signals[signal] ?? 1 : 1),
78323
+ exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ? os21.constants.signals[signal] ?? 1 : 1),
78091
78324
  signal: signal ?? null,
78092
78325
  timedOut,
78093
78326
  durationMs: Date.now() - started,
@@ -78164,10 +78397,10 @@ function runCheckCommand(argv, options) {
78164
78397
  function storeLog(storeRoot, log) {
78165
78398
  const digest = logDigest(log);
78166
78399
  const ref = `blobs/logs/${digest.slice("sha256:".length)}.log`;
78167
- const file = path53.join(storeRoot, ref);
78400
+ const file = path55.join(storeRoot, ref);
78168
78401
  try {
78169
78402
  if (!fs21.existsSync(file)) {
78170
- fs21.mkdirSync(path53.dirname(file), { recursive: true });
78403
+ fs21.mkdirSync(path55.dirname(file), { recursive: true });
78171
78404
  const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
78172
78405
  fs21.writeFileSync(temp, log, { mode: 384 });
78173
78406
  fs21.renameSync(temp, file);
@@ -78180,7 +78413,7 @@ function storeLog(storeRoot, log) {
78180
78413
  function pruneCheckLogs(storeRoot, options = {}) {
78181
78414
  const limits = { ...LOG_RETENTION, ...options.retention };
78182
78415
  const now = options.now ?? Date.now();
78183
- const dir = path53.join(storeRoot, "blobs", "logs");
78416
+ const dir = path55.join(storeRoot, "blobs", "logs");
78184
78417
  const report = { removed: 0, removedBytes: 0, kept: 0 };
78185
78418
  let names;
78186
78419
  try {
@@ -78190,7 +78423,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
78190
78423
  }
78191
78424
  const files = names.flatMap((name) => {
78192
78425
  try {
78193
- const stat = fs21.statSync(path53.join(dir, name));
78426
+ const stat = fs21.statSync(path55.join(dir, name));
78194
78427
  return stat.isFile() ? [{ name, size: stat.size, mtimeMs: stat.mtimeMs }] : [];
78195
78428
  } catch {
78196
78429
  return [];
@@ -78209,7 +78442,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
78209
78442
  continue;
78210
78443
  if (!options.dryRun)
78211
78444
  try {
78212
- fs21.rmSync(path53.join(dir, file.name), { force: true });
78445
+ fs21.rmSync(path55.join(dir, file.name), { force: true });
78213
78446
  } catch {
78214
78447
  continue;
78215
78448
  }
@@ -78479,7 +78712,7 @@ __export(exports_workspace, {
78479
78712
  run: () => run11,
78480
78713
  runWorkspace: () => runWorkspace
78481
78714
  });
78482
- import { copyFileSync as copyFileSync7, existsSync as existsSync24 } from "node:fs";
78715
+ import { copyFileSync as copyFileSync7, existsSync as existsSync25 } from "node:fs";
78483
78716
  function list2(argv, io) {
78484
78717
  if (argv.length)
78485
78718
  return usage3(io, `unexpected argument ${argv[0]}`);
@@ -78788,7 +79021,7 @@ usage: ${USAGE5}`)), load = (io) => {
78788
79021
  return { ok: false, error: `${current.path} changed; retry` };
78789
79022
  let backup = null;
78790
79023
  try {
78791
- if (existsSync24(current.path)) {
79024
+ if (existsSync25(current.path)) {
78792
79025
  backup = `${current.path}.bak`;
78793
79026
  copyFileSync7(current.path, backup);
78794
79027
  }
@@ -78862,12 +79095,12 @@ var init_workspace = __esm(() => {
78862
79095
 
78863
79096
  // packages/workit-core/src/core/heavy-rules.ts
78864
79097
  import fs22 from "node:fs";
78865
- import path54 from "node:path";
79098
+ import path56 from "node:path";
78866
79099
  function gitTop(cwd) {
78867
- for (let dir = path54.resolve(cwd);; dir = path54.dirname(dir)) {
78868
- if (fs22.existsSync(path54.join(dir, ".git")))
79100
+ for (let dir = path56.resolve(cwd);; dir = path56.dirname(dir)) {
79101
+ if (fs22.existsSync(path56.join(dir, ".git")))
78869
79102
  return dir;
78870
- if (path54.dirname(dir) === dir)
79103
+ if (path56.dirname(dir) === dir)
78871
79104
  return null;
78872
79105
  }
78873
79106
  }
@@ -78908,19 +79141,19 @@ var init_heavy_rules = () => {};
78908
79141
 
78909
79142
  // packages/workit-core/src/core/heavy.ts
78910
79143
  import fs23 from "node:fs";
78911
- import os20 from "node:os";
78912
- import path55 from "node:path";
79144
+ import os22 from "node:os";
79145
+ import path57 from "node:path";
78913
79146
  function stateDir2(env, platform = process.platform) {
78914
79147
  if (env.WORKFLOW_TOOLKIT_STATE)
78915
79148
  return env.WORKFLOW_TOOLKIT_STATE;
78916
79149
  if (env.XDG_STATE_HOME)
78917
- return path55.join(env.XDG_STATE_HOME, "workit");
78918
- const home = env.HOME || os20.homedir();
79150
+ return path57.join(env.XDG_STATE_HOME, "workit");
79151
+ const home = env.HOME || os22.homedir();
78919
79152
  if (platform === "darwin")
78920
- return path55.join(home, "Library", "Application Support", "workit");
79153
+ return path57.join(home, "Library", "Application Support", "workit");
78921
79154
  if (platform === "win32")
78922
- return path55.join(env.LOCALAPPDATA ?? path55.join(home, "AppData", "Local"), "workit");
78923
- return path55.join(home, ".local", "state", "workit");
79155
+ return path57.join(env.LOCALAPPDATA ?? path57.join(home, "AppData", "Local"), "workit");
79156
+ return path57.join(home, ".local", "state", "workit");
78924
79157
  }
78925
79158
  function positional(words, from, values = PM_VALUES) {
78926
79159
  let index = from;
@@ -79060,7 +79293,7 @@ function machinePatterns(env) {
79060
79293
  return isRecord8(value) ? stringList2(value.patterns) : [];
79061
79294
  }
79062
79295
  function repoPatterns(cwd) {
79063
- return repoHeavyCommands(gitTop(cwd) ?? path55.resolve(cwd));
79296
+ return repoHeavyCommands(gitTop(cwd) ?? path57.resolve(cwd));
79064
79297
  }
79065
79298
  function heavyLines(lines, options) {
79066
79299
  const found = [];
@@ -79139,7 +79372,7 @@ function leaseRewrite(command) {
79139
79372
  return null;
79140
79373
  return `${prefix}workit check --heavy -- ${rest}`;
79141
79374
  }
79142
- var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path55.join(stateDir2(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) => {
79375
+ var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path57.join(stateDir2(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) => {
79143
79376
  try {
79144
79377
  return JSON.parse(fs23.readFileSync(file, "utf8"));
79145
79378
  } catch {
@@ -79285,8 +79518,8 @@ var init_heavy = __esm(() => {
79285
79518
  // packages/workit-core/src/core/resources.ts
79286
79519
  import { randomUUID as randomUUID5 } from "node:crypto";
79287
79520
  import fs24 from "node:fs";
79288
- import os21 from "node:os";
79289
- import path56 from "node:path";
79521
+ import os23 from "node:os";
79522
+ import path58 from "node:path";
79290
79523
  function memoryValue(value, host) {
79291
79524
  const text = typeof value === "number" ? String(value) : typeof value === "string" ? value : "";
79292
79525
  const percent = PERCENT.exec(text.trim());
@@ -79412,7 +79645,7 @@ function scopeBusy(unit) {
79412
79645
  return false;
79413
79646
  const uid = process.getuid?.() ?? 0;
79414
79647
  const manager = `/sys/fs/cgroup/user.slice/user-${uid}.slice/user@${uid}.service`;
79415
- return [`${manager}/app.slice/${unit}`, `${manager}/${unit}`].some((dir) => (readText5(`${dir}/cgroup.procs`) ?? "").trim() !== "");
79648
+ return [`${manager}/app.slice/${unit}`, `${manager}/${unit}`].some((dir) => (readText6(`${dir}/cgroup.procs`) ?? "").trim() !== "");
79416
79649
  }
79417
79650
  function isAncestor(pid) {
79418
79651
  if (process.platform !== "linux")
@@ -79469,7 +79702,7 @@ function reclaim(file, stale) {
79469
79702
  } catch {
79470
79703
  return true;
79471
79704
  }
79472
- if (!stale(parseLease(readText5(file)), ageMs))
79705
+ if (!stale(parseLease(readText6(file)), ageMs))
79473
79706
  return false;
79474
79707
  fs24.rmSync(file, { force: true });
79475
79708
  return true;
@@ -79482,7 +79715,7 @@ function tryOnce(options, record, reclaimed) {
79482
79715
  const text = `${JSON.stringify(record)}
79483
79716
  `;
79484
79717
  for (let slot = 0;slot < options.slots; slot += 1) {
79485
- const file = path56.join(options.dir, `slot-${slot}.json`);
79718
+ const file = path58.join(options.dir, `slot-${slot}.json`);
79486
79719
  for (let attempt = 0;attempt < 2; attempt += 1) {
79487
79720
  try {
79488
79721
  const fd = fs24.openSync(file, "wx", 384);
@@ -79496,7 +79729,7 @@ function tryOnce(options, record, reclaimed) {
79496
79729
  if (error.code !== "EEXIST")
79497
79730
  throw error;
79498
79731
  }
79499
- const lease = parseLease(readText5(file));
79732
+ const lease = parseLease(readText6(file));
79500
79733
  let reason = null;
79501
79734
  const removed = reclaim(file, (current, ageMs) => {
79502
79735
  reason = current ? staleReason(current, options.probe) : ageMs > UNREADABLE_TTL_MS ? "unreadable" : null;
@@ -79515,7 +79748,7 @@ function tryOnce(options, record, reclaimed) {
79515
79748
  return { holders };
79516
79749
  }
79517
79750
  function removeOwn(file, id) {
79518
- if (parseLease(readText5(file))?.id === id)
79751
+ if (parseLease(readText6(file))?.id === id)
79519
79752
  fs24.rmSync(file, { force: true });
79520
79753
  }
79521
79754
  function leaseQueue(dir, probe = {}) {
@@ -79527,8 +79760,8 @@ function leaseQueue(dir, probe = {}) {
79527
79760
  }
79528
79761
  const entries = [];
79529
79762
  for (const name of names.filter((item) => item.endsWith(".json")).toSorted()) {
79530
- const file = path56.join(queueDir(dir), name);
79531
- const record = parseLease(readText5(file));
79763
+ const file = path58.join(queueDir(dir), name);
79764
+ const record = parseLease(readText6(file));
79532
79765
  if (!record)
79533
79766
  continue;
79534
79767
  entries.push({
@@ -79543,9 +79776,9 @@ function leaseQueue(dir, probe = {}) {
79543
79776
  function waitersAhead(options, own) {
79544
79777
  let ahead = 0;
79545
79778
  for (const entry of leaseQueue(options.dir, options.probe)) {
79546
- if (path56.basename(entry.file) >= own)
79779
+ if (path58.basename(entry.file) >= own)
79547
79780
  break;
79548
- if (!TICKET.test(path56.basename(entry.file)))
79781
+ if (!TICKET.test(path58.basename(entry.file)))
79549
79782
  continue;
79550
79783
  if (entry.stale && reclaim(entry.file, (current) => !current || staleReason(current, options.probe) !== null))
79551
79784
  continue;
@@ -79557,7 +79790,7 @@ function liveHolders(options) {
79557
79790
  return leaseSlots(options.dir, options.slots, options.probe).filter((slot) => slot.holder && !slot.stale).map((slot) => slot.holder);
79558
79791
  }
79559
79792
  function writeTicket(file, record) {
79560
- fs24.mkdirSync(path56.dirname(file), { recursive: true, mode: 448 });
79793
+ fs24.mkdirSync(path58.dirname(file), { recursive: true, mode: 448 });
79561
79794
  fs24.writeFileSync(file, `${JSON.stringify(record)}
79562
79795
  `, { mode: 384 });
79563
79796
  }
@@ -79602,7 +79835,7 @@ async function acquireLease(options) {
79602
79835
  const reclaimed = [];
79603
79836
  let waitedOn = [];
79604
79837
  const name = ticketName(started, record.id);
79605
- const ticket = path56.join(queueDir(options.dir), name);
79838
+ const ticket = path58.join(queueDir(options.dir), name);
79606
79839
  const ticketRecord = {
79607
79840
  ...record,
79608
79841
  maxAgeMs: options.waitMs + 60000
@@ -79703,7 +79936,7 @@ async function acquireLease(options) {
79703
79936
  function updateLease(lease, patch) {
79704
79937
  Object.assign(lease.record, patch);
79705
79938
  try {
79706
- if (parseLease(readText5(lease.file))?.id !== lease.record.id)
79939
+ if (parseLease(readText6(lease.file))?.id !== lease.record.id)
79707
79940
  return;
79708
79941
  const temp = `${lease.file}.${process.pid}.tmp`;
79709
79942
  fs24.writeFileSync(temp, `${JSON.stringify(lease.record)}
@@ -79723,7 +79956,7 @@ function heldLease(dir, id, options = {}) {
79723
79956
  for (const name of names) {
79724
79957
  if (!/^slot-\d+\.json$/u.test(name))
79725
79958
  continue;
79726
- const lease = parseLease(readText5(path56.join(dir, name)));
79959
+ const lease = parseLease(readText6(path58.join(dir, name)));
79727
79960
  if (lease?.id === id && !staleReason(lease, options.probe) && (options.ancestor ?? isAncestor)(lease.pid))
79728
79961
  return lease;
79729
79962
  }
@@ -79778,10 +80011,10 @@ async function runScoped(run, wrapper, sinks) {
79778
80011
  }
79779
80012
  function firstNotice(env, session, key, now = Date.now()) {
79780
80013
  const id = (session ?? `ppid-${process.ppid}`).replace(/[^A-Za-z0-9_.-]/gu, "_").slice(0, 120);
79781
- const dir = path56.join(stateDir2(env), "notices");
80014
+ const dir = path58.join(stateDir2(env), "notices");
79782
80015
  try {
79783
80016
  fs24.mkdirSync(dir, { recursive: true, mode: 448 });
79784
- fs24.writeFileSync(path56.join(dir, `${key}-${id}`), `${new Date(now).toISOString()}
80017
+ fs24.writeFileSync(path58.join(dir, `${key}-${id}`), `${new Date(now).toISOString()}
79785
80018
  `, {
79786
80019
  flag: "wx",
79787
80020
  mode: 384
@@ -79791,7 +80024,7 @@ function firstNotice(env, session, key, now = Date.now()) {
79791
80024
  }
79792
80025
  try {
79793
80026
  for (const name of fs24.readdirSync(dir)) {
79794
- const file = path56.join(dir, name);
80027
+ const file = path58.join(dir, name);
79795
80028
  if (now - fs24.statSync(file).mtimeMs > NOTICE_TTL_MS)
79796
80029
  fs24.rmSync(file, { force: true });
79797
80030
  }
@@ -79801,7 +80034,7 @@ function firstNotice(env, session, key, now = Date.now()) {
79801
80034
  function leaseSlots(dir, slots, probe = {}) {
79802
80035
  const states = [];
79803
80036
  for (let slot = 0;slot < slots; slot += 1) {
79804
- const lease = parseLease(readText5(path56.join(dir, `slot-${slot}.json`)));
80037
+ const lease = parseLease(readText6(path58.join(dir, `slot-${slot}.json`)));
79805
80038
  states.push({
79806
80039
  slot,
79807
80040
  holder: lease ? holderOf(lease) : null,
@@ -79811,16 +80044,16 @@ function leaseSlots(dir, slots, probe = {}) {
79811
80044
  return states;
79812
80045
  }
79813
80046
  var DEFAULT_HEAVY_CHECKS, DEFAULT_LIGHT_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_S = 1800, DEFAULT_MEMORY_SHARE = 0.4, DEFAULT_CPU_SHARE = 0.7, MAX_SLOTS = 64, UNREADABLE_TTL_MS = 30000, GUARD_TTL_MS = 30000, hostShape = () => ({
79814
- totalMemBytes: os21.totalmem(),
79815
- cpus: Math.max(1, os21.availableParallelism?.() ?? os21.cpus().length)
79816
- }), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path56.join(stateDir2(env), "leases"), readText5 = (file) => {
80047
+ totalMemBytes: os23.totalmem(),
80048
+ cpus: Math.max(1, os23.availableParallelism?.() ?? os23.cpus().length)
80049
+ }), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path58.join(stateDir2(env), "leases"), readText6 = (file) => {
79817
80050
  try {
79818
80051
  return fs24.readFileSync(file, "utf8");
79819
80052
  } catch {
79820
80053
  return null;
79821
80054
  }
79822
- }, bootId = () => readText5("/proc/sys/kernel/random/boot_id")?.trim() || null, bootTime = () => Math.round((Date.now() - os21.uptime() * 1000) / 1000) * 1000, BOOT_SLACK_MS = 120000, statFields = (pid) => {
79823
- const stat = readText5(`/proc/${pid}/stat`);
80055
+ }, bootId = () => readText6("/proc/sys/kernel/random/boot_id")?.trim() || null, bootTime = () => Math.round((Date.now() - os23.uptime() * 1000) / 1000) * 1000, BOOT_SLACK_MS = 120000, statFields = (pid) => {
80056
+ const stat = readText6(`/proc/${pid}/stat`);
79824
80057
  return stat ? stat.slice(stat.lastIndexOf(")") + 2).split(" ") : null;
79825
80058
  }, processStart = (pid) => statFields(pid)?.[19] ?? null, pidAlive2 = (pid) => {
79826
80059
  try {
@@ -79844,7 +80077,7 @@ var DEFAULT_HEAVY_CHECKS, DEFAULT_LIGHT_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_
79844
80077
  cwd: lease.cwd,
79845
80078
  session: lease.session,
79846
80079
  startedAt: lease.startedAt
79847
- }), realClock, queueDir = (dir) => path56.join(dir, "queue"), TICKET, ticketName = (now, id) => `${String(now).padStart(15, "0")}-${String(process.hrtime.bigint() % 10n ** 16n).padStart(16, "0")}-${id}.json`, SCOPE_START_FAILURE, NOTICE_TTL_MS;
80080
+ }), realClock, queueDir = (dir) => path58.join(dir, "queue"), TICKET, ticketName = (now, id) => `${String(now).padStart(15, "0")}-${String(process.hrtime.bigint() % 10n ** 16n).padStart(16, "0")}-${id}.json`, SCOPE_START_FAILURE, NOTICE_TTL_MS;
79848
80081
  var init_resources = __esm(() => {
79849
80082
  init_checks3();
79850
80083
  init_heavy();
@@ -79873,8 +80106,8 @@ __export(exports_check, {
79873
80106
  run: () => run12,
79874
80107
  workspaceResources: () => workspaceResources
79875
80108
  });
79876
- import os22 from "node:os";
79877
- import path57 from "node:path";
80109
+ import os24 from "node:os";
80110
+ import path59 from "node:path";
79878
80111
  function parse6(argv) {
79879
80112
  const split = argv.indexOf("--");
79880
80113
  const head = split >= 0 ? argv.slice(0, split) : [...argv];
@@ -80105,7 +80338,7 @@ ${footer}`;
80105
80338
  }
80106
80339
  async function workspaceResources(io) {
80107
80340
  const env = io.env;
80108
- const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path57.join(env.XDG_CONFIG_HOME || path57.join(env.HOME || os22.homedir(), ".config"), "workit");
80341
+ const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path59.join(env.XDG_CONFIG_HOME || path59.join(env.HOME || os24.homedir(), ".config"), "workit");
80109
80342
  try {
80110
80343
  await Promise.resolve().then(() => init_workspaces());
80111
80344
  const workspace = resolveWorkspaceFrom(io.cwd, dir, env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
@@ -80247,7 +80480,7 @@ async function run12(argv, io) {
80247
80480
  if (options.shell && command.length !== 1)
80248
80481
  return emit(io, fail2("invalid_input", '--shell takes the command as one string: workit check --shell -- "<cmd>"'));
80249
80482
  }
80250
- const relCwd = posix(path57.relative(top, runCwd));
80483
+ const relCwd = posix(path59.relative(top, runCwd));
80251
80484
  const configured = !options.shell && matchesNamedCheck(config, name, command, relCwd);
80252
80485
  const shadowed = !configured && name !== null ? config.checks.find((item) => item.name === name) : undefined;
80253
80486
  if (shadowed)
@@ -80312,7 +80545,7 @@ async function run12(argv, io) {
80312
80545
  const modifiedWorktree = key.tree !== null && treeAfter !== key.tree;
80313
80546
  const store = storeRoot(io.cwd);
80314
80547
  const blob = store.ok ? storeLog(store.value.root, result.log) : null;
80315
- const logPath = store.ok && blob ? path57.join(store.value.root, blob.ref) : null;
80548
+ const logPath = store.ok && blob ? path59.join(store.value.root, blob.ref) : null;
80316
80549
  const tail = tailLines(result.log, TAIL_LINES);
80317
80550
  const passed = result.exitCode === 0 && !result.timedOut;
80318
80551
  const bounded = boundedArgv(command);
@@ -80427,7 +80660,7 @@ async function run12(argv, io) {
80427
80660
  return recordError.code === "busy" ? 4 : recordError.code === "invalid_input" ? 2 : 5;
80428
80661
  return 0;
80429
80662
  }
80430
- var USAGE6 = 'workit check <name> [--full] [--wait <dur> | --no-wait] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <dur> | --no-wait] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', OUTPUT_LINES = 60, MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(path57.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, ANSI_COLOR, WARNING_LINE, NO_WARNINGS, STDERR_TAIL_LINES = 10, STDERR_KEEP_CHARS = 65536, FAILURE_LINE, MAX_FAILURE_LINES = 15;
80663
+ var USAGE6 = 'workit check <name> [--full] [--wait <dur> | --no-wait] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <dur> | --no-wait] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', OUTPUT_LINES = 60, MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(path59.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, ANSI_COLOR, WARNING_LINE, NO_WARNINGS, STDERR_TAIL_LINES = 10, STDERR_KEEP_CHARS = 65536, FAILURE_LINE, MAX_FAILURE_LINES = 15;
80431
80664
  var init_check2 = __esm(() => {
80432
80665
  init_check_config();
80433
80666
  init_checks3();
@@ -80458,7 +80691,7 @@ __export(exports_lock, {
80458
80691
  run: () => run13
80459
80692
  });
80460
80693
  import fs25 from "node:fs";
80461
- import path58 from "node:path";
80694
+ import path60 from "node:path";
80462
80695
  async function settingsFor(io) {
80463
80696
  const workspace = await workspaceResources(io);
80464
80697
  const config = loadCheckConfig(io.cwd);
@@ -80550,7 +80783,7 @@ function readPatterns(file) {
80550
80783
  return { patterns: [] };
80551
80784
  }
80552
80785
  function writePatterns(file, value) {
80553
- fs25.mkdirSync(path58.dirname(file), { recursive: true, mode: 448 });
80786
+ fs25.mkdirSync(path60.dirname(file), { recursive: true, mode: 448 });
80554
80787
  const temp = `${file}.${process.pid}.tmp`;
80555
80788
  fs25.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
80556
80789
  `, { mode: 384 });
@@ -80636,9 +80869,9 @@ var exports_models = {};
80636
80869
  __export(exports_models, {
80637
80870
  run: () => run14
80638
80871
  });
80639
- import { existsSync as existsSync25, readdirSync as readdirSync13, readFileSync as readFileSync26, statSync as statSync9 } from "node:fs";
80640
- import os23 from "node:os";
80641
- import path59 from "node:path";
80872
+ import { existsSync as existsSync26, readdirSync as readdirSync13, readFileSync as readFileSync27, statSync as statSync9 } from "node:fs";
80873
+ import os25 from "node:os";
80874
+ import path61 from "node:path";
80642
80875
  async function run14(argv, io) {
80643
80876
  const [sub, ...args] = argv.filter((arg) => arg !== "--json");
80644
80877
  if (sub !== "show")
@@ -80699,7 +80932,7 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
80699
80932
  const found = new Set;
80700
80933
  let text = "";
80701
80934
  try {
80702
- text = readFileSync26(file, "utf8");
80935
+ text = readFileSync27(file, "utf8");
80703
80936
  } catch {
80704
80937
  return found;
80705
80938
  }
@@ -80713,26 +80946,26 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
80713
80946
  } catch {}
80714
80947
  return found;
80715
80948
  }, matches3 = (ran, configured) => ran.toLowerCase().includes(configured.toLowerCase()), usageReport = (cwd, env, days) => {
80716
- const projects = path59.join(env.CLAUDE_CONFIG_DIR || path59.join(env.HOME || os23.homedir(), ".claude"), "projects");
80949
+ const projects = path61.join(env.CLAUDE_CONFIG_DIR || path61.join(env.HOME || os25.homedir(), ".claude"), "projects");
80717
80950
  const since = Date.now() - days * 86400000;
80718
80951
  const types = {};
80719
80952
  let agents = 0;
80720
80953
  const dirs = (dir) => {
80721
80954
  try {
80722
- return readdirSync13(dir).map((name) => path59.join(dir, name));
80955
+ return readdirSync13(dir).map((name) => path61.join(dir, name));
80723
80956
  } catch {
80724
80957
  return [];
80725
80958
  }
80726
80959
  };
80727
80960
  for (const project of dirs(projects))
80728
80961
  for (const session of dirs(project))
80729
- for (const meta of dirs(path59.join(session, "subagents")).filter((f) => f.endsWith(".meta.json"))) {
80962
+ for (const meta of dirs(path61.join(session, "subagents")).filter((f) => f.endsWith(".meta.json"))) {
80730
80963
  try {
80731
80964
  if (statSync9(meta).mtimeMs < since)
80732
80965
  continue;
80733
- const agentType = JSON.parse(readFileSync26(meta, "utf8")).agentType;
80966
+ const agentType = JSON.parse(readFileSync27(meta, "utf8")).agentType;
80734
80967
  const transcript = meta.replace(/\.meta\.json$/, ".jsonl");
80735
- if (typeof agentType !== "string" || !existsSync25(transcript))
80968
+ if (typeof agentType !== "string" || !existsSync26(transcript))
80736
80969
  continue;
80737
80970
  const ran = modelsOf(transcript);
80738
80971
  if (!ran.size)
@@ -80871,8 +81104,8 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
80871
81104
 
80872
81105
  // packages/workit-core/src/git/ops.ts
80873
81106
  import { spawnSync as spawnSync21 } from "node:child_process";
80874
- import { existsSync as existsSync26, readFileSync as readFileSync27 } from "node:fs";
80875
- import path60 from "node:path";
81107
+ import { existsSync as existsSync27, readFileSync as readFileSync28 } from "node:fs";
81108
+ import path62 from "node:path";
80876
81109
  function operationInProgress(cwd) {
80877
81110
  const markers = [
80878
81111
  ["rebase-merge", "rebase"],
@@ -80885,18 +81118,18 @@ function operationInProgress(cwd) {
80885
81118
  if (!run.ok)
80886
81119
  return null;
80887
81120
  const found = run.stdout.split(`
80888
- `).map((line) => path60.resolve(cwd, line.trim()));
81121
+ `).map((line) => path62.resolve(cwd, line.trim()));
80889
81122
  const conflicted = () => git5(cwd, ["ls-files", "-u"]).stdout.trim() !== "";
80890
81123
  for (const [index, [, operation]] of markers.entries()) {
80891
81124
  const marker = found[index];
80892
- if (!marker || !existsSync26(marker))
81125
+ if (!marker || !existsSync27(marker))
80893
81126
  continue;
80894
- if (index === 1 && existsSync26(path60.join(marker, "applying")))
81127
+ if (index === 1 && existsSync27(path62.join(marker, "applying")))
80895
81128
  return { operation: "am", commitAllowed: false, branch: null };
80896
- if (index === 0 && existsSync26(path60.join(marker, "amend")) && !conflicted()) {
81129
+ if (index === 0 && existsSync27(path62.join(marker, "amend")) && !conflicted()) {
80897
81130
  let headName = "";
80898
81131
  try {
80899
- headName = readFileSync27(path60.join(marker, "head-name"), "utf8").trim();
81132
+ headName = readFileSync28(path62.join(marker, "head-name"), "utf8").trim();
80900
81133
  } catch {}
80901
81134
  const branch = headName.startsWith("refs/heads/") ? headName.slice("refs/heads/".length) : null;
80902
81135
  return { operation, commitAllowed: branch !== null, branch };
@@ -81231,7 +81464,7 @@ function gitCommit(cwd, input) {
81231
81464
  if (paths.some((value) => value.startsWith("-") || !value.trim()))
81232
81465
  return failure3("invalid_input", "paths must not be empty or start with -");
81233
81466
  const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
81234
- const addable = paths.filter((value) => existsSync26(path60.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
81467
+ const addable = paths.filter((value) => existsSync27(path62.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
81235
81468
  if (addable.length) {
81236
81469
  const added = git5(cwd, ["add", "-A", "--", ...addable]);
81237
81470
  if (!added.ok)
@@ -81772,12 +82005,12 @@ var init_ops = __esm(() => {
81772
82005
 
81773
82006
  // packages/workit-core/src/verdict-cover.ts
81774
82007
  import fs26 from "node:fs";
81775
- import path61 from "node:path";
82008
+ import path63 from "node:path";
81776
82009
  function chainsAbove(cwd, branch) {
81777
82010
  const root = storeRoot(cwd);
81778
82011
  if (!root.ok)
81779
82012
  return [];
81780
- const dir = path61.join(root.value.root, "stacks");
82013
+ const dir = path63.join(root.value.root, "stacks");
81781
82014
  let names = [];
81782
82015
  try {
81783
82016
  names = fs26.readdirSync(dir).filter((name) => name.endsWith(".json"));
@@ -81788,7 +82021,7 @@ function chainsAbove(cwd, branch) {
81788
82021
  for (const name of names.toSorted()) {
81789
82022
  let parsed;
81790
82023
  try {
81791
- parsed = JSON.parse(fs26.readFileSync(path61.join(dir, name), "utf8"));
82024
+ parsed = JSON.parse(fs26.readFileSync(path63.join(dir, name), "utf8"));
81792
82025
  } catch {
81793
82026
  continue;
81794
82027
  }
@@ -81944,10 +82177,10 @@ var init_check_evidence = __esm(() => {
81944
82177
 
81945
82178
  // packages/workit-core/src/forge/reruns.ts
81946
82179
  import fs27 from "node:fs";
81947
- import path62 from "node:path";
82180
+ import path64 from "node:path";
81948
82181
  function rerunLogPath(cwd) {
81949
82182
  const common = gitCommonDir(cwd);
81950
- return common ? path62.join(common, "workit", "ci-reruns.jsonl") : null;
82183
+ return common ? path64.join(common, "workit", "ci-reruns.jsonl") : null;
81951
82184
  }
81952
82185
  function rerunCounts(cwd, key) {
81953
82186
  const counts = new Map;
@@ -81982,7 +82215,7 @@ function recordReruns(cwd, rows) {
81982
82215
  if (!file)
81983
82216
  return false;
81984
82217
  try {
81985
- fs27.mkdirSync(path62.dirname(file), { recursive: true });
82218
+ fs27.mkdirSync(path64.dirname(file), { recursive: true });
81986
82219
  fs27.appendFileSync(file, rows.map((row) => `${JSON.stringify(row)}
81987
82220
  `).join(""));
81988
82221
  return true;
@@ -81995,7 +82228,7 @@ function withRerunLock(cwd, fn) {
81995
82228
  if (!file)
81996
82229
  return fn();
81997
82230
  const lock = `${file.slice(0, -".jsonl".length)}.lock`;
81998
- fs27.mkdirSync(path62.dirname(lock), { recursive: true });
82231
+ fs27.mkdirSync(path64.dirname(lock), { recursive: true });
81999
82232
  const until = Date.now() + LOCK_WAIT_MS2;
82000
82233
  for (;; ) {
82001
82234
  try {
@@ -82991,7 +83224,7 @@ var init_pr_ops = __esm(() => {
82991
83224
  import { spawnSync as spawnSync23 } from "node:child_process";
82992
83225
  import { createHash as createHash18, randomBytes as randomBytes4 } from "node:crypto";
82993
83226
  import fs28 from "node:fs";
82994
- import path63 from "node:path";
83227
+ import path65 from "node:path";
82995
83228
  function worktreeOf(cwd, branch) {
82996
83229
  const list = gitRun3(cwd, ["worktree", "list", "--porcelain"]);
82997
83230
  if (!list.ok)
@@ -83040,7 +83273,7 @@ function gitRestack(cwd, input) {
83040
83273
  error: "no store root"
83041
83274
  };
83042
83275
  fs28.mkdirSync(scratch, { recursive: true });
83043
- dir = path63.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
83276
+ dir = path65.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
83044
83277
  const added = gitRun3(cwd, ["worktree", "add", "-q", dir, input.branch], GIT_TIMEOUTS.worktree);
83045
83278
  if (!added.ok)
83046
83279
  return {
@@ -83096,7 +83329,7 @@ function pruneScratch(cwd) {
83096
83329
  if (!scratch || !fs28.existsSync(scratch))
83097
83330
  return;
83098
83331
  for (const name of fs28.readdirSync(scratch)) {
83099
- const dir = path63.join(scratch, name);
83332
+ const dir = path65.join(scratch, name);
83100
83333
  if (!rebaseInProgress(dir) && !trackedDirt(dir))
83101
83334
  gitRun3(cwd, ["worktree", "remove", "--force", dir]);
83102
83335
  }
@@ -83106,7 +83339,7 @@ function stacksDir(cwd) {
83106
83339
  const root = storeRoot(cwd);
83107
83340
  if (!root.ok)
83108
83341
  return stackFail(root.code, root.error, root.unblock);
83109
- return { ok: true, data: path63.join(root.value.root, "stacks") };
83342
+ return { ok: true, data: path65.join(root.value.root, "stacks") };
83110
83343
  }
83111
83344
  function parseStack(raw) {
83112
83345
  if (!isRecord12(raw) || !Array.isArray(raw.branches))
@@ -83158,7 +83391,7 @@ function readStack(cwd, name) {
83158
83391
  const dir = stacksDir(cwd);
83159
83392
  if (!dir.ok)
83160
83393
  return dir;
83161
- const file = path63.join(dir.data, fileFor(name));
83394
+ const file = path65.join(dir.data, fileFor(name));
83162
83395
  let text;
83163
83396
  try {
83164
83397
  text = fs28.readFileSync(file, "utf8");
@@ -83179,7 +83412,7 @@ function writeStack(cwd, stack, now = new Date) {
83179
83412
  const dir = stacksDir(cwd);
83180
83413
  if (!dir.ok)
83181
83414
  return dir;
83182
- const file = path63.join(dir.data, fileFor(stack.name));
83415
+ const file = path65.join(dir.data, fileFor(stack.name));
83183
83416
  const temp = `${file}.${process.pid}.tmp`;
83184
83417
  try {
83185
83418
  fs28.mkdirSync(dir.data, { recursive: true });
@@ -83207,7 +83440,7 @@ function listStacks(cwd) {
83207
83440
  for (const name of names) {
83208
83441
  let parsed = null;
83209
83442
  try {
83210
- parsed = parseStack(JSON.parse(fs28.readFileSync(path63.join(dir.data, name), "utf8")));
83443
+ parsed = parseStack(JSON.parse(fs28.readFileSync(path65.join(dir.data, name), "utf8")));
83211
83444
  } catch {
83212
83445
  parsed = null;
83213
83446
  }
@@ -83269,7 +83502,7 @@ function takeLock(lock) {
83269
83502
  host: localLockHost(),
83270
83503
  nonce: randomBytes4(8).toString("hex")
83271
83504
  };
83272
- fs28.writeFileSync(path63.join(lock, OWNER), JSON.stringify(owner));
83505
+ fs28.writeFileSync(path65.join(lock, OWNER), JSON.stringify(owner));
83273
83506
  return owner;
83274
83507
  }
83275
83508
  function reapLock(lock, observed) {
@@ -83306,7 +83539,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
83306
83539
  return dir;
83307
83540
  if (!validName(name))
83308
83541
  return stackFail("invalid_input", "a stack name must be 1-200 printable characters");
83309
- const lock = path63.join(dir.data, `${fileFor(name)}.lock`);
83542
+ const lock = path65.join(dir.data, `${fileFor(name)}.lock`);
83310
83543
  try {
83311
83544
  fs28.mkdirSync(dir.data, { recursive: true });
83312
83545
  } catch (error) {
@@ -83336,7 +83569,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
83336
83569
  const touch = () => {
83337
83570
  try {
83338
83571
  const now = new Date;
83339
- fs28.utimesSync(path63.join(lock, OWNER), now, now);
83572
+ fs28.utimesSync(path65.join(lock, OWNER), now, now);
83340
83573
  } catch {}
83341
83574
  };
83342
83575
  const beat = setInterval(touch, HEARTBEAT_MS);
@@ -84305,7 +84538,7 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
84305
84538
  return !status.ok || status.stdout.trim() !== "";
84306
84539
  }, scratchDir = (cwd) => {
84307
84540
  const dir = stacksDir(cwd);
84308
- return dir.ok ? path63.join(dir.data, "worktrees") : null;
84541
+ return dir.ok ? path65.join(dir.data, "worktrees") : null;
84309
84542
  }, firstLine = (run) => (`${run.stderr}
84310
84543
  ${run.stdout}`.split(`
84311
84544
  `).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()}-${createHash18("sha256").update(name).digest("hex").slice(0, 12)}.json`, fileFor, validName = (name) => {
@@ -84320,12 +84553,12 @@ ${run.stdout}`.split(`
84320
84553
  }, isRecord12 = (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) => {
84321
84554
  let raw = null;
84322
84555
  try {
84323
- raw = fs28.readFileSync(path63.join(lock, OWNER), "utf8");
84556
+ raw = fs28.readFileSync(path65.join(lock, OWNER), "utf8");
84324
84557
  } catch {
84325
84558
  raw = null;
84326
84559
  }
84327
84560
  let age = null;
84328
- for (const target of [path63.join(lock, OWNER), lock])
84561
+ for (const target of [path65.join(lock, OWNER), lock])
84329
84562
  try {
84330
84563
  age = Date.now() - fs28.statSync(target).mtimeMs;
84331
84564
  break;
@@ -84369,7 +84602,7 @@ var init_stack = __esm(() => {
84369
84602
  import { spawnSync as spawnSync24 } from "node:child_process";
84370
84603
  import { createHash as createHash19 } from "node:crypto";
84371
84604
  import fs29 from "node:fs";
84372
- import path64 from "node:path";
84605
+ import path66 from "node:path";
84373
84606
  function expandBraces2(pattern, limit = 64) {
84374
84607
  for (let index = 0;index < pattern.length; index += 1) {
84375
84608
  if (pattern[index] === "\\") {
@@ -84615,7 +84848,7 @@ function parsePlan(raw, defaults, name) {
84615
84848
  id,
84616
84849
  branch,
84617
84850
  base: optional("base") ?? "",
84618
- worktree: path64.resolve(defaults.root, optional("worktree") ?? path64.join(defaults.worktreeRoot, id)),
84851
+ worktree: path66.resolve(defaults.root, optional("worktree") ?? path66.join(defaults.worktreeRoot, id)),
84619
84852
  tier,
84620
84853
  reason,
84621
84854
  dependsOn: [...new Set(dependsOn ?? [])],
@@ -84744,12 +84977,12 @@ function regeneratedFiles(root, tracked) {
84744
84977
  const found = new Map;
84745
84978
  let scripts;
84746
84979
  try {
84747
- const manifest = JSON.parse(fs29.readFileSync(path64.join(root, "package.json"), "utf8"));
84980
+ const manifest = JSON.parse(fs29.readFileSync(path66.join(root, "package.json"), "utf8"));
84748
84981
  scripts = manifest.scripts ?? {};
84749
84982
  } catch {
84750
84983
  return found;
84751
84984
  }
84752
- const runner = fs29.existsSync(path64.join(root, "bun.lock")) ? "bun run" : fs29.existsSync(path64.join(root, "pnpm-lock.yaml")) ? "pnpm run" : fs29.existsSync(path64.join(root, "yarn.lock")) ? "yarn run" : "npm run";
84985
+ const runner = fs29.existsSync(path66.join(root, "bun.lock")) ? "bun run" : fs29.existsSync(path66.join(root, "pnpm-lock.yaml")) ? "pnpm run" : fs29.existsSync(path66.join(root, "yarn.lock")) ? "yarn run" : "npm run";
84753
84986
  const outputs = tracked.filter((file) => !CODE.test(file));
84754
84987
  for (const [name, command] of Object.entries(scripts)) {
84755
84988
  if (!name.startsWith("write:") || typeof command !== "string")
@@ -84757,7 +84990,7 @@ function regeneratedFiles(root, tracked) {
84757
84990
  for (const file of command.match(/[\w./-]+\.[cm]?[jt]s\b/gu) ?? []) {
84758
84991
  let source;
84759
84992
  try {
84760
- source = fs29.readFileSync(path64.join(root, file), "utf8");
84993
+ source = fs29.readFileSync(path66.join(root, file), "utf8");
84761
84994
  } catch {
84762
84995
  continue;
84763
84996
  }
@@ -84879,11 +85112,11 @@ function defaultTrunk(cwd) {
84879
85112
  }
84880
85113
  function mainCheckout(cwd) {
84881
85114
  const common = gitCommonDir(cwd);
84882
- return common && path64.basename(common) === ".git" ? path64.dirname(common) : path64.resolve(cwd);
85115
+ return common && path66.basename(common) === ".git" ? path66.dirname(common) : path66.resolve(cwd);
84883
85116
  }
84884
85117
  function worktreeRoot(cwd) {
84885
85118
  const main = mainCheckout(cwd);
84886
- return path64.join(path64.dirname(main), `${path64.basename(main)}-wt`);
85119
+ return path66.join(path66.dirname(main), `${path66.basename(main)}-wt`);
84887
85120
  }
84888
85121
  function sliceHash(slice) {
84889
85122
  const {
@@ -84903,7 +85136,7 @@ function fanoutsDir(cwd) {
84903
85136
  const root = storeRoot(cwd);
84904
85137
  if (!root.ok)
84905
85138
  return fanoutFail(root.code, root.error, root.unblock);
84906
- return { ok: true, data: path64.join(root.value.root, "fanouts") };
85139
+ return { ok: true, data: path66.join(root.value.root, "fanouts") };
84907
85140
  }
84908
85141
  function parseStored(raw) {
84909
85142
  if (!isRecord13(raw) || typeof raw.name !== "string" || typeof raw.trunk !== "string")
@@ -84971,7 +85204,7 @@ function readFanout(cwd, name) {
84971
85204
  const dir = fanoutsDir(cwd);
84972
85205
  if (!dir.ok)
84973
85206
  return dir;
84974
- const file = path64.join(dir.data, stackFileName(name));
85207
+ const file = path66.join(dir.data, stackFileName(name));
84975
85208
  let parsed = null;
84976
85209
  try {
84977
85210
  parsed = parseStored(JSON.parse(fs29.readFileSync(file, "utf8")));
@@ -84996,7 +85229,7 @@ function listFanouts(cwd) {
84996
85229
  for (const entry of names) {
84997
85230
  let parsed = null;
84998
85231
  try {
84999
- parsed = parseStored(JSON.parse(fs29.readFileSync(path64.join(dir.data, entry), "utf8")));
85232
+ parsed = parseStored(JSON.parse(fs29.readFileSync(path66.join(dir.data, entry), "utf8")));
85000
85233
  } catch {
85001
85234
  parsed = null;
85002
85235
  }
@@ -85035,7 +85268,7 @@ function writeFanout(cwd, plan) {
85035
85268
  const dir = fanoutsDir(cwd);
85036
85269
  if (!dir.ok)
85037
85270
  return dir;
85038
- const file = path64.join(dir.data, stackFileName(plan.name));
85271
+ const file = path66.join(dir.data, stackFileName(plan.name));
85039
85272
  const temp = `${file}.${process.pid}.tmp`;
85040
85273
  try {
85041
85274
  fs29.mkdirSync(dir.data, { recursive: true });
@@ -85246,13 +85479,13 @@ var init_fanout = __esm(() => {
85246
85479
  // packages/workit-core/src/forge/exec.ts
85247
85480
  import { spawnSync as spawnSync25 } from "node:child_process";
85248
85481
  import fs30 from "node:fs";
85249
- import path65 from "node:path";
85482
+ import path67 from "node:path";
85250
85483
  function findExecutable(bin, env) {
85251
- const dirs = (env.PATH ?? env.Path ?? "").split(path65.delimiter).filter(Boolean);
85484
+ const dirs = (env.PATH ?? env.Path ?? "").split(path67.delimiter).filter(Boolean);
85252
85485
  const exts = process.platform === "win32" ? [".exe"] : [""];
85253
85486
  for (const dir of dirs)
85254
85487
  for (const ext of exts) {
85255
- const candidate = path65.join(dir, `${bin}${ext}`);
85488
+ const candidate = path67.join(dir, `${bin}${ext}`);
85256
85489
  try {
85257
85490
  const stat = fs30.statSync(candidate);
85258
85491
  if (stat.isFile())
@@ -87042,7 +87275,7 @@ var init_live_session = __esm(() => {
87042
87275
  });
87043
87276
 
87044
87277
  // packages/workit-core/src/hooks/write-gate.ts
87045
- import path66 from "node:path";
87278
+ import path68 from "node:path";
87046
87279
  var CASE_INSENSITIVE, PREFIXES2, SCRIPT_SHELLS, cache3, MUTATING_GIT, DRY_N, MUTATING_WORKIT_GIT, CD2, PUSHD2, POPD2, UNKNOWN_DIR;
87047
87280
  var init_write_gate = __esm(() => {
87048
87281
  init_task_store();
@@ -87082,7 +87315,7 @@ var init_write_gate = __esm(() => {
87082
87315
  CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
87083
87316
  PUSHD2 = new Set(["pushd", "push-location"]);
87084
87317
  POPD2 = new Set(["popd", "pop-location"]);
87085
- UNKNOWN_DIR = path66.resolve(path66.parse(process.cwd()).root, ".workit-unknown-dir");
87318
+ UNKNOWN_DIR = path68.resolve(path68.parse(process.cwd()).root, ".workit-unknown-dir");
87086
87319
  });
87087
87320
 
87088
87321
  // packages/workit-core/src/hooks/worktree-confine.ts
@@ -87107,20 +87340,20 @@ var init_worktree_confine = __esm(() => {
87107
87340
 
87108
87341
  // packages/workit-core/src/worktree-deps.ts
87109
87342
  import fs31 from "node:fs";
87110
- import path67 from "node:path";
87343
+ import path69 from "node:path";
87111
87344
  function moduleDirs(main) {
87112
87345
  const out = [];
87113
87346
  const walk = (relative, depth) => {
87114
87347
  let entries;
87115
87348
  try {
87116
- entries = fs31.readdirSync(path67.join(main, relative), { withFileTypes: true });
87349
+ entries = fs31.readdirSync(path69.join(main, relative), { withFileTypes: true });
87117
87350
  } catch {
87118
87351
  return;
87119
87352
  }
87120
87353
  for (const entry of entries) {
87121
87354
  if (!entry.isDirectory())
87122
87355
  continue;
87123
- const child = path67.join(relative, entry.name);
87356
+ const child = path69.join(relative, entry.name);
87124
87357
  if (entry.name === MODULES)
87125
87358
  out.push(child);
87126
87359
  else if (depth < MAX_DEPTH2 && !entry.name.startsWith("."))
@@ -87134,8 +87367,8 @@ function linkEntry(main, worktree, source, target) {
87134
87367
  const stat = fs31.lstatSync(source);
87135
87368
  if (stat.isSymbolicLink()) {
87136
87369
  const link = fs31.readlinkSync(source);
87137
- const outside = path67.isAbsolute(link) && within(link, main) && !path67.relative(main, link).split(path67.sep).includes(MODULES);
87138
- const to = outside ? path67.join(worktree, path67.relative(main, link)) : link;
87370
+ const outside = path69.isAbsolute(link) && within(link, main) && !path69.relative(main, link).split(path69.sep).includes(MODULES);
87371
+ const to = outside ? path69.join(worktree, path69.relative(main, link)) : link;
87139
87372
  fs31.symlinkSync(to, target, process.platform === "win32" ? "junction" : undefined);
87140
87373
  return;
87141
87374
  }
@@ -87145,8 +87378,8 @@ function mirror(main, worktree, source, target, top) {
87145
87378
  fs31.mkdirSync(target);
87146
87379
  let count = 0;
87147
87380
  for (const entry of fs31.readdirSync(source, { withFileTypes: true })) {
87148
- const from = path67.join(source, entry.name);
87149
- const to = path67.join(target, entry.name);
87381
+ const from = path69.join(source, entry.name);
87382
+ const to = path69.join(target, entry.name);
87150
87383
  if (top && entry.isDirectory() && (entry.name.startsWith("@") || entry.name === ".bin"))
87151
87384
  count += mirror(main, worktree, from, to, false);
87152
87385
  else {
@@ -87162,16 +87395,16 @@ function linkWorktreeDependencies(main, worktree) {
87162
87395
  const dirs = [];
87163
87396
  let entries = 0;
87164
87397
  for (const relative of moduleDirs(main)) {
87165
- const target = path67.join(worktree, relative);
87166
- if (!fs31.existsSync(path67.dirname(target)) || fs31.existsSync(target))
87398
+ const target = path69.join(worktree, relative);
87399
+ if (!fs31.existsSync(path69.dirname(target)) || fs31.existsSync(target))
87167
87400
  continue;
87168
- if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(path67.sep).join("/")}/`]).ok) {
87169
- notes.push(`${relative.split(path67.sep).join("/")} is not ignored by git, so it was not linked from ${main}; install dependencies in the worktree yourself`);
87401
+ if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(path69.sep).join("/")}/`]).ok) {
87402
+ notes.push(`${relative.split(path69.sep).join("/")} is not ignored by git, so it was not linked from ${main}; install dependencies in the worktree yourself`);
87170
87403
  continue;
87171
87404
  }
87172
87405
  try {
87173
- entries += mirror(main, worktree, path67.join(main, relative), target, true);
87174
- dirs.push(relative.split(path67.sep).join("/"));
87406
+ entries += mirror(main, worktree, path69.join(main, relative), target, true);
87407
+ dirs.push(relative.split(path69.sep).join("/"));
87175
87408
  } catch (error) {
87176
87409
  fs31.rmSync(target, { recursive: true, force: true });
87177
87410
  notes.push(`could not link ${relative} from ${main} (${error.message}); install dependencies in the worktree yourself`);
@@ -87184,8 +87417,8 @@ function linkWorktreeDependencies(main, worktree) {
87184
87417
  return { linked: { from: main, dirs, entries, ms }, notes };
87185
87418
  }
87186
87419
  var MODULES = "node_modules", MAX_DEPTH2 = 2, within = (child, parent) => {
87187
- const relative = path67.relative(parent, child);
87188
- return relative === "" || !relative.startsWith("..") && !path67.isAbsolute(relative);
87420
+ const relative = path69.relative(parent, child);
87421
+ return relative === "" || !relative.startsWith("..") && !path69.isAbsolute(relative);
87189
87422
  };
87190
87423
  var init_worktree_deps = __esm(() => {
87191
87424
  init_fanout();
@@ -87194,7 +87427,7 @@ var init_worktree_deps = __esm(() => {
87194
87427
  // packages/workit-core/src/fanout-worktree.ts
87195
87428
  import { randomBytes as randomBytes5 } from "node:crypto";
87196
87429
  import fs32 from "node:fs";
87197
- import path68 from "node:path";
87430
+ import path70 from "node:path";
87198
87431
  function rowSample(lines) {
87199
87432
  const out = [];
87200
87433
  let bytes = 0;
@@ -87254,7 +87487,7 @@ function adminDir(worktree) {
87254
87487
  const file = dir.stdout.trim();
87255
87488
  let token = null;
87256
87489
  try {
87257
- token = fs32.readFileSync(path68.join(file, FANOUT_TOKEN_FILE), "utf8").trim() || null;
87490
+ token = fs32.readFileSync(path70.join(file, FANOUT_TOKEN_FILE), "utf8").trim() || null;
87258
87491
  } catch {
87259
87492
  token = null;
87260
87493
  }
@@ -87262,7 +87495,7 @@ function adminDir(worktree) {
87262
87495
  const stat = worktreeDeps.stat(file);
87263
87496
  return {
87264
87497
  path: file,
87265
- id: path68.basename(file),
87498
+ id: path70.basename(file),
87266
87499
  ino: stat.ino.toString(),
87267
87500
  token,
87268
87501
  birthMs: stat.birthtimeNs > 0n ? Number(stat.birthtimeMs) : null,
@@ -87278,7 +87511,7 @@ function markAdminDir(worktree) {
87278
87511
  return null;
87279
87512
  const token = randomBytes5(16).toString("hex");
87280
87513
  try {
87281
- fs32.writeFileSync(path68.join(admin.path, FANOUT_TOKEN_FILE), `${token}
87514
+ fs32.writeFileSync(path70.join(admin.path, FANOUT_TOKEN_FILE), `${token}
87282
87515
  `);
87283
87516
  } catch {
87284
87517
  return null;
@@ -87293,7 +87526,7 @@ function excludeScratch(cwd) {
87293
87526
  const common = gitCommonDir(cwd);
87294
87527
  if (!common)
87295
87528
  return;
87296
- const file = path68.join(common, "info", "exclude");
87529
+ const file = path70.join(common, "info", "exclude");
87297
87530
  let text = "";
87298
87531
  try {
87299
87532
  text = fs32.readFileSync(file, "utf8");
@@ -87302,7 +87535,7 @@ function excludeScratch(cwd) {
87302
87535
  }
87303
87536
  if (text.split(/\r?\n/u).includes(EXCLUDE_LINE))
87304
87537
  return;
87305
- fs32.mkdirSync(path68.dirname(file), { recursive: true });
87538
+ fs32.mkdirSync(path70.dirname(file), { recursive: true });
87306
87539
  fs32.appendFileSync(file, `${text && !text.endsWith(`
87307
87540
  `) ? `
87308
87541
  ` : ""}# workit fanout: per-worker scratch dirs
@@ -87311,13 +87544,13 @@ ${EXCLUDE_LINE}
87311
87544
  }
87312
87545
  function worktreeDependencies(main, worktree) {
87313
87546
  for (const [name, install] of LOCKFILES2) {
87314
- const ours = readBytes(path68.join(main, name));
87315
- const theirs = readBytes(path68.join(worktree, name));
87547
+ const ours = readBytes(path70.join(main, name));
87548
+ const theirs = readBytes(path70.join(worktree, name));
87316
87549
  if (ours === null && theirs === null)
87317
87550
  continue;
87318
87551
  if (ours !== null && theirs !== null && ours.equals(theirs))
87319
87552
  continue;
87320
- if (fs32.existsSync(path68.join(worktree, "node_modules")))
87553
+ if (fs32.existsSync(path70.join(worktree, "node_modules")))
87321
87554
  break;
87322
87555
  const command = install(worktree);
87323
87556
  return {
@@ -87329,7 +87562,7 @@ function worktreeDependencies(main, worktree) {
87329
87562
  };
87330
87563
  }
87331
87564
  const stale = staleBunInstall(main);
87332
- if (stale && !fs32.existsSync(path68.join(worktree, "node_modules"))) {
87565
+ if (stale && !fs32.existsSync(path70.join(worktree, "node_modules"))) {
87333
87566
  const command = `bun install --frozen-lockfile --cwd ${worktree}`;
87334
87567
  return {
87335
87568
  linked: null,
@@ -87342,9 +87575,9 @@ function worktreeDependencies(main, worktree) {
87342
87575
  return { ...linkWorktreeDependencies(main, worktree), install: null };
87343
87576
  }
87344
87577
  function staleBunInstall(main) {
87345
- if (!fs32.existsSync(path68.join(main, "node_modules")))
87578
+ if (!fs32.existsSync(path70.join(main, "node_modules")))
87346
87579
  return null;
87347
- const text = readBytes(path68.join(main, "bun.lock"))?.toString("utf8");
87580
+ const text = readBytes(path70.join(main, "bun.lock"))?.toString("utf8");
87348
87581
  if (!text)
87349
87582
  return null;
87350
87583
  let packages;
@@ -87371,7 +87604,7 @@ function staleBunInstall(main) {
87371
87604
  const version = spec.slice(at + 1);
87372
87605
  if (name !== key || version.includes(":"))
87373
87606
  continue;
87374
- const manifest = readBytes(path68.join(main, "node_modules", key, "package.json"));
87607
+ const manifest = readBytes(path70.join(main, "node_modules", key, "package.json"));
87375
87608
  if (!manifest) {
87376
87609
  problems.push(`${key} missing`);
87377
87610
  continue;
@@ -87388,7 +87621,7 @@ function staleBunInstall(main) {
87388
87621
  return problems.length ? problems.join("; ") : null;
87389
87622
  }
87390
87623
  function ensureScratch(worktree) {
87391
- const scratch = path68.join(worktree, SCRATCH_DIR);
87624
+ const scratch = path70.join(worktree, SCRATCH_DIR);
87392
87625
  fs32.mkdirSync(scratch, { recursive: true });
87393
87626
  return scratch;
87394
87627
  }
@@ -87662,7 +87895,7 @@ function unpushedCount(cwd, branch) {
87662
87895
  return count.ok ? Number(count.stdout.trim()) : null;
87663
87896
  }
87664
87897
  function removeScratch(worktree) {
87665
- const scratch = path68.join(worktree, SCRATCH_DIR);
87898
+ const scratch = path70.join(worktree, SCRATCH_DIR);
87666
87899
  let stat;
87667
87900
  try {
87668
87901
  stat = fs32.lstatSync(scratch);
@@ -87678,16 +87911,16 @@ var SLOW, SCRATCH_DIR = ".workit-scratch", EXCLUDE_LINE, DIRTY_ROW_BYTES = 2000,
87678
87911
  try {
87679
87912
  return fs32.realpathSync.native(target);
87680
87913
  } catch {
87681
- return path68.resolve(target);
87914
+ return path70.resolve(target);
87682
87915
  }
87683
87916
  }, samePath = (a, b) => {
87684
87917
  const left = canonical2(a);
87685
87918
  const right = canonical2(b);
87686
87919
  return process.platform === "win32" || process.platform === "darwin" ? left.toLowerCase() === right.toLowerCase() : left === right;
87687
87920
  }, inside3 = (child, parent) => {
87688
- const relative = path68.relative(canonical2(parent), canonical2(child));
87689
- return relative === "" || !relative.startsWith("..") && !path68.isAbsolute(relative);
87690
- }, slicePath = (cwd, slice) => path68.isAbsolute(slice.worktree) ? slice.worktree : path68.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, LOCKFILES2, readBytes = (file) => {
87921
+ const relative = path70.relative(canonical2(parent), canonical2(child));
87922
+ return relative === "" || !relative.startsWith("..") && !path70.isAbsolute(relative);
87923
+ }, slicePath = (cwd, slice) => path70.isAbsolute(slice.worktree) ? slice.worktree : path70.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, LOCKFILES2, readBytes = (file) => {
87691
87924
  try {
87692
87925
  return fs32.readFileSync(file);
87693
87926
  } catch {
@@ -87719,7 +87952,7 @@ var init_fanout_worktree = __esm(() => {
87719
87952
 
87720
87953
  // packages/workit-core/src/forge/merge-cleanup.ts
87721
87954
  import fs33 from "node:fs";
87722
- import path69 from "node:path";
87955
+ import path71 from "node:path";
87723
87956
  function cleanupMergedBranch(cwd, branch, mergedHead) {
87724
87957
  const out = { branchDeleted: false, worktreeRemoved: null, notes: [] };
87725
87958
  if (!branch || branch.startsWith("-"))
@@ -87779,13 +88012,13 @@ var SLOW2, isFanoutWorktree = (worktree) => {
87779
88012
  if (!dir.ok)
87780
88013
  return false;
87781
88014
  try {
87782
- return fs33.readFileSync(path69.join(dir.stdout.trim(), FANOUT_TOKEN_FILE), "utf8").trim() !== "";
88015
+ return fs33.readFileSync(path71.join(dir.stdout.trim(), FANOUT_TOKEN_FILE), "utf8").trim() !== "";
87783
88016
  } catch {
87784
88017
  return false;
87785
88018
  }
87786
88019
  }, inside4 = (child, parent) => {
87787
- const relative = path69.relative(fs33.realpathSync.native(parent), fs33.realpathSync.native(child));
87788
- return relative === "" || !relative.startsWith("..") && !path69.isAbsolute(relative);
88020
+ const relative = path71.relative(fs33.realpathSync.native(parent), fs33.realpathSync.native(child));
88021
+ return relative === "" || !relative.startsWith("..") && !path71.isAbsolute(relative);
87789
88022
  };
87790
88023
  var init_merge_cleanup = __esm(() => {
87791
88024
  init_fanout();
@@ -88066,7 +88299,7 @@ var init_duration = __esm(() => {
88066
88299
  });
88067
88300
 
88068
88301
  // packages/workit-cli/src/verbs/forge-common.ts
88069
- import { readFileSync as readFileSync28 } from "node:fs";
88302
+ import { readFileSync as readFileSync29 } from "node:fs";
88070
88303
  function parseFlags(argv, spec) {
88071
88304
  const parsed = { values: {}, booleans: new Set, lists: {}, positionals: [] };
88072
88305
  for (let index = 0;index < argv.length; index += 1) {
@@ -88224,7 +88457,7 @@ var init_forge_common = __esm(() => {
88224
88457
  forgeDeps = {
88225
88458
  runner: undefined,
88226
88459
  npm: undefined,
88227
- readStdin: () => readFileSync28(0, "utf8"),
88460
+ readStdin: () => readFileSync29(0, "utf8"),
88228
88461
  sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
88229
88462
  now: () => Date.now()
88230
88463
  };
@@ -88236,8 +88469,8 @@ __export(exports_pr, {
88236
88469
  checkPrTitle: () => checkPrTitle,
88237
88470
  run: () => run15
88238
88471
  });
88239
- import { existsSync as existsSync27, readFileSync as readFileSync29 } from "node:fs";
88240
- import path70 from "node:path";
88472
+ import { existsSync as existsSync28, readFileSync as readFileSync30 } from "node:fs";
88473
+ import path72 from "node:path";
88241
88474
  function titleRules(cwd) {
88242
88475
  let root;
88243
88476
  try {
@@ -88248,16 +88481,16 @@ function titleRules(cwd) {
88248
88481
  let text = null;
88249
88482
  let name = "";
88250
88483
  for (const candidate of COMMITLINT_FILES) {
88251
- const full = path70.join(root, candidate);
88252
- if (!existsSync27(full))
88484
+ const full = path72.join(root, candidate);
88485
+ if (!existsSync28(full))
88253
88486
  continue;
88254
- text = readFileSync29(full, "utf8");
88487
+ text = readFileSync30(full, "utf8");
88255
88488
  name = candidate;
88256
88489
  break;
88257
88490
  }
88258
88491
  if (text === null) {
88259
88492
  try {
88260
- const pkg = JSON.parse(readFileSync29(path70.join(root, "package.json"), "utf8"));
88493
+ const pkg = JSON.parse(readFileSync30(path72.join(root, "package.json"), "utf8"));
88261
88494
  if (pkg.commitlint === undefined)
88262
88495
  return { rules: null, note: null };
88263
88496
  text = JSON.stringify(pkg.commitlint);
@@ -88354,7 +88587,7 @@ function refuseTitle(io, title, line) {
88354
88587
  function readBodyFile(io, file) {
88355
88588
  try {
88356
88589
  return {
88357
- body: file === "-" ? forgeDeps.readStdin() : readFileSync29(path70.resolve(io.cwd, file), "utf8")
88590
+ body: file === "-" ? forgeDeps.readStdin() : readFileSync30(path72.resolve(io.cwd, file), "utf8")
88358
88591
  };
88359
88592
  } catch {
88360
88593
  return `cannot read --body-file ${file}`;
@@ -89243,8 +89476,8 @@ var exports_git = {};
89243
89476
  __export(exports_git, {
89244
89477
  run: () => run17
89245
89478
  });
89246
- import { readFileSync as readFileSync30 } from "node:fs";
89247
- import path71 from "node:path";
89479
+ import { readFileSync as readFileSync31 } from "node:fs";
89480
+ import path73 from "node:path";
89248
89481
  function kindHint(cwd, kind) {
89249
89482
  let kinds = [...BRANCH_KINDS];
89250
89483
  try {
@@ -89348,7 +89581,7 @@ function commitMessage(parsed, io) {
89348
89581
 
89349
89582
  `);
89350
89583
  try {
89351
- return file === "-" ? readFileSync30(0, "utf8") : readFileSync30(path71.resolve(io.cwd, file), "utf8");
89584
+ return file === "-" ? readFileSync31(0, "utf8") : readFileSync31(path73.resolve(io.cwd, file), "utf8");
89352
89585
  } catch (error) {
89353
89586
  return {
89354
89587
  error: `cannot read -F ${file}: ${error instanceof Error ? error.message : String(error)}`
@@ -90812,7 +91045,7 @@ var init_stack2 = __esm(() => {
90812
91045
  // packages/workit-core/src/fanout-brief.ts
90813
91046
  import { createHash as createHash20 } from "node:crypto";
90814
91047
  import fs35 from "node:fs";
90815
- import path72 from "node:path";
91048
+ import path74 from "node:path";
90816
91049
  function workerSession(lead, slice, attempt) {
90817
91050
  const tail = attempt === null ? "" : `+try${attempt}`;
90818
91051
  const full = `${lead}-w-${slice}${tail}`;
@@ -90895,7 +91128,7 @@ function renderBrief(cwd, plan, input) {
90895
91128
  "STANDING:",
90896
91129
  ...standing.length ? standing.map((order) => ` - ${order.what}`) : [" - none recorded beyond this brief"],
90897
91130
  exists ? `WORKTREE: ${planned} (made by \`workit fanout worktree create ${slice.id}\`; yours alone)` : `WORKTREE: ${planned} (not made yet: the lead runs \`workit fanout worktree create ${slice.id}\` before spawning, then renders this brief again)`,
90898
- ...exists && typeof made?.install === "string" && !fs35.existsSync(path72.join(planned, "node_modules")) ? [`INSTALL: \`${made.install}\` first: the main checkout's node_modules was not linked here`] : [],
91131
+ ...exists && typeof made?.install === "string" && !fs35.existsSync(path74.join(planned, "node_modules")) ? [`INSTALL: \`${made.install}\` first: the main checkout's node_modules was not linked here`] : [],
90899
91132
  ...identityLines(identity, minted),
90900
91133
  ...rules(mode, branch, sliceBase, exists ? planned : null)
90901
91134
  ];
@@ -91437,7 +91670,7 @@ __export(exports_fanout, {
91437
91670
  run: () => run21
91438
91671
  });
91439
91672
  import fs36 from "node:fs";
91440
- import path73 from "node:path";
91673
+ import path75 from "node:path";
91441
91674
  function forgeFor(io, offline) {
91442
91675
  if (offline)
91443
91676
  return { forge: null, error: "--offline" };
@@ -91498,7 +91731,7 @@ function plan2(argv, io) {
91498
91731
  return usage4(io, "pass --trunk or --track, not both (--track picks the trunk)", PLAN_USAGE2);
91499
91732
  if (flags.positionals.length !== 1)
91500
91733
  return usage4(io, flags.positionals.length ? `unexpected argument ${flags.positionals[1]}` : "missing <plan.json>", PLAN_USAGE2);
91501
- const file = path73.resolve(io.cwd, flags.positionals[0]);
91734
+ const file = path75.resolve(io.cwd, flags.positionals[0]);
91502
91735
  let raw;
91503
91736
  try {
91504
91737
  raw = JSON.parse(fs36.readFileSync(file, "utf8"));
@@ -107074,7 +107307,7 @@ var init_ast = __esm(() => {
107074
107307
 
107075
107308
  // packages/workit-cli/src/test-audit/rules.ts
107076
107309
  import { builtinModules } from "node:module";
107077
- import path74 from "node:path";
107310
+ import path76 from "node:path";
107078
107311
  function testCallee(call) {
107079
107312
  let callee = call.callee;
107080
107313
  if (callee.type === "CallExpression")
@@ -107567,12 +107800,12 @@ function checkConstantsOnly(ctx, emit) {
107567
107800
  }
107568
107801
  function checkOverMocking(ctx, emit) {
107569
107802
  const { program } = ctx.parsed;
107570
- const unit = path74.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
107803
+ const unit = path76.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
107571
107804
  const mocked = find2(program, (node) => node.type === "CallExpression" && MODULE_MOCK.test(calleeName(node.callee) ?? "") && node.arguments[0]?.type === "StringLiteral");
107572
107805
  const internal = mocked.filter((call) => /^(?:\.|@\/|~\/)/.test(call.arguments[0].value));
107573
107806
  for (const call of mocked) {
107574
107807
  const spec = call.arguments[0].value;
107575
- const base = path74.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
107808
+ const base = path76.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
107576
107809
  if (base === unit)
107577
107810
  emit({
107578
107811
  rule: "over-mocking",
@@ -107961,8 +108194,8 @@ var init_rules = __esm(() => {
107961
108194
 
107962
108195
  // packages/workit-cli/src/test-audit/audit.ts
107963
108196
  import { spawnSync as spawnSync30 } from "node:child_process";
107964
- import { existsSync as existsSync28, readdirSync as readdirSync14, readFileSync as readFileSync31, statSync as statSync10 } from "node:fs";
107965
- import path75 from "node:path";
108197
+ import { existsSync as existsSync29, readdirSync as readdirSync14, readFileSync as readFileSync32, statSync as statSync10 } from "node:fs";
108198
+ import path77 from "node:path";
107966
108199
  function git7(cwd, args) {
107967
108200
  const run = spawnSync30("git", ["-c", "core.quotepath=off", ...args], {
107968
108201
  cwd,
@@ -107975,7 +108208,7 @@ function walkTests(dir, out) {
107975
108208
  for (const entry of readdirSync14(dir, { withFileTypes: true })) {
107976
108209
  if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
107977
108210
  continue;
107978
- const full = path75.join(dir, entry.name);
108211
+ const full = path77.join(dir, entry.name);
107979
108212
  if (entry.isDirectory()) {
107980
108213
  if (!SKIP_DIRS.has(entry.name))
107981
108214
  walkTests(full, out);
@@ -107987,8 +108220,8 @@ function expandPaths(cwd, inputs) {
107987
108220
  const files = [];
107988
108221
  const missing = [];
107989
108222
  for (const input of inputs.length > 0 ? inputs : ["."]) {
107990
- const full = path75.resolve(cwd, input);
107991
- if (!existsSync28(full))
108223
+ const full = path77.resolve(cwd, input);
108224
+ if (!existsSync29(full))
107992
108225
  missing.push(input);
107993
108226
  else if (statSync10(full).isDirectory())
107994
108227
  walkTests(full, files);
@@ -108024,11 +108257,11 @@ function changedLines(cwd, base) {
108024
108257
  for (let offset = 0;offset < count; offset += 1)
108025
108258
  lines.add(start + offset);
108026
108259
  }
108027
- changed.set(path75.join(root, file), lines);
108260
+ changed.set(path77.join(root, file), lines);
108028
108261
  }
108029
108262
  const untracked = git7(root, ["ls-files", "--others", "--exclude-standard", "-z"]);
108030
108263
  for (const file of untracked.stdout.split("\x00").filter(Boolean))
108031
- changed.set(path75.join(root, file), "all");
108264
+ changed.set(path77.join(root, file), "all");
108032
108265
  return changed;
108033
108266
  }
108034
108267
  function auditFiles(files, display) {
@@ -108041,7 +108274,7 @@ function auditFiles(files, display) {
108041
108274
  const shown = display(file);
108042
108275
  let parsed;
108043
108276
  try {
108044
- parsed = parseSource(readFileSync31(file, "utf8"), file);
108277
+ parsed = parseSource(readFileSync32(file, "utf8"), file);
108045
108278
  } catch (error) {
108046
108279
  parseErrors.push({
108047
108280
  file: shown,
@@ -108090,7 +108323,7 @@ function auditFiles(files, display) {
108090
108323
  durationMs: Math.round(performance.now() - started)
108091
108324
  };
108092
108325
  }
108093
- var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path75.sep).join("/"), SEVERITY_ORDER, ruleIds;
108326
+ var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path77.sep).join("/"), SEVERITY_ORDER, ruleIds;
108094
108327
  var init_audit = __esm(() => {
108095
108328
  init_ast();
108096
108329
  init_rules();
@@ -108104,23 +108337,23 @@ var init_audit = __esm(() => {
108104
108337
  // packages/workit-cli/src/test-audit/mutate.ts
108105
108338
  import { spawn as spawn5 } from "node:child_process";
108106
108339
  import {
108107
- existsSync as existsSync29,
108340
+ existsSync as existsSync30,
108108
108341
  lstatSync as lstatSync9,
108109
108342
  mkdirSync as mkdirSync13,
108110
- mkdtempSync as mkdtempSync4,
108343
+ mkdtempSync as mkdtempSync6,
108111
108344
  readdirSync as readdirSync15,
108112
- readFileSync as readFileSync32,
108345
+ readFileSync as readFileSync33,
108113
108346
  readlinkSync as readlinkSync3,
108114
108347
  realpathSync as realpathSync11,
108115
108348
  renameSync as renameSync8,
108116
- rmSync as rmSync9,
108349
+ rmSync as rmSync11,
108117
108350
  statSync as statSync11,
108118
108351
  symlinkSync,
108119
- writeFileSync as writeFileSync14,
108352
+ writeFileSync as writeFileSync15,
108120
108353
  copyFileSync as copyFileSync8
108121
108354
  } from "node:fs";
108122
- import os24 from "node:os";
108123
- import path76 from "node:path";
108355
+ import os26 from "node:os";
108356
+ import path78 from "node:path";
108124
108357
  function mutantsFor(source, file, lines) {
108125
108358
  const parsed = parseSource(source, file);
108126
108359
  const out = [];
@@ -108193,7 +108426,7 @@ function relatedTests(source, testFiles) {
108193
108426
  for (const match of text.matchAll(SPECIFIER)) {
108194
108427
  const spec = match[1];
108195
108428
  if (spec.startsWith(".")) {
108196
- if (stripExt(path76.posix.join(path76.posix.dirname(file), spec)) === target)
108429
+ if (stripExt(path78.posix.join(path78.posix.dirname(file), spec)) === target)
108197
108430
  return true;
108198
108431
  } else if (spec.includes("/") && stripExt(spec).split("/").slice(-2).join("/") === tail)
108199
108432
  return true;
@@ -108201,7 +108434,7 @@ function relatedTests(source, testFiles) {
108201
108434
  return false;
108202
108435
  }).map((entry) => entry.file);
108203
108436
  }
108204
- function removeStaleCopies(tmp = os24.tmpdir()) {
108437
+ function removeStaleCopies(tmp = os26.tmpdir()) {
108205
108438
  let removed = 0;
108206
108439
  let names = [];
108207
108440
  try {
@@ -108213,12 +108446,12 @@ function removeStaleCopies(tmp = os24.tmpdir()) {
108213
108446
  for (const name of names) {
108214
108447
  if (!name.startsWith(TEMP_PREFIX))
108215
108448
  continue;
108216
- const dir = path76.join(tmp, name);
108449
+ const dir = path78.join(tmp, name);
108217
108450
  try {
108218
108451
  const stat = lstatSync9(dir);
108219
108452
  if (!stat.isDirectory() || uid !== undefined && stat.uid !== uid)
108220
108453
  continue;
108221
- const pid = Number(readFileSync32(path76.join(dir, PID_FILE), "utf8"));
108454
+ const pid = Number(readFileSync33(path78.join(dir, PID_FILE), "utf8"));
108222
108455
  if (Number.isInteger(pid) && pid > 0 && alive(pid))
108223
108456
  continue;
108224
108457
  } catch (error) {
@@ -108226,7 +108459,7 @@ function removeStaleCopies(tmp = os24.tmpdir()) {
108226
108459
  continue;
108227
108460
  }
108228
108461
  try {
108229
- rmSync9(dir, { recursive: true, force: true });
108462
+ rmSync11(dir, { recursive: true, force: true });
108230
108463
  removed += 1;
108231
108464
  } catch {}
108232
108465
  }
@@ -108235,8 +108468,8 @@ function removeStaleCopies(tmp = os24.tmpdir()) {
108235
108468
  function linkNodeModules(origin, target, repo, copy) {
108236
108469
  mkdirSync13(target, { recursive: true });
108237
108470
  for (const entry of readdirSync15(origin, { withFileTypes: true })) {
108238
- const from = path76.join(origin, entry.name);
108239
- const to = path76.join(target, entry.name);
108471
+ const from = path78.join(origin, entry.name);
108472
+ const to = path78.join(target, entry.name);
108240
108473
  if (entry.name.startsWith("@") && entry.isDirectory()) {
108241
108474
  linkNodeModules(from, to, repo, copy);
108242
108475
  continue;
@@ -108252,9 +108485,9 @@ function linkNodeModules(origin, target, repo, copy) {
108252
108485
  } catch {
108253
108486
  continue;
108254
108487
  }
108255
- const relative = path76.relative(repo, real);
108256
- if (!relative.startsWith("..") && !path76.isAbsolute(relative) && !relative.split(path76.sep).includes("node_modules")) {
108257
- symlinkSync(path76.join(copy, relative), to, "junction");
108488
+ const relative = path78.relative(repo, real);
108489
+ if (!relative.startsWith("..") && !path78.isAbsolute(relative) && !relative.split(path78.sep).includes("node_modules")) {
108490
+ symlinkSync(path78.join(copy, relative), to, "junction");
108258
108491
  continue;
108259
108492
  }
108260
108493
  }
@@ -108270,7 +108503,7 @@ function copySymlink(repo, tree, from, to) {
108270
108503
  }
108271
108504
  const realRepo = realpathSync11(repo);
108272
108505
  if (real && inside5(realRepo, real)) {
108273
- symlinkSync(path76.relative(path76.dirname(to), path76.join(tree, path76.relative(realRepo, real))), to);
108506
+ symlinkSync(path78.relative(path78.dirname(to), path78.join(tree, path78.relative(realRepo, real))), to);
108274
108507
  return;
108275
108508
  }
108276
108509
  if (real && statSync11(real).isFile())
@@ -108279,23 +108512,23 @@ function copySymlink(repo, tree, from, to) {
108279
108512
  symlinkSync(readlinkSync3(from), to);
108280
108513
  }
108281
108514
  function writeInside(copy, file, content) {
108282
- const target = path76.join(copy, file);
108515
+ const target = path78.join(copy, file);
108283
108516
  try {
108284
108517
  const stat = lstatSync9(target);
108285
- if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(path76.dirname(target))))
108518
+ if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(path78.dirname(target))))
108286
108519
  return false;
108287
108520
  } catch {
108288
108521
  return false;
108289
108522
  }
108290
108523
  const temp = `${target}.workit-mutant-${process.pid}`;
108291
- writeFileSync14(temp, content);
108524
+ writeFileSync15(temp, content);
108292
108525
  renameSync8(temp, target);
108293
108526
  return true;
108294
108527
  }
108295
108528
  function copyWorkingTree(repo) {
108296
- const dir = mkdtempSync4(path76.join(os24.tmpdir(), TEMP_PREFIX));
108297
- writeFileSync14(path76.join(dir, PID_FILE), String(process.pid));
108298
- const tree = path76.join(dir, "tree");
108529
+ const dir = mkdtempSync6(path78.join(os26.tmpdir(), TEMP_PREFIX));
108530
+ writeFileSync15(path78.join(dir, PID_FILE), String(process.pid));
108531
+ const tree = path78.join(dir, "tree");
108299
108532
  const head = git7(repo, ["rev-parse", "--verify", "--quiet", "HEAD"]).stdout.trim();
108300
108533
  if (head && git7(dir, ["clone", "-q", "--shared", "--no-checkout", repo, tree]).ok) {
108301
108534
  const branch = git7(repo, ["symbolic-ref", "--quiet", "--short", "HEAD"]).stdout.trim();
@@ -108312,29 +108545,29 @@ function copyWorkingTree(repo) {
108312
108545
  for (const relative of listed) {
108313
108546
  if (!relative)
108314
108547
  continue;
108315
- const from = path76.join(repo, relative);
108548
+ const from = path78.join(repo, relative);
108316
108549
  let stat;
108317
108550
  try {
108318
108551
  stat = lstatSync9(from);
108319
108552
  } catch {
108320
108553
  continue;
108321
108554
  }
108322
- const to = path76.join(tree, relative);
108323
- mkdirSync13(path76.dirname(to), { recursive: true });
108555
+ const to = path78.join(tree, relative);
108556
+ mkdirSync13(path78.dirname(to), { recursive: true });
108324
108557
  if (stat.isSymbolicLink())
108325
108558
  copySymlink(repo, tree, from, to);
108326
108559
  else if (stat.isFile())
108327
108560
  copyFileSync8(from, to);
108328
- let parent = path76.dirname(relative);
108561
+ let parent = path78.dirname(relative);
108329
108562
  while (parent !== "." && !dirs.has(parent)) {
108330
108563
  dirs.add(parent);
108331
- parent = path76.dirname(parent);
108564
+ parent = path78.dirname(parent);
108332
108565
  }
108333
108566
  }
108334
108567
  for (const parent of dirs) {
108335
- const modules = path76.join(repo, parent, "node_modules");
108336
- if (existsSync29(modules) && !existsSync29(path76.join(tree, parent, "node_modules")))
108337
- linkNodeModules(modules, path76.join(tree, parent, "node_modules"), repo, tree);
108568
+ const modules = path78.join(repo, parent, "node_modules");
108569
+ if (existsSync30(modules) && !existsSync30(path78.join(tree, parent, "node_modules")))
108570
+ linkNodeModules(modules, path78.join(tree, parent, "node_modules"), repo, tree);
108338
108571
  }
108339
108572
  return { dir, tree };
108340
108573
  }
@@ -108373,20 +108606,20 @@ async function runMutation(options) {
108373
108606
  const tracked = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00").filter(Boolean);
108374
108607
  const testFiles = tracked.filter((file) => TEST_FILE.test(file)).map((file) => {
108375
108608
  try {
108376
- return { file, text: readFileSync32(path76.join(repo, file), "utf8") };
108609
+ return { file, text: readFileSync33(path78.join(repo, file), "utf8") };
108377
108610
  } catch {
108378
108611
  return { file, text: "" };
108379
108612
  }
108380
108613
  });
108381
108614
  const candidates = [];
108382
108615
  for (const [absolute, lines] of [...options.changed].toSorted(([a], [b]) => a.localeCompare(b))) {
108383
- const relative = toPosix(path76.relative(repo, absolute));
108616
+ const relative = toPosix(path78.relative(repo, absolute));
108384
108617
  if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
108385
108618
  continue;
108386
- if (NOT_SOURCE.test(relative) || !existsSync29(absolute))
108619
+ if (NOT_SOURCE.test(relative) || !existsSync30(absolute))
108387
108620
  continue;
108388
108621
  try {
108389
- candidates.push(...mutantsFor(readFileSync32(absolute, "utf8"), relative, lines));
108622
+ candidates.push(...mutantsFor(readFileSync33(absolute, "utf8"), relative, lines));
108390
108623
  } catch {}
108391
108624
  }
108392
108625
  const mutants = candidates.map((mutant, index) => ({ ...mutant, id: index + 1 }));
@@ -108394,9 +108627,9 @@ async function runMutation(options) {
108394
108627
  for (const mutant of mutants)
108395
108628
  if (!related.has(mutant.file))
108396
108629
  related.set(mutant.file, relatedTests(mutant.file, testFiles));
108397
- const cwdRelative = path76.relative(repo, options.cwd);
108630
+ const cwdRelative = path78.relative(repo, options.cwd);
108398
108631
  const asArg = (file) => {
108399
- const relative = toPosix(path76.relative(cwdRelative, file));
108632
+ const relative = toPosix(path78.relative(cwdRelative, file));
108400
108633
  return shellQuote(relative.startsWith(".") ? relative : `./${relative}`);
108401
108634
  };
108402
108635
  const commandFor = (tests) => options.command.replaceAll("{files}", () => tests.map(asArg).join(" "));
@@ -108432,7 +108665,7 @@ async function runMutation(options) {
108432
108665
  return finish3(options, 0, results, counts, started);
108433
108666
  removeStaleCopies();
108434
108667
  const { dir: copyDir, tree: copy } = copyWorkingTree(repo);
108435
- const copyCwd = path76.join(copy, cwdRelative);
108668
+ const copyCwd = path78.join(copy, cwdRelative);
108436
108669
  let current = null;
108437
108670
  const restore = () => {
108438
108671
  if (current)
@@ -108443,7 +108676,7 @@ async function runMutation(options) {
108443
108676
  for (const child of active)
108444
108677
  killTree(child);
108445
108678
  restore();
108446
- rmSync9(copyDir, { recursive: true, force: true });
108679
+ rmSync11(copyDir, { recursive: true, force: true });
108447
108680
  };
108448
108681
  const onSignal = (signal) => {
108449
108682
  cleanup();
@@ -108467,7 +108700,7 @@ async function runMutation(options) {
108467
108700
  record({ ...mutant, status: "skipped", durationMs: 0, tests, reason: "budget" });
108468
108701
  continue;
108469
108702
  }
108470
- const original = readFileSync32(path76.join(copy, mutant.file), "utf8");
108703
+ const original = readFileSync33(path78.join(copy, mutant.file), "utf8");
108471
108704
  const mutated = original.slice(0, mutant.start) + mutant.replacement + original.slice(mutant.end);
108472
108705
  current = { file: mutant.file, original };
108473
108706
  if (!writeInside(copy, mutant.file, mutated)) {
@@ -108524,8 +108757,8 @@ var NOT_SOURCE, FLIPS, isStringy = (node) => node.type === "StringLiteral" || no
108524
108757
  return error.code === "EPERM";
108525
108758
  }
108526
108759
  }, inside5 = (root, file) => {
108527
- const relative = path76.relative(root, file);
108528
- return relative === "" || !relative.startsWith("..") && !path76.isAbsolute(relative);
108760
+ const relative = path78.relative(root, file);
108761
+ return relative === "" || !relative.startsWith("..") && !path78.isAbsolute(relative);
108529
108762
  }, active, killTree = (child) => {
108530
108763
  try {
108531
108764
  if (child.pid && process.platform !== "win32")
@@ -108573,8 +108806,8 @@ var exports_test_audit = {};
108573
108806
  __export(exports_test_audit, {
108574
108807
  run: () => run23
108575
108808
  });
108576
- import { existsSync as existsSync30 } from "node:fs";
108577
- import path77 from "node:path";
108809
+ import { existsSync as existsSync31 } from "node:fs";
108810
+ import path79 from "node:path";
108578
108811
  function parse8(argv) {
108579
108812
  const options = {
108580
108813
  paths: [],
@@ -108679,8 +108912,8 @@ async function run23(argv, io) {
108679
108912
  return emit(io, fail2("invalid_input", `${options}
108680
108913
  usage: ${USAGE16}`));
108681
108914
  const top = git7(io.cwd, ["rev-parse", "--show-toplevel"]);
108682
- const repo = top.ok ? path77.resolve(top.stdout.trim()) : null;
108683
- const display = (file) => toPosix(path77.relative(io.cwd, file) || file);
108915
+ const repo = top.ok ? path79.resolve(top.stdout.trim()) : null;
108916
+ const display = (file) => toPosix(path79.relative(io.cwd, file) || file);
108684
108917
  let base = null;
108685
108918
  let changed = null;
108686
108919
  if (options.diff || options.mutate) {
@@ -108697,7 +108930,7 @@ usage: ${USAGE16}`));
108697
108930
  }
108698
108931
  let files;
108699
108932
  if (options.diff && changed)
108700
- files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) && existsSync30(file)).toSorted();
108933
+ files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) && existsSync31(file)).toSorted();
108701
108934
  else {
108702
108935
  const expanded = expandPaths(io.cwd, options.paths);
108703
108936
  if (expanded.missing.length > 0)
@@ -108818,8 +109051,8 @@ var exports_youtrack = {};
108818
109051
  __export(exports_youtrack, {
108819
109052
  run: () => run25
108820
109053
  });
108821
- import { readFileSync as readFileSync33 } from "node:fs";
108822
- import path78 from "node:path";
109054
+ import { readFileSync as readFileSync34 } from "node:fs";
109055
+ import path80 from "node:path";
108823
109056
  async function run25(argv, io) {
108824
109057
  const [sub, ...rest] = argv;
108825
109058
  if (sub !== "note" && sub !== "time" && sub !== "meeting")
@@ -108865,7 +109098,7 @@ async function run25(argv, io) {
108865
109098
  let markdown = flags.values.markdown ?? "";
108866
109099
  if (flags.values.file)
108867
109100
  try {
108868
- markdown = readFileSync33(path78.resolve(io.cwd, flags.values.file), "utf8");
109101
+ markdown = readFileSync34(path80.resolve(io.cwd, flags.values.file), "utf8");
108869
109102
  } catch (error) {
108870
109103
  return usage4(io, `cannot read ${flags.values.file}: ${String(error)}`, USAGE18);
108871
109104
  }
@@ -108936,8 +109169,8 @@ var exports_changelog = {};
108936
109169
  __export(exports_changelog, {
108937
109170
  run: () => run26
108938
109171
  });
108939
- import { readFileSync as readFileSync34 } from "node:fs";
108940
- import path79 from "node:path";
109172
+ import { readFileSync as readFileSync35 } from "node:fs";
109173
+ import path81 from "node:path";
108941
109174
  async function run26(argv, io) {
108942
109175
  const [sub, ...rest] = argv;
108943
109176
  if (sub !== "apply")
@@ -108983,7 +109216,7 @@ async function run26(argv, io) {
108983
109216
  ]);
108984
109217
  }
108985
109218
  var USAGE19 = "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]", readEntries = (raw, cwd) => {
108986
- const text = raw === "-" ? readFileSync34(0, "utf8") : raw.startsWith("@") ? readFileSync34(path79.resolve(cwd, raw.slice(1)), "utf8") : raw;
109219
+ const text = raw === "-" ? readFileSync35(0, "utf8") : raw.startsWith("@") ? readFileSync35(path81.resolve(cwd, raw.slice(1)), "utf8") : raw;
108987
109220
  return JSON.parse(text);
108988
109221
  };
108989
109222
  var init_changelog2 = __esm(() => {
@@ -108999,7 +109232,7 @@ __export(exports_handoff, {
108999
109232
  run: () => run27
109000
109233
  });
109001
109234
  import fs37 from "node:fs";
109002
- import path80 from "node:path";
109235
+ import path82 from "node:path";
109003
109236
  import { parseArgs as parseArgs2 } from "node:util";
109004
109237
  function render3(brief) {
109005
109238
  const lines = [
@@ -109039,9 +109272,9 @@ function bounded(brief, cwd) {
109039
109272
  let file = null;
109040
109273
  if (store.ok)
109041
109274
  try {
109042
- const dir = path80.join(store.value.root, "handoff");
109275
+ const dir = path82.join(store.value.root, "handoff");
109043
109276
  fs37.mkdirSync(dir, { recursive: true });
109044
- file = path80.join(dir, `${(brief.branch ?? "detached").replaceAll(/[^\w.-]+/gu, "-")}.txt`);
109277
+ file = path82.join(dir, `${(brief.branch ?? "detached").replaceAll(/[^\w.-]+/gu, "-")}.txt`);
109045
109278
  fs37.writeFileSync(file, `${[...body, ...tail].join(`
109046
109279
  `)}
109047
109280
  `, {
@@ -109116,7 +109349,7 @@ var init_handoff = __esm(() => {
109116
109349
  });
109117
109350
 
109118
109351
  // packages/workit-cli/src/main.ts
109119
- import path81 from "node:path";
109352
+ import path83 from "node:path";
109120
109353
 
109121
109354
  // packages/workit-core/src/git/env-redirect.ts
109122
109355
  var GIT_REDIRECT_ENV = [
@@ -110065,7 +110298,7 @@ var defaultIo = (json) => ({
110065
110298
  });
110066
110299
  async function main(argv, overrides = {}, options = {}) {
110067
110300
  const parsed = parseGlobals(argv);
110068
- const cwd = path81.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
110301
+ const cwd = path83.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
110069
110302
  const io = {
110070
110303
  ...defaultIo(parsed.json),
110071
110304
  terminals: {