@brainervirus/workit-cli 8.27.0 → 8.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +326 -155
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -9240,7 +9240,7 @@ var package_default;
9240
9240
  var init_package = __esm(() => {
9241
9241
  package_default = {
9242
9242
  name: "@brainervirus/workit-cli",
9243
- version: "8.27.0",
9243
+ version: "8.28.0",
9244
9244
  private: false,
9245
9245
  description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
9246
9246
  keywords: [
@@ -9278,13 +9278,13 @@ var init_package = __esm(() => {
9278
9278
  },
9279
9279
  dependencies: {
9280
9280
  "@babel/parser": "7.29.9",
9281
- "@brainervirus/workit-cursor": "^8.27.0",
9281
+ "@brainervirus/workit-cursor": "^8.28.0",
9282
9282
  "@inkjs/ui": "2.0.0",
9283
9283
  ink: "7.1.1",
9284
9284
  react: "19.2.8"
9285
9285
  },
9286
9286
  devDependencies: {
9287
- "@brainervirus/workit-core": "^8.27.0"
9287
+ "@brainervirus/workit-core": "^8.28.0"
9288
9288
  },
9289
9289
  engines: {
9290
9290
  node: ">=24"
@@ -65551,6 +65551,21 @@ var MODEL_ROLES, MODEL_TIERS, HOST_KEYS, BUILT_IN_CLAUDE_CODE, isObject9 = (valu
65551
65551
  }
65552
65552
  }
65553
65553
  return issues;
65554
+ }, roleForAgentType = (agentType, prompt) => {
65555
+ switch (agentType) {
65556
+ case "workit:implementer": {
65557
+ const tier = typeof prompt === "string" ? /^[ \t]*TIER:[ \t]*(mundane|standard|hard)\b/im.exec(prompt)?.[1] : undefined;
65558
+ return { role: "implementer", tier: tier?.toLowerCase() ?? "standard" };
65559
+ }
65560
+ case "workit:verifier":
65561
+ return { role: "verifier" };
65562
+ case "workit:reviewer":
65563
+ return { role: "reviewer" };
65564
+ case "Explore":
65565
+ return { role: "explore" };
65566
+ default:
65567
+ return null;
65568
+ }
65554
65569
  };
65555
65570
  var init_role_models = __esm(() => {
65556
65571
  init_workspaces();
@@ -67025,6 +67040,21 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67025
67040
  return null;
67026
67041
  dir = parent;
67027
67042
  }
67043
+ }, listClaudeProcesses = () => {
67044
+ const r = spawnSync16("ps", ["-eo", "pid=,lstart=,args="], { encoding: "utf8", timeout: 5000 });
67045
+ if (r.status !== 0 || typeof r.stdout !== "string")
67046
+ return null;
67047
+ const found = [];
67048
+ for (const row of r.stdout.split(`
67049
+ `)) {
67050
+ const m = /^\s*(\d+)\s+(\w{3}\s+\w{3}\s+\d+\s+[\d:]+\s+\d{4})\s+(.*)$/.exec(row);
67051
+ if (!m || !/^(\S*\/)?claude(\s|$)/.test(m[3]))
67052
+ continue;
67053
+ const startedMs = Date.parse(m[2]);
67054
+ if (Number.isFinite(startedMs))
67055
+ found.push({ pid: Number(m[1]), startedMs, args: m[3] });
67056
+ }
67057
+ return found;
67028
67058
  }, resolve = (options) => {
67029
67059
  const env = options.env ?? process.env;
67030
67060
  const home = options.home ?? env.HOME ?? os12.homedir();
@@ -67052,7 +67082,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
67052
67082
  env,
67053
67083
  installer: options.installer ?? false,
67054
67084
  cliVersion: options.cliVersion ?? null,
67055
- scopeProbe: options.scopeProbe ?? probeScope
67085
+ scopeProbe: options.scopeProbe ?? probeScope,
67086
+ claudeProcesses: options.claudeProcesses ?? listClaudeProcesses
67056
67087
  };
67057
67088
  }, readJson = (p) => {
67058
67089
  try {
@@ -68892,6 +68923,68 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
68892
68923
  fix: repair,
68893
68924
  registryProbed
68894
68925
  };
68926
+ }, checkClaudeSessionPlugin = (res) => {
68927
+ const id = "claude_session_plugin";
68928
+ if (process.platform === "win32")
68929
+ return {
68930
+ id,
68931
+ status: "info",
68932
+ detail: "running Claude Code sessions are not checked on Windows"
68933
+ };
68934
+ const installs = claudeWorkitInstalls(res.home, res.env, res.cwd).filter((install) => install.version);
68935
+ if (installs.length === 0)
68936
+ return {
68937
+ id,
68938
+ status: "info",
68939
+ detail: "no Workit Claude Code plugin install recorded — skipping"
68940
+ };
68941
+ const registry = readJson(path38.join(claudeConfigDir(res.home, res.env), "plugins", "installed_plugins.json"));
68942
+ const recorded = (install) => {
68943
+ const entries = registry?.plugins?.[install.id];
68944
+ const entry = Array.isArray(entries) ? entries.find((e) => e?.installPath === install.installPath) : null;
68945
+ for (const stamp of [entry?.lastUpdated, entry?.installedAt]) {
68946
+ const ms = typeof stamp === "string" ? Date.parse(stamp) : NaN;
68947
+ if (Number.isFinite(ms))
68948
+ return ms;
68949
+ }
68950
+ try {
68951
+ return statSync6(install.installPath).mtimeMs;
68952
+ } catch {
68953
+ return null;
68954
+ }
68955
+ };
68956
+ const latest = installs.map((install) => ({ install, at: recorded(install) })).filter((one) => one.at !== null).toSorted((a, b) => b.at - a.at)[0];
68957
+ if (!latest)
68958
+ return {
68959
+ id,
68960
+ status: "info",
68961
+ detail: "no install time recorded for the Workit plugin — skipping"
68962
+ };
68963
+ const running = res.claudeProcesses();
68964
+ if (running === null)
68965
+ return {
68966
+ id,
68967
+ status: "info",
68968
+ detail: "could not list running claude processes (ps) — skipping"
68969
+ };
68970
+ const stale = running.filter((proc) => proc.startedMs < latest.at);
68971
+ if (stale.length === 0)
68972
+ return {
68973
+ id,
68974
+ status: "info",
68975
+ detail: `${running.length} running claude process(es), none started before Workit ${latest.install.version} was installed`
68976
+ };
68977
+ const sessionOf = (args) => /(?:--resume|--session-id|-r)[ =]([0-9a-f]{8}-[0-9a-f-]{27})/i.exec(args)?.[1] ?? null;
68978
+ const rows = stale.map((proc) => {
68979
+ const session = sessionOf(proc.args);
68980
+ return `pid ${proc.pid} started ${new Date(proc.startedMs).toISOString()}${session ? ` (session ${session})` : ""}`;
68981
+ });
68982
+ const first = stale.map((proc) => sessionOf(proc.args)).find((one) => one);
68983
+ return {
68984
+ id,
68985
+ status: "warn",
68986
+ detail: `started before Workit ${latest.install.version} was installed: ${rows.join("; ")}; quit and start \`claude --resume ${first ?? "<session id>"}\` to load it (\`/resume\` keeps the old plugin)`
68987
+ };
68895
68988
  }, HOOK_ISSUED_MARKER = "workit-issued-sessions/3", hookRecordsIssued = (root) => {
68896
68989
  let files;
68897
68990
  try {
@@ -69093,6 +69186,7 @@ var init_doctor = __esm(() => {
69093
69186
  checkPiExtension,
69094
69187
  checkOpencodeVersion,
69095
69188
  checkClaudePlugin,
69189
+ checkClaudeSessionPlugin,
69096
69190
  checkHookIssuedSessions,
69097
69191
  checkWorkitOnPath,
69098
69192
  checkAssets,
@@ -77403,6 +77497,9 @@ var exports_models = {};
77403
77497
  __export(exports_models, {
77404
77498
  run: () => run13
77405
77499
  });
77500
+ import { existsSync as existsSync21, readdirSync as readdirSync10, readFileSync as readFileSync21, statSync as statSync9 } from "node:fs";
77501
+ import os21 from "node:os";
77502
+ import path51 from "node:path";
77406
77503
  async function run13(argv, io) {
77407
77504
  const [sub, ...args] = argv.filter((arg) => arg !== "--json");
77408
77505
  if (sub !== "show")
@@ -77410,13 +77507,27 @@ async function run13(argv, io) {
77410
77507
  const role = flag3(args, "--role");
77411
77508
  const tier = flag3(args, "--tier");
77412
77509
  const hostFlag = flag3(args, "--host");
77413
- for (const value of [role, tier, hostFlag])
77510
+ const daysFlag = flag3(args, "--days");
77511
+ for (const value of [role, tier, hostFlag, daysFlag])
77414
77512
  if (value instanceof Error)
77415
77513
  return emit(io, fail2("invalid_input", value.message));
77416
77514
  if (role && !MODEL_ROLES.includes(role))
77417
77515
  return emit(io, fail2("invalid_input", `unknown role ${role}: ${MODEL_ROLES.join(", ")}`));
77418
77516
  if (tier && !MODEL_TIERS.includes(tier))
77419
77517
  return emit(io, fail2("invalid_input", `unknown tier ${tier}: ${MODEL_TIERS.join(", ")}`));
77518
+ const days = daysFlag === null ? 7 : Number(daysFlag);
77519
+ if (!Number.isFinite(days) || days <= 0)
77520
+ return emit(io, fail2("invalid_input", "--days needs a positive number"));
77521
+ if (args.includes("--report")) {
77522
+ const report = usageReport(io.cwd, io.env, days);
77523
+ return emit(io, ok2(report), (data) => [
77524
+ `subagent models over the last ${data.days} days (${data.agents} agents)`,
77525
+ ...Object.entries(data.types).flatMap(([type, use]) => [
77526
+ ` ${type}${use.role ? ` (role ${use.role}, default ${use.defaults.join("/") || "host default"})` : ""}: ${Object.entries(use.models).map(([model, count]) => `${model} x${count}`).join(", ")}`,
77527
+ ...use.flagged.map((model) => ` flag: ran on ${model}, not the role default`)
77528
+ ])
77529
+ ]);
77530
+ }
77420
77531
  const envHost = actorFromEnv(io.env).host;
77421
77532
  const host = hostFlag ?? (envHost === "cli" ? "claude_code" : envHost);
77422
77533
  const row = (selector) => resolveRoleModel(io.cwd, selector, host) ?? { model: null, effort: null, source: "none" };
@@ -77439,13 +77550,73 @@ async function run13(argv, io) {
77439
77550
  ...(data.issues ?? []).map((issue) => `note: ${issue}`)
77440
77551
  ]);
77441
77552
  }
77442
- var USAGE6 = "workit models show [--role <role>] [--tier <tier>] [--host <host>] [--json]", flag3 = (argv, name) => {
77553
+ var USAGE6 = "workit models show [--role <role>] [--tier <tier>] [--host <host>] [--report [--days <n>]] [--json]", flag3 = (argv, name) => {
77443
77554
  const at = argv.findIndex((arg) => arg === name || arg.startsWith(`${name}=`));
77444
77555
  if (at < 0)
77445
77556
  return null;
77446
77557
  const value = argv[at].includes("=") ? argv[at].slice(name.length + 1) : argv[at + 1];
77447
77558
  return value && !value.startsWith("--") ? value : new Error(`${name} needs a value`);
77448
- }, line2 = (label, entry) => ` ${label}: ${entry.model ? `${entry.model}${entry.effort ? ` (effort ${entry.effort})` : ""} [${entry.source}]` : "host default (nothing configured)"}`;
77559
+ }, line2 = (label, entry) => ` ${label}: ${entry.model ? `${entry.model}${entry.effort ? ` (effort ${entry.effort})` : ""} [${entry.source}]` : "host default (nothing configured)"}`, modelsOf = (file) => {
77560
+ const found = new Set;
77561
+ let text = "";
77562
+ try {
77563
+ text = readFileSync21(file, "utf8");
77564
+ } catch {
77565
+ return found;
77566
+ }
77567
+ for (const row of text.split(`
77568
+ `))
77569
+ if (row.includes('"type":"assistant"'))
77570
+ try {
77571
+ const model = JSON.parse(row).message?.model;
77572
+ if (typeof model === "string" && model && !model.startsWith("<"))
77573
+ found.add(model);
77574
+ } catch {}
77575
+ return found;
77576
+ }, matches3 = (ran, configured) => ran.toLowerCase().includes(configured.toLowerCase()), usageReport = (cwd, env, days) => {
77577
+ const projects = path51.join(env.CLAUDE_CONFIG_DIR || path51.join(env.HOME || os21.homedir(), ".claude"), "projects");
77578
+ const since = Date.now() - days * 86400000;
77579
+ const types = {};
77580
+ let agents = 0;
77581
+ const dirs = (dir) => {
77582
+ try {
77583
+ return readdirSync10(dir).map((name) => path51.join(dir, name));
77584
+ } catch {
77585
+ return [];
77586
+ }
77587
+ };
77588
+ for (const project of dirs(projects))
77589
+ for (const session of dirs(project))
77590
+ for (const meta of dirs(path51.join(session, "subagents")).filter((f) => f.endsWith(".meta.json"))) {
77591
+ try {
77592
+ if (statSync9(meta).mtimeMs < since)
77593
+ continue;
77594
+ const agentType = JSON.parse(readFileSync21(meta, "utf8")).agentType;
77595
+ const transcript = meta.replace(/\.meta\.json$/, ".jsonl");
77596
+ if (typeof agentType !== "string" || !existsSync21(transcript))
77597
+ continue;
77598
+ const ran = modelsOf(transcript);
77599
+ if (!ran.size)
77600
+ continue;
77601
+ agents += 1;
77602
+ const selector = roleForAgentType(agentType);
77603
+ const entry = types[agentType] ??= {
77604
+ role: selector?.role ?? null,
77605
+ defaults: selector ? [
77606
+ ...new Set((selector.role === "implementer" ? MODEL_TIERS.map((tier) => ({ ...selector, tier })) : [selector]).flatMap((one) => resolveRoleModel(cwd, one, "claude_code")?.model ?? []))
77607
+ ] : [],
77608
+ models: {},
77609
+ flagged: []
77610
+ };
77611
+ for (const model of ran) {
77612
+ entry.models[model] = (entry.models[model] ?? 0) + 1;
77613
+ if (entry.models[model] === 1 && entry.defaults.length && !entry.defaults.some((d) => matches3(model, d)))
77614
+ entry.flagged.push(model);
77615
+ }
77616
+ } catch {}
77617
+ }
77618
+ return { days, agents, types };
77619
+ };
77449
77620
  var init_models = __esm(() => {
77450
77621
  init_role_models();
77451
77622
  init_ledger();
@@ -77561,8 +77732,8 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
77561
77732
 
77562
77733
  // packages/workit-core/src/git/ops.ts
77563
77734
  import { spawnSync as spawnSync20 } from "node:child_process";
77564
- import { existsSync as existsSync21, readFileSync as readFileSync21 } from "node:fs";
77565
- import path51 from "node:path";
77735
+ import { existsSync as existsSync22, readFileSync as readFileSync22 } from "node:fs";
77736
+ import path52 from "node:path";
77566
77737
  function operationInProgress(cwd) {
77567
77738
  const markers = [
77568
77739
  ["rebase-merge", "rebase"],
@@ -77575,18 +77746,18 @@ function operationInProgress(cwd) {
77575
77746
  if (!run.ok)
77576
77747
  return null;
77577
77748
  const found = run.stdout.split(`
77578
- `).map((line) => path51.resolve(cwd, line.trim()));
77749
+ `).map((line) => path52.resolve(cwd, line.trim()));
77579
77750
  const conflicted = () => git5(cwd, ["ls-files", "-u"]).stdout.trim() !== "";
77580
77751
  for (const [index, [, operation]] of markers.entries()) {
77581
77752
  const marker = found[index];
77582
- if (!marker || !existsSync21(marker))
77753
+ if (!marker || !existsSync22(marker))
77583
77754
  continue;
77584
- if (index === 1 && existsSync21(path51.join(marker, "applying")))
77755
+ if (index === 1 && existsSync22(path52.join(marker, "applying")))
77585
77756
  return { operation: "am", commitAllowed: false, branch: null };
77586
- if (index === 0 && existsSync21(path51.join(marker, "amend")) && !conflicted()) {
77757
+ if (index === 0 && existsSync22(path52.join(marker, "amend")) && !conflicted()) {
77587
77758
  let headName = "";
77588
77759
  try {
77589
- headName = readFileSync21(path51.join(marker, "head-name"), "utf8").trim();
77760
+ headName = readFileSync22(path52.join(marker, "head-name"), "utf8").trim();
77590
77761
  } catch {}
77591
77762
  const branch = headName.startsWith("refs/heads/") ? headName.slice("refs/heads/".length) : null;
77592
77763
  return { operation, commitAllowed: branch !== null, branch };
@@ -77914,7 +78085,7 @@ function gitCommit(cwd, input) {
77914
78085
  if (paths.some((value) => value.startsWith("-") || !value.trim()))
77915
78086
  return failure3("invalid_input", "paths must not be empty or start with -");
77916
78087
  const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
77917
- const addable = paths.filter((value) => existsSync21(path51.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
78088
+ const addable = paths.filter((value) => existsSync22(path52.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
77918
78089
  if (addable.length) {
77919
78090
  const added = git5(cwd, ["add", "-A", "--", ...addable]);
77920
78091
  if (!added.ok)
@@ -78441,12 +78612,12 @@ var init_ops = __esm(() => {
78441
78612
 
78442
78613
  // packages/workit-core/src/verdict-cover.ts
78443
78614
  import fs26 from "node:fs";
78444
- import path52 from "node:path";
78615
+ import path53 from "node:path";
78445
78616
  function chainsAbove(cwd, branch) {
78446
78617
  const root = storeRoot(cwd);
78447
78618
  if (!root.ok)
78448
78619
  return [];
78449
- const dir = path52.join(root.value.root, "stacks");
78620
+ const dir = path53.join(root.value.root, "stacks");
78450
78621
  let names = [];
78451
78622
  try {
78452
78623
  names = fs26.readdirSync(dir).filter((name) => name.endsWith(".json"));
@@ -78457,7 +78628,7 @@ function chainsAbove(cwd, branch) {
78457
78628
  for (const name of names.toSorted()) {
78458
78629
  let parsed;
78459
78630
  try {
78460
- parsed = JSON.parse(fs26.readFileSync(path52.join(dir, name), "utf8"));
78631
+ parsed = JSON.parse(fs26.readFileSync(path53.join(dir, name), "utf8"));
78461
78632
  } catch {
78462
78633
  continue;
78463
78634
  }
@@ -78552,10 +78723,10 @@ var init_pr_lane = __esm(() => {
78552
78723
 
78553
78724
  // packages/workit-core/src/forge/reruns.ts
78554
78725
  import fs27 from "node:fs";
78555
- import path53 from "node:path";
78726
+ import path54 from "node:path";
78556
78727
  function rerunLogPath(cwd) {
78557
78728
  const common = gitCommonDir(cwd);
78558
- return common ? path53.join(common, "workit", "ci-reruns.jsonl") : null;
78729
+ return common ? path54.join(common, "workit", "ci-reruns.jsonl") : null;
78559
78730
  }
78560
78731
  function rerunCounts(cwd, key) {
78561
78732
  const counts = new Map;
@@ -78590,7 +78761,7 @@ function recordReruns(cwd, rows) {
78590
78761
  if (!file)
78591
78762
  return false;
78592
78763
  try {
78593
- fs27.mkdirSync(path53.dirname(file), { recursive: true });
78764
+ fs27.mkdirSync(path54.dirname(file), { recursive: true });
78594
78765
  fs27.appendFileSync(file, rows.map((row) => `${JSON.stringify(row)}
78595
78766
  `).join(""));
78596
78767
  return true;
@@ -78603,7 +78774,7 @@ function withRerunLock(cwd, fn) {
78603
78774
  if (!file)
78604
78775
  return fn();
78605
78776
  const lock = `${file.slice(0, -".jsonl".length)}.lock`;
78606
- fs27.mkdirSync(path53.dirname(lock), { recursive: true });
78777
+ fs27.mkdirSync(path54.dirname(lock), { recursive: true });
78607
78778
  const until = Date.now() + LOCK_WAIT_MS2;
78608
78779
  for (;; ) {
78609
78780
  try {
@@ -79518,7 +79689,7 @@ var init_pr_ops = __esm(() => {
79518
79689
  import { spawnSync as spawnSync22 } from "node:child_process";
79519
79690
  import { createHash as createHash17, randomBytes as randomBytes4 } from "node:crypto";
79520
79691
  import fs28 from "node:fs";
79521
- import path54 from "node:path";
79692
+ import path55 from "node:path";
79522
79693
  function worktreeOf(cwd, branch) {
79523
79694
  const list = gitRun3(cwd, ["worktree", "list", "--porcelain"]);
79524
79695
  if (!list.ok)
@@ -79562,7 +79733,7 @@ function gitRestack(cwd, input) {
79562
79733
  if (!scratch)
79563
79734
  return { ok: false, conflict: false, worktree: cwd, error: "no store root" };
79564
79735
  fs28.mkdirSync(scratch, { recursive: true });
79565
- dir = path54.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
79736
+ dir = path55.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
79566
79737
  const added = gitRun3(cwd, ["worktree", "add", "-q", dir, input.branch], GIT_TIMEOUTS.worktree);
79567
79738
  if (!added.ok)
79568
79739
  return { ok: false, conflict: false, worktree: cwd, error: firstLine(added) };
@@ -79603,7 +79774,7 @@ function pruneScratch(cwd) {
79603
79774
  if (!scratch || !fs28.existsSync(scratch))
79604
79775
  return;
79605
79776
  for (const name of fs28.readdirSync(scratch)) {
79606
- const dir = path54.join(scratch, name);
79777
+ const dir = path55.join(scratch, name);
79607
79778
  if (!rebaseInProgress(dir) && !trackedDirt(dir))
79608
79779
  gitRun3(cwd, ["worktree", "remove", "--force", dir]);
79609
79780
  }
@@ -79613,7 +79784,7 @@ function stacksDir(cwd) {
79613
79784
  const root = storeRoot(cwd);
79614
79785
  if (!root.ok)
79615
79786
  return stackFail(root.code, root.error, root.unblock);
79616
- return { ok: true, data: path54.join(root.value.root, "stacks") };
79787
+ return { ok: true, data: path55.join(root.value.root, "stacks") };
79617
79788
  }
79618
79789
  function parseStack(raw) {
79619
79790
  if (!isRecord12(raw) || !Array.isArray(raw.branches))
@@ -79665,7 +79836,7 @@ function readStack(cwd, name) {
79665
79836
  const dir = stacksDir(cwd);
79666
79837
  if (!dir.ok)
79667
79838
  return dir;
79668
- const file = path54.join(dir.data, fileFor(name));
79839
+ const file = path55.join(dir.data, fileFor(name));
79669
79840
  let text;
79670
79841
  try {
79671
79842
  text = fs28.readFileSync(file, "utf8");
@@ -79686,7 +79857,7 @@ function writeStack(cwd, stack, now = new Date) {
79686
79857
  const dir = stacksDir(cwd);
79687
79858
  if (!dir.ok)
79688
79859
  return dir;
79689
- const file = path54.join(dir.data, fileFor(stack.name));
79860
+ const file = path55.join(dir.data, fileFor(stack.name));
79690
79861
  const temp = `${file}.${process.pid}.tmp`;
79691
79862
  try {
79692
79863
  fs28.mkdirSync(dir.data, { recursive: true });
@@ -79714,7 +79885,7 @@ function listStacks(cwd) {
79714
79885
  for (const name of names) {
79715
79886
  let parsed = null;
79716
79887
  try {
79717
- parsed = parseStack(JSON.parse(fs28.readFileSync(path54.join(dir.data, name), "utf8")));
79888
+ parsed = parseStack(JSON.parse(fs28.readFileSync(path55.join(dir.data, name), "utf8")));
79718
79889
  } catch {
79719
79890
  parsed = null;
79720
79891
  }
@@ -79773,7 +79944,7 @@ function takeLock(lock) {
79773
79944
  host: localLockHost(),
79774
79945
  nonce: randomBytes4(8).toString("hex")
79775
79946
  };
79776
- fs28.writeFileSync(path54.join(lock, OWNER), JSON.stringify(owner));
79947
+ fs28.writeFileSync(path55.join(lock, OWNER), JSON.stringify(owner));
79777
79948
  return owner;
79778
79949
  }
79779
79950
  function reapLock(lock, observed) {
@@ -79810,7 +79981,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
79810
79981
  return dir;
79811
79982
  if (!validName(name))
79812
79983
  return stackFail("invalid_input", "a stack name must be 1-200 printable characters");
79813
- const lock = path54.join(dir.data, `${fileFor(name)}.lock`);
79984
+ const lock = path55.join(dir.data, `${fileFor(name)}.lock`);
79814
79985
  try {
79815
79986
  fs28.mkdirSync(dir.data, { recursive: true });
79816
79987
  } catch (error) {
@@ -79840,7 +80011,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
79840
80011
  const touch = () => {
79841
80012
  try {
79842
80013
  const now = new Date;
79843
- fs28.utimesSync(path54.join(lock, OWNER), now, now);
80014
+ fs28.utimesSync(path55.join(lock, OWNER), now, now);
79844
80015
  } catch {}
79845
80016
  };
79846
80017
  const beat = setInterval(touch, HEARTBEAT_MS);
@@ -80691,7 +80862,7 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
80691
80862
  return !status.ok || status.stdout.trim() !== "";
80692
80863
  }, scratchDir = (cwd) => {
80693
80864
  const dir = stacksDir(cwd);
80694
- return dir.ok ? path54.join(dir.data, "worktrees") : null;
80865
+ return dir.ok ? path55.join(dir.data, "worktrees") : null;
80695
80866
  }, firstLine = (run) => (`${run.stderr}
80696
80867
  ${run.stdout}`.split(`
80697
80868
  `).find((line) => line.trim()) ?? "git failed").trim().slice(0, 300), stackFileName = (name) => `${name.replace(/[^A-Za-z0-9._-]+/gu, "_").replace(/^[._]+/u, "").slice(0, 48).toLowerCase()}-${createHash17("sha256").update(name).digest("hex").slice(0, 12)}.json`, fileFor, validName = (name) => {
@@ -80706,12 +80877,12 @@ ${run.stdout}`.split(`
80706
80877
  }, 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) => {
80707
80878
  let raw = null;
80708
80879
  try {
80709
- raw = fs28.readFileSync(path54.join(lock, OWNER), "utf8");
80880
+ raw = fs28.readFileSync(path55.join(lock, OWNER), "utf8");
80710
80881
  } catch {
80711
80882
  raw = null;
80712
80883
  }
80713
80884
  let age = null;
80714
- for (const target of [path54.join(lock, OWNER), lock])
80885
+ for (const target of [path55.join(lock, OWNER), lock])
80715
80886
  try {
80716
80887
  age = Date.now() - fs28.statSync(target).mtimeMs;
80717
80888
  break;
@@ -80754,7 +80925,7 @@ var init_stack = __esm(() => {
80754
80925
  import { spawnSync as spawnSync23 } from "node:child_process";
80755
80926
  import { createHash as createHash18 } from "node:crypto";
80756
80927
  import fs29 from "node:fs";
80757
- import path55 from "node:path";
80928
+ import path56 from "node:path";
80758
80929
  function expandBraces2(pattern, limit = 64) {
80759
80930
  for (let index = 0;index < pattern.length; index += 1) {
80760
80931
  if (pattern[index] === "\\") {
@@ -81000,7 +81171,7 @@ function parsePlan(raw, defaults, name) {
81000
81171
  id,
81001
81172
  branch,
81002
81173
  base: optional("base") ?? "",
81003
- worktree: path55.resolve(defaults.root, optional("worktree") ?? path55.join(defaults.worktreeRoot, id)),
81174
+ worktree: path56.resolve(defaults.root, optional("worktree") ?? path56.join(defaults.worktreeRoot, id)),
81004
81175
  tier,
81005
81176
  reason,
81006
81177
  dependsOn: [...new Set(dependsOn ?? [])],
@@ -81231,11 +81402,11 @@ function defaultTrunk(cwd) {
81231
81402
  }
81232
81403
  function mainCheckout(cwd) {
81233
81404
  const common = gitCommonDir(cwd);
81234
- return common && path55.basename(common) === ".git" ? path55.dirname(common) : path55.resolve(cwd);
81405
+ return common && path56.basename(common) === ".git" ? path56.dirname(common) : path56.resolve(cwd);
81235
81406
  }
81236
81407
  function worktreeRoot(cwd) {
81237
81408
  const main = mainCheckout(cwd);
81238
- return path55.join(path55.dirname(main), `${path55.basename(main)}-wt`);
81409
+ return path56.join(path56.dirname(main), `${path56.basename(main)}-wt`);
81239
81410
  }
81240
81411
  function sliceHash(slice) {
81241
81412
  const {
@@ -81255,7 +81426,7 @@ function fanoutsDir(cwd) {
81255
81426
  const root = storeRoot(cwd);
81256
81427
  if (!root.ok)
81257
81428
  return fanoutFail(root.code, root.error, root.unblock);
81258
- return { ok: true, data: path55.join(root.value.root, "fanouts") };
81429
+ return { ok: true, data: path56.join(root.value.root, "fanouts") };
81259
81430
  }
81260
81431
  function parseStored(raw) {
81261
81432
  if (!isRecord13(raw) || typeof raw.name !== "string" || typeof raw.trunk !== "string")
@@ -81323,7 +81494,7 @@ function readFanout(cwd, name) {
81323
81494
  const dir = fanoutsDir(cwd);
81324
81495
  if (!dir.ok)
81325
81496
  return dir;
81326
- const file = path55.join(dir.data, stackFileName(name));
81497
+ const file = path56.join(dir.data, stackFileName(name));
81327
81498
  let parsed = null;
81328
81499
  try {
81329
81500
  parsed = parseStored(JSON.parse(fs29.readFileSync(file, "utf8")));
@@ -81348,7 +81519,7 @@ function listFanouts(cwd) {
81348
81519
  for (const entry of names) {
81349
81520
  let parsed = null;
81350
81521
  try {
81351
- parsed = parseStored(JSON.parse(fs29.readFileSync(path55.join(dir.data, entry), "utf8")));
81522
+ parsed = parseStored(JSON.parse(fs29.readFileSync(path56.join(dir.data, entry), "utf8")));
81352
81523
  } catch {
81353
81524
  parsed = null;
81354
81525
  }
@@ -81387,7 +81558,7 @@ function writeFanout(cwd, plan) {
81387
81558
  const dir = fanoutsDir(cwd);
81388
81559
  if (!dir.ok)
81389
81560
  return dir;
81390
- const file = path55.join(dir.data, stackFileName(plan.name));
81561
+ const file = path56.join(dir.data, stackFileName(plan.name));
81391
81562
  const temp = `${file}.${process.pid}.tmp`;
81392
81563
  try {
81393
81564
  fs29.mkdirSync(dir.data, { recursive: true });
@@ -81594,13 +81765,13 @@ var init_fanout = __esm(() => {
81594
81765
  // packages/workit-core/src/forge/exec.ts
81595
81766
  import { spawnSync as spawnSync24 } from "node:child_process";
81596
81767
  import fs30 from "node:fs";
81597
- import path56 from "node:path";
81768
+ import path57 from "node:path";
81598
81769
  function findExecutable(bin, env) {
81599
- const dirs = (env.PATH ?? env.Path ?? "").split(path56.delimiter).filter(Boolean);
81770
+ const dirs = (env.PATH ?? env.Path ?? "").split(path57.delimiter).filter(Boolean);
81600
81771
  const exts = process.platform === "win32" ? [".exe"] : [""];
81601
81772
  for (const dir of dirs)
81602
81773
  for (const ext of exts) {
81603
- const candidate = path56.join(dir, `${bin}${ext}`);
81774
+ const candidate = path57.join(dir, `${bin}${ext}`);
81604
81775
  try {
81605
81776
  const stat = fs30.statSync(candidate);
81606
81777
  if (stat.isFile())
@@ -83344,7 +83515,7 @@ var init_duration = __esm(() => {
83344
83515
  });
83345
83516
 
83346
83517
  // packages/workit-cli/src/verbs/forge-common.ts
83347
- import { readFileSync as readFileSync22 } from "node:fs";
83518
+ import { readFileSync as readFileSync23 } from "node:fs";
83348
83519
  function parseFlags(argv, spec) {
83349
83520
  const parsed = { values: {}, booleans: new Set, lists: {}, positionals: [] };
83350
83521
  for (let index = 0;index < argv.length; index += 1) {
@@ -83488,7 +83659,7 @@ var init_forge_common = __esm(() => {
83488
83659
  forgeDeps = {
83489
83660
  runner: undefined,
83490
83661
  npm: undefined,
83491
- readStdin: () => readFileSync22(0, "utf8"),
83662
+ readStdin: () => readFileSync23(0, "utf8"),
83492
83663
  sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
83493
83664
  now: () => Date.now()
83494
83665
  };
@@ -83499,12 +83670,12 @@ var exports_pr = {};
83499
83670
  __export(exports_pr, {
83500
83671
  run: () => run14
83501
83672
  });
83502
- import { readFileSync as readFileSync23 } from "node:fs";
83503
- import path57 from "node:path";
83673
+ import { readFileSync as readFileSync24 } from "node:fs";
83674
+ import path58 from "node:path";
83504
83675
  function readBodyFile(io, file) {
83505
83676
  try {
83506
83677
  return {
83507
- body: file === "-" ? forgeDeps.readStdin() : readFileSync23(path57.resolve(io.cwd, file), "utf8")
83678
+ body: file === "-" ? forgeDeps.readStdin() : readFileSync24(path58.resolve(io.cwd, file), "utf8")
83508
83679
  };
83509
83680
  } catch {
83510
83681
  return `cannot read --body-file ${file}`;
@@ -84209,8 +84380,8 @@ var exports_git = {};
84209
84380
  __export(exports_git, {
84210
84381
  run: () => run16
84211
84382
  });
84212
- import { readFileSync as readFileSync24 } from "node:fs";
84213
- import path58 from "node:path";
84383
+ import { readFileSync as readFileSync25 } from "node:fs";
84384
+ import path59 from "node:path";
84214
84385
  function kindHint(cwd, kind) {
84215
84386
  let kinds = [...BRANCH_KINDS];
84216
84387
  try {
@@ -84314,7 +84485,7 @@ function commitMessage(parsed, io) {
84314
84485
 
84315
84486
  `);
84316
84487
  try {
84317
- return file === "-" ? readFileSync24(0, "utf8") : readFileSync24(path58.resolve(io.cwd, file), "utf8");
84488
+ return file === "-" ? readFileSync25(0, "utf8") : readFileSync25(path59.resolve(io.cwd, file), "utf8");
84318
84489
  } catch (error) {
84319
84490
  return {
84320
84491
  error: `cannot read -F ${file}: ${error instanceof Error ? error.message : String(error)}`
@@ -85735,7 +85906,7 @@ var init_live_session = __esm(() => {
85735
85906
  });
85736
85907
 
85737
85908
  // packages/workit-core/src/hooks/write-gate.ts
85738
- import path59 from "node:path";
85909
+ import path60 from "node:path";
85739
85910
  var CASE_INSENSITIVE, PREFIXES2, SCRIPT_SHELLS, cache3, MUTATING_GIT, DRY_N, MUTATING_WORKIT_GIT, CD2, PUSHD2, POPD2, UNKNOWN_DIR;
85740
85911
  var init_write_gate = __esm(() => {
85741
85912
  init_task_store();
@@ -85775,7 +85946,7 @@ var init_write_gate = __esm(() => {
85775
85946
  CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
85776
85947
  PUSHD2 = new Set(["pushd", "push-location"]);
85777
85948
  POPD2 = new Set(["popd", "pop-location"]);
85778
- UNKNOWN_DIR = path59.resolve(path59.parse(process.cwd()).root, ".workit-unknown-dir");
85949
+ UNKNOWN_DIR = path60.resolve(path60.parse(process.cwd()).root, ".workit-unknown-dir");
85779
85950
  });
85780
85951
 
85781
85952
  // packages/workit-core/src/hooks/worktree-confine.ts
@@ -85800,20 +85971,20 @@ var init_worktree_confine = __esm(() => {
85800
85971
 
85801
85972
  // packages/workit-core/src/worktree-deps.ts
85802
85973
  import fs32 from "node:fs";
85803
- import path60 from "node:path";
85974
+ import path61 from "node:path";
85804
85975
  function moduleDirs(main) {
85805
85976
  const out = [];
85806
85977
  const walk = (relative, depth) => {
85807
85978
  let entries;
85808
85979
  try {
85809
- entries = fs32.readdirSync(path60.join(main, relative), { withFileTypes: true });
85980
+ entries = fs32.readdirSync(path61.join(main, relative), { withFileTypes: true });
85810
85981
  } catch {
85811
85982
  return;
85812
85983
  }
85813
85984
  for (const entry of entries) {
85814
85985
  if (!entry.isDirectory())
85815
85986
  continue;
85816
- const child = path60.join(relative, entry.name);
85987
+ const child = path61.join(relative, entry.name);
85817
85988
  if (entry.name === MODULES)
85818
85989
  out.push(child);
85819
85990
  else if (depth < MAX_DEPTH2 && !entry.name.startsWith("."))
@@ -85827,8 +85998,8 @@ function linkEntry(main, worktree, source, target) {
85827
85998
  const stat = fs32.lstatSync(source);
85828
85999
  if (stat.isSymbolicLink()) {
85829
86000
  const link = fs32.readlinkSync(source);
85830
- const outside = path60.isAbsolute(link) && within(link, main) && !path60.relative(main, link).split(path60.sep).includes(MODULES);
85831
- const to = outside ? path60.join(worktree, path60.relative(main, link)) : link;
86001
+ const outside = path61.isAbsolute(link) && within(link, main) && !path61.relative(main, link).split(path61.sep).includes(MODULES);
86002
+ const to = outside ? path61.join(worktree, path61.relative(main, link)) : link;
85832
86003
  fs32.symlinkSync(to, target, process.platform === "win32" ? "junction" : undefined);
85833
86004
  return;
85834
86005
  }
@@ -85838,8 +86009,8 @@ function mirror(main, worktree, source, target, top) {
85838
86009
  fs32.mkdirSync(target);
85839
86010
  let count = 0;
85840
86011
  for (const entry of fs32.readdirSync(source, { withFileTypes: true })) {
85841
- const from = path60.join(source, entry.name);
85842
- const to = path60.join(target, entry.name);
86012
+ const from = path61.join(source, entry.name);
86013
+ const to = path61.join(target, entry.name);
85843
86014
  if (top && entry.isDirectory() && (entry.name.startsWith("@") || entry.name === ".bin"))
85844
86015
  count += mirror(main, worktree, from, to, false);
85845
86016
  else {
@@ -85855,16 +86026,16 @@ function linkWorktreeDependencies(main, worktree) {
85855
86026
  const dirs = [];
85856
86027
  let entries = 0;
85857
86028
  for (const relative of moduleDirs(main)) {
85858
- const target = path60.join(worktree, relative);
85859
- if (!fs32.existsSync(path60.dirname(target)) || fs32.existsSync(target))
86029
+ const target = path61.join(worktree, relative);
86030
+ if (!fs32.existsSync(path61.dirname(target)) || fs32.existsSync(target))
85860
86031
  continue;
85861
- if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(path60.sep).join("/")}/`]).ok) {
85862
- notes.push(`${relative.split(path60.sep).join("/")} is not ignored by git, so it was not linked from ${main}; install dependencies in the worktree yourself`);
86032
+ if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(path61.sep).join("/")}/`]).ok) {
86033
+ notes.push(`${relative.split(path61.sep).join("/")} is not ignored by git, so it was not linked from ${main}; install dependencies in the worktree yourself`);
85863
86034
  continue;
85864
86035
  }
85865
86036
  try {
85866
- entries += mirror(main, worktree, path60.join(main, relative), target, true);
85867
- dirs.push(relative.split(path60.sep).join("/"));
86037
+ entries += mirror(main, worktree, path61.join(main, relative), target, true);
86038
+ dirs.push(relative.split(path61.sep).join("/"));
85868
86039
  } catch (error) {
85869
86040
  fs32.rmSync(target, { recursive: true, force: true });
85870
86041
  notes.push(`could not link ${relative} from ${main} (${error.message}); install dependencies in the worktree yourself`);
@@ -85877,8 +86048,8 @@ function linkWorktreeDependencies(main, worktree) {
85877
86048
  return { linked: { from: main, dirs, entries, ms }, notes };
85878
86049
  }
85879
86050
  var MODULES = "node_modules", MAX_DEPTH2 = 2, within = (child, parent) => {
85880
- const relative = path60.relative(parent, child);
85881
- return relative === "" || !relative.startsWith("..") && !path60.isAbsolute(relative);
86051
+ const relative = path61.relative(parent, child);
86052
+ return relative === "" || !relative.startsWith("..") && !path61.isAbsolute(relative);
85882
86053
  };
85883
86054
  var init_worktree_deps = __esm(() => {
85884
86055
  init_fanout();
@@ -85887,7 +86058,7 @@ var init_worktree_deps = __esm(() => {
85887
86058
  // packages/workit-core/src/fanout-worktree.ts
85888
86059
  import { randomBytes as randomBytes5 } from "node:crypto";
85889
86060
  import fs33 from "node:fs";
85890
- import path61 from "node:path";
86061
+ import path62 from "node:path";
85891
86062
  function rowSample(lines) {
85892
86063
  const out = [];
85893
86064
  let bytes = 0;
@@ -85947,7 +86118,7 @@ function adminDir(worktree) {
85947
86118
  const file = dir.stdout.trim();
85948
86119
  let token = null;
85949
86120
  try {
85950
- token = fs33.readFileSync(path61.join(file, FANOUT_TOKEN_FILE), "utf8").trim() || null;
86121
+ token = fs33.readFileSync(path62.join(file, FANOUT_TOKEN_FILE), "utf8").trim() || null;
85951
86122
  } catch {
85952
86123
  token = null;
85953
86124
  }
@@ -85955,7 +86126,7 @@ function adminDir(worktree) {
85955
86126
  const stat = worktreeDeps.stat(file);
85956
86127
  return {
85957
86128
  path: file,
85958
- id: path61.basename(file),
86129
+ id: path62.basename(file),
85959
86130
  ino: stat.ino.toString(),
85960
86131
  token,
85961
86132
  birthMs: stat.birthtimeNs > 0n ? Number(stat.birthtimeMs) : null,
@@ -85971,7 +86142,7 @@ function markAdminDir(worktree) {
85971
86142
  return null;
85972
86143
  const token = randomBytes5(16).toString("hex");
85973
86144
  try {
85974
- fs33.writeFileSync(path61.join(admin.path, FANOUT_TOKEN_FILE), `${token}
86145
+ fs33.writeFileSync(path62.join(admin.path, FANOUT_TOKEN_FILE), `${token}
85975
86146
  `);
85976
86147
  } catch {
85977
86148
  return null;
@@ -85986,7 +86157,7 @@ function excludeScratch(cwd) {
85986
86157
  const common = gitCommonDir(cwd);
85987
86158
  if (!common)
85988
86159
  return;
85989
- const file = path61.join(common, "info", "exclude");
86160
+ const file = path62.join(common, "info", "exclude");
85990
86161
  let text = "";
85991
86162
  try {
85992
86163
  text = fs33.readFileSync(file, "utf8");
@@ -85995,7 +86166,7 @@ function excludeScratch(cwd) {
85995
86166
  }
85996
86167
  if (text.split(/\r?\n/u).includes(EXCLUDE_LINE))
85997
86168
  return;
85998
- fs33.mkdirSync(path61.dirname(file), { recursive: true });
86169
+ fs33.mkdirSync(path62.dirname(file), { recursive: true });
85999
86170
  fs33.appendFileSync(file, `${text && !text.endsWith(`
86000
86171
  `) ? `
86001
86172
  ` : ""}# workit fanout: per-worker scratch dirs
@@ -86003,7 +86174,7 @@ ${EXCLUDE_LINE}
86003
86174
  `);
86004
86175
  }
86005
86176
  function ensureScratch(worktree) {
86006
- const scratch = path61.join(worktree, SCRATCH_DIR);
86177
+ const scratch = path62.join(worktree, SCRATCH_DIR);
86007
86178
  fs33.mkdirSync(scratch, { recursive: true });
86008
86179
  return scratch;
86009
86180
  }
@@ -86231,7 +86402,7 @@ function unpushedCount(cwd, branch) {
86231
86402
  return count.ok ? Number(count.stdout.trim()) : null;
86232
86403
  }
86233
86404
  function removeScratch(worktree) {
86234
- const scratch = path61.join(worktree, SCRATCH_DIR);
86405
+ const scratch = path62.join(worktree, SCRATCH_DIR);
86235
86406
  let stat;
86236
86407
  try {
86237
86408
  stat = fs33.lstatSync(scratch);
@@ -86247,16 +86418,16 @@ var SLOW, SCRATCH_DIR = ".workit-scratch", EXCLUDE_LINE, DIRTY_ROW_BYTES = 2000,
86247
86418
  try {
86248
86419
  return fs33.realpathSync.native(target);
86249
86420
  } catch {
86250
- return path61.resolve(target);
86421
+ return path62.resolve(target);
86251
86422
  }
86252
86423
  }, samePath = (a, b) => {
86253
86424
  const left = canonical2(a);
86254
86425
  const right = canonical2(b);
86255
86426
  return process.platform === "win32" || process.platform === "darwin" ? left.toLowerCase() === right.toLowerCase() : left === right;
86256
86427
  }, inside3 = (child, parent) => {
86257
- const relative = path61.relative(canonical2(parent), canonical2(child));
86258
- return relative === "" || !relative.startsWith("..") && !path61.isAbsolute(relative);
86259
- }, slicePath = (cwd, slice) => path61.isAbsolute(slice.worktree) ? slice.worktree : path61.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, worktreeFailed = (stderr) => fanoutFail("failed", `git worktree add failed: ${stderr.trim().split(`
86428
+ const relative = path62.relative(canonical2(parent), canonical2(child));
86429
+ return relative === "" || !relative.startsWith("..") && !path62.isAbsolute(relative);
86430
+ }, slicePath = (cwd, slice) => path62.isAbsolute(slice.worktree) ? slice.worktree : path62.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, worktreeFailed = (stderr) => fanoutFail("failed", `git worktree add failed: ${stderr.trim().split(`
86260
86431
  `)[0] || "unknown error"}`);
86261
86432
  var init_fanout_worktree = __esm(() => {
86262
86433
  init_ops();
@@ -87092,7 +87263,7 @@ __export(exports_fanout, {
87092
87263
  run: () => run20
87093
87264
  });
87094
87265
  import fs34 from "node:fs";
87095
- import path62 from "node:path";
87266
+ import path63 from "node:path";
87096
87267
  function forgeFor(io, offline) {
87097
87268
  if (offline)
87098
87269
  return { forge: null, error: "--offline" };
@@ -87153,7 +87324,7 @@ function plan2(argv, io) {
87153
87324
  return usage3(io, "pass --trunk or --track, not both (--track picks the trunk)", PLAN_USAGE2);
87154
87325
  if (flags.positionals.length !== 1)
87155
87326
  return usage3(io, flags.positionals.length ? `unexpected argument ${flags.positionals[1]}` : "missing <plan.json>", PLAN_USAGE2);
87156
- const file = path62.resolve(io.cwd, flags.positionals[0]);
87327
+ const file = path63.resolve(io.cwd, flags.positionals[0]);
87157
87328
  let raw;
87158
87329
  try {
87159
87330
  raw = JSON.parse(fs34.readFileSync(file, "utf8"));
@@ -102692,7 +102863,7 @@ var init_ast = __esm(() => {
102692
102863
 
102693
102864
  // packages/workit-cli/src/test-audit/rules.ts
102694
102865
  import { builtinModules } from "node:module";
102695
- import path63 from "node:path";
102866
+ import path64 from "node:path";
102696
102867
  function testCallee(call) {
102697
102868
  let callee = call.callee;
102698
102869
  if (callee.type === "CallExpression")
@@ -103185,12 +103356,12 @@ function checkConstantsOnly(ctx, emit) {
103185
103356
  }
103186
103357
  function checkOverMocking(ctx, emit) {
103187
103358
  const { program } = ctx.parsed;
103188
- const unit = path63.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
103359
+ const unit = path64.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
103189
103360
  const mocked = find2(program, (node) => node.type === "CallExpression" && MODULE_MOCK.test(calleeName(node.callee) ?? "") && node.arguments[0]?.type === "StringLiteral");
103190
103361
  const internal = mocked.filter((call) => /^(?:\.|@\/|~\/)/.test(call.arguments[0].value));
103191
103362
  for (const call of mocked) {
103192
103363
  const spec = call.arguments[0].value;
103193
- const base = path63.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
103364
+ const base = path64.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
103194
103365
  if (base === unit)
103195
103366
  emit({
103196
103367
  rule: "over-mocking",
@@ -103579,8 +103750,8 @@ var init_rules = __esm(() => {
103579
103750
 
103580
103751
  // packages/workit-cli/src/test-audit/audit.ts
103581
103752
  import { spawnSync as spawnSync29 } from "node:child_process";
103582
- import { existsSync as existsSync22, readdirSync as readdirSync10, readFileSync as readFileSync25, statSync as statSync9 } from "node:fs";
103583
- import path64 from "node:path";
103753
+ import { existsSync as existsSync23, readdirSync as readdirSync11, readFileSync as readFileSync26, statSync as statSync10 } from "node:fs";
103754
+ import path65 from "node:path";
103584
103755
  function git7(cwd, args) {
103585
103756
  const run = spawnSync29("git", ["-c", "core.quotepath=off", ...args], {
103586
103757
  cwd,
@@ -103590,10 +103761,10 @@ function git7(cwd, args) {
103590
103761
  return { ok: run.status === 0, stdout: run.stdout ?? "" };
103591
103762
  }
103592
103763
  function walkTests(dir, out) {
103593
- for (const entry of readdirSync10(dir, { withFileTypes: true })) {
103764
+ for (const entry of readdirSync11(dir, { withFileTypes: true })) {
103594
103765
  if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
103595
103766
  continue;
103596
- const full = path64.join(dir, entry.name);
103767
+ const full = path65.join(dir, entry.name);
103597
103768
  if (entry.isDirectory()) {
103598
103769
  if (!SKIP_DIRS.has(entry.name))
103599
103770
  walkTests(full, out);
@@ -103605,10 +103776,10 @@ function expandPaths(cwd, inputs) {
103605
103776
  const files = [];
103606
103777
  const missing = [];
103607
103778
  for (const input of inputs.length > 0 ? inputs : ["."]) {
103608
- const full = path64.resolve(cwd, input);
103609
- if (!existsSync22(full))
103779
+ const full = path65.resolve(cwd, input);
103780
+ if (!existsSync23(full))
103610
103781
  missing.push(input);
103611
- else if (statSync9(full).isDirectory())
103782
+ else if (statSync10(full).isDirectory())
103612
103783
  walkTests(full, files);
103613
103784
  else
103614
103785
  files.push(full);
@@ -103642,11 +103813,11 @@ function changedLines(cwd, base) {
103642
103813
  for (let offset = 0;offset < count; offset += 1)
103643
103814
  lines.add(start + offset);
103644
103815
  }
103645
- changed.set(path64.join(root, file), lines);
103816
+ changed.set(path65.join(root, file), lines);
103646
103817
  }
103647
103818
  const untracked = git7(root, ["ls-files", "--others", "--exclude-standard", "-z"]);
103648
103819
  for (const file of untracked.stdout.split("\x00").filter(Boolean))
103649
- changed.set(path64.join(root, file), "all");
103820
+ changed.set(path65.join(root, file), "all");
103650
103821
  return changed;
103651
103822
  }
103652
103823
  function auditFiles(files, display) {
@@ -103659,7 +103830,7 @@ function auditFiles(files, display) {
103659
103830
  const shown = display(file);
103660
103831
  let parsed;
103661
103832
  try {
103662
- parsed = parseSource(readFileSync25(file, "utf8"), file);
103833
+ parsed = parseSource(readFileSync26(file, "utf8"), file);
103663
103834
  } catch (error) {
103664
103835
  parseErrors.push({
103665
103836
  file: shown,
@@ -103708,7 +103879,7 @@ function auditFiles(files, display) {
103708
103879
  durationMs: Math.round(performance.now() - started)
103709
103880
  };
103710
103881
  }
103711
- var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path64.sep).join("/"), SEVERITY_ORDER, ruleIds;
103882
+ var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path65.sep).join("/"), SEVERITY_ORDER, ruleIds;
103712
103883
  var init_audit = __esm(() => {
103713
103884
  init_ast();
103714
103885
  init_rules();
@@ -103722,23 +103893,23 @@ var init_audit = __esm(() => {
103722
103893
  // packages/workit-cli/src/test-audit/mutate.ts
103723
103894
  import { spawn as spawn2 } from "node:child_process";
103724
103895
  import {
103725
- existsSync as existsSync23,
103896
+ existsSync as existsSync24,
103726
103897
  lstatSync as lstatSync8,
103727
103898
  mkdirSync as mkdirSync11,
103728
103899
  mkdtempSync as mkdtempSync4,
103729
- readdirSync as readdirSync11,
103730
- readFileSync as readFileSync26,
103900
+ readdirSync as readdirSync12,
103901
+ readFileSync as readFileSync27,
103731
103902
  readlinkSync as readlinkSync3,
103732
103903
  realpathSync as realpathSync10,
103733
103904
  renameSync as renameSync7,
103734
103905
  rmSync as rmSync9,
103735
- statSync as statSync10,
103906
+ statSync as statSync11,
103736
103907
  symlinkSync,
103737
103908
  writeFileSync as writeFileSync11,
103738
103909
  copyFileSync as copyFileSync7
103739
103910
  } from "node:fs";
103740
- import os21 from "node:os";
103741
- import path65 from "node:path";
103911
+ import os22 from "node:os";
103912
+ import path66 from "node:path";
103742
103913
  function mutantsFor(source, file, lines) {
103743
103914
  const parsed = parseSource(source, file);
103744
103915
  const out = [];
@@ -103811,7 +103982,7 @@ function relatedTests(source, testFiles) {
103811
103982
  for (const match of text.matchAll(SPECIFIER)) {
103812
103983
  const spec = match[1];
103813
103984
  if (spec.startsWith(".")) {
103814
- if (stripExt(path65.posix.join(path65.posix.dirname(file), spec)) === target)
103985
+ if (stripExt(path66.posix.join(path66.posix.dirname(file), spec)) === target)
103815
103986
  return true;
103816
103987
  } else if (spec.includes("/") && stripExt(spec).split("/").slice(-2).join("/") === tail)
103817
103988
  return true;
@@ -103819,11 +103990,11 @@ function relatedTests(source, testFiles) {
103819
103990
  return false;
103820
103991
  }).map((entry) => entry.file);
103821
103992
  }
103822
- function removeStaleCopies(tmp = os21.tmpdir()) {
103993
+ function removeStaleCopies(tmp = os22.tmpdir()) {
103823
103994
  let removed = 0;
103824
103995
  let names = [];
103825
103996
  try {
103826
- names = readdirSync11(tmp);
103997
+ names = readdirSync12(tmp);
103827
103998
  } catch {
103828
103999
  return 0;
103829
104000
  }
@@ -103831,12 +104002,12 @@ function removeStaleCopies(tmp = os21.tmpdir()) {
103831
104002
  for (const name of names) {
103832
104003
  if (!name.startsWith(TEMP_PREFIX))
103833
104004
  continue;
103834
- const dir = path65.join(tmp, name);
104005
+ const dir = path66.join(tmp, name);
103835
104006
  try {
103836
104007
  const stat = lstatSync8(dir);
103837
104008
  if (!stat.isDirectory() || uid !== undefined && stat.uid !== uid)
103838
104009
  continue;
103839
- const pid = Number(readFileSync26(path65.join(dir, PID_FILE), "utf8"));
104010
+ const pid = Number(readFileSync27(path66.join(dir, PID_FILE), "utf8"));
103840
104011
  if (Number.isInteger(pid) && pid > 0 && alive(pid))
103841
104012
  continue;
103842
104013
  } catch (error) {
@@ -103852,9 +104023,9 @@ function removeStaleCopies(tmp = os21.tmpdir()) {
103852
104023
  }
103853
104024
  function linkNodeModules(origin, target, repo, copy) {
103854
104025
  mkdirSync11(target, { recursive: true });
103855
- for (const entry of readdirSync11(origin, { withFileTypes: true })) {
103856
- const from = path65.join(origin, entry.name);
103857
- const to = path65.join(target, entry.name);
104026
+ for (const entry of readdirSync12(origin, { withFileTypes: true })) {
104027
+ const from = path66.join(origin, entry.name);
104028
+ const to = path66.join(target, entry.name);
103858
104029
  if (entry.name.startsWith("@") && entry.isDirectory()) {
103859
104030
  linkNodeModules(from, to, repo, copy);
103860
104031
  continue;
@@ -103870,9 +104041,9 @@ function linkNodeModules(origin, target, repo, copy) {
103870
104041
  } catch {
103871
104042
  continue;
103872
104043
  }
103873
- const relative = path65.relative(repo, real);
103874
- if (!relative.startsWith("..") && !path65.isAbsolute(relative) && !relative.split(path65.sep).includes("node_modules")) {
103875
- symlinkSync(path65.join(copy, relative), to, "junction");
104044
+ const relative = path66.relative(repo, real);
104045
+ if (!relative.startsWith("..") && !path66.isAbsolute(relative) && !relative.split(path66.sep).includes("node_modules")) {
104046
+ symlinkSync(path66.join(copy, relative), to, "junction");
103876
104047
  continue;
103877
104048
  }
103878
104049
  }
@@ -103888,19 +104059,19 @@ function copySymlink(repo, tree, from, to) {
103888
104059
  }
103889
104060
  const realRepo = realpathSync10(repo);
103890
104061
  if (real && inside4(realRepo, real)) {
103891
- symlinkSync(path65.relative(path65.dirname(to), path65.join(tree, path65.relative(realRepo, real))), to);
104062
+ symlinkSync(path66.relative(path66.dirname(to), path66.join(tree, path66.relative(realRepo, real))), to);
103892
104063
  return;
103893
104064
  }
103894
- if (real && statSync10(real).isFile())
104065
+ if (real && statSync11(real).isFile())
103895
104066
  copyFileSync7(real, to);
103896
104067
  else
103897
104068
  symlinkSync(readlinkSync3(from), to);
103898
104069
  }
103899
104070
  function writeInside(copy, file, content) {
103900
- const target = path65.join(copy, file);
104071
+ const target = path66.join(copy, file);
103901
104072
  try {
103902
104073
  const stat = lstatSync8(target);
103903
- if (!stat.isFile() || !inside4(realpathSync10(copy), realpathSync10(path65.dirname(target))))
104074
+ if (!stat.isFile() || !inside4(realpathSync10(copy), realpathSync10(path66.dirname(target))))
103904
104075
  return false;
103905
104076
  } catch {
103906
104077
  return false;
@@ -103911,9 +104082,9 @@ function writeInside(copy, file, content) {
103911
104082
  return true;
103912
104083
  }
103913
104084
  function copyWorkingTree(repo) {
103914
- const dir = mkdtempSync4(path65.join(os21.tmpdir(), TEMP_PREFIX));
103915
- writeFileSync11(path65.join(dir, PID_FILE), String(process.pid));
103916
- const tree = path65.join(dir, "tree");
104085
+ const dir = mkdtempSync4(path66.join(os22.tmpdir(), TEMP_PREFIX));
104086
+ writeFileSync11(path66.join(dir, PID_FILE), String(process.pid));
104087
+ const tree = path66.join(dir, "tree");
103917
104088
  const head = git7(repo, ["rev-parse", "--verify", "--quiet", "HEAD"]).stdout.trim();
103918
104089
  if (head && git7(dir, ["clone", "-q", "--shared", "--no-checkout", repo, tree]).ok) {
103919
104090
  const branch = git7(repo, ["symbolic-ref", "--quiet", "--short", "HEAD"]).stdout.trim();
@@ -103930,29 +104101,29 @@ function copyWorkingTree(repo) {
103930
104101
  for (const relative of listed) {
103931
104102
  if (!relative)
103932
104103
  continue;
103933
- const from = path65.join(repo, relative);
104104
+ const from = path66.join(repo, relative);
103934
104105
  let stat;
103935
104106
  try {
103936
104107
  stat = lstatSync8(from);
103937
104108
  } catch {
103938
104109
  continue;
103939
104110
  }
103940
- const to = path65.join(tree, relative);
103941
- mkdirSync11(path65.dirname(to), { recursive: true });
104111
+ const to = path66.join(tree, relative);
104112
+ mkdirSync11(path66.dirname(to), { recursive: true });
103942
104113
  if (stat.isSymbolicLink())
103943
104114
  copySymlink(repo, tree, from, to);
103944
104115
  else if (stat.isFile())
103945
104116
  copyFileSync7(from, to);
103946
- let parent = path65.dirname(relative);
104117
+ let parent = path66.dirname(relative);
103947
104118
  while (parent !== "." && !dirs.has(parent)) {
103948
104119
  dirs.add(parent);
103949
- parent = path65.dirname(parent);
104120
+ parent = path66.dirname(parent);
103950
104121
  }
103951
104122
  }
103952
104123
  for (const parent of dirs) {
103953
- const modules = path65.join(repo, parent, "node_modules");
103954
- if (existsSync23(modules) && !existsSync23(path65.join(tree, parent, "node_modules")))
103955
- linkNodeModules(modules, path65.join(tree, parent, "node_modules"), repo, tree);
104124
+ const modules = path66.join(repo, parent, "node_modules");
104125
+ if (existsSync24(modules) && !existsSync24(path66.join(tree, parent, "node_modules")))
104126
+ linkNodeModules(modules, path66.join(tree, parent, "node_modules"), repo, tree);
103956
104127
  }
103957
104128
  return { dir, tree };
103958
104129
  }
@@ -103991,20 +104162,20 @@ async function runMutation(options) {
103991
104162
  const tracked = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00").filter(Boolean);
103992
104163
  const testFiles = tracked.filter((file) => TEST_FILE.test(file)).map((file) => {
103993
104164
  try {
103994
- return { file, text: readFileSync26(path65.join(repo, file), "utf8") };
104165
+ return { file, text: readFileSync27(path66.join(repo, file), "utf8") };
103995
104166
  } catch {
103996
104167
  return { file, text: "" };
103997
104168
  }
103998
104169
  });
103999
104170
  const candidates = [];
104000
104171
  for (const [absolute, lines] of [...options.changed].toSorted(([a], [b]) => a.localeCompare(b))) {
104001
- const relative = toPosix(path65.relative(repo, absolute));
104172
+ const relative = toPosix(path66.relative(repo, absolute));
104002
104173
  if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
104003
104174
  continue;
104004
- if (NOT_SOURCE.test(relative) || !existsSync23(absolute))
104175
+ if (NOT_SOURCE.test(relative) || !existsSync24(absolute))
104005
104176
  continue;
104006
104177
  try {
104007
- candidates.push(...mutantsFor(readFileSync26(absolute, "utf8"), relative, lines));
104178
+ candidates.push(...mutantsFor(readFileSync27(absolute, "utf8"), relative, lines));
104008
104179
  } catch {}
104009
104180
  }
104010
104181
  const mutants = candidates.map((mutant, index) => ({ ...mutant, id: index + 1 }));
@@ -104012,9 +104183,9 @@ async function runMutation(options) {
104012
104183
  for (const mutant of mutants)
104013
104184
  if (!related.has(mutant.file))
104014
104185
  related.set(mutant.file, relatedTests(mutant.file, testFiles));
104015
- const cwdRelative = path65.relative(repo, options.cwd);
104186
+ const cwdRelative = path66.relative(repo, options.cwd);
104016
104187
  const asArg = (file) => {
104017
- const relative = toPosix(path65.relative(cwdRelative, file));
104188
+ const relative = toPosix(path66.relative(cwdRelative, file));
104018
104189
  return shellQuote(relative.startsWith(".") ? relative : `./${relative}`);
104019
104190
  };
104020
104191
  const commandFor = (tests) => options.command.replaceAll("{files}", () => tests.map(asArg).join(" "));
@@ -104050,7 +104221,7 @@ async function runMutation(options) {
104050
104221
  return finish3(options, 0, results, counts, started);
104051
104222
  removeStaleCopies();
104052
104223
  const { dir: copyDir, tree: copy } = copyWorkingTree(repo);
104053
- const copyCwd = path65.join(copy, cwdRelative);
104224
+ const copyCwd = path66.join(copy, cwdRelative);
104054
104225
  let current = null;
104055
104226
  const restore = () => {
104056
104227
  if (current)
@@ -104085,7 +104256,7 @@ async function runMutation(options) {
104085
104256
  record({ ...mutant, status: "skipped", durationMs: 0, tests, reason: "budget" });
104086
104257
  continue;
104087
104258
  }
104088
- const original = readFileSync26(path65.join(copy, mutant.file), "utf8");
104259
+ const original = readFileSync27(path66.join(copy, mutant.file), "utf8");
104089
104260
  const mutated = original.slice(0, mutant.start) + mutant.replacement + original.slice(mutant.end);
104090
104261
  current = { file: mutant.file, original };
104091
104262
  if (!writeInside(copy, mutant.file, mutated)) {
@@ -104142,8 +104313,8 @@ var NOT_SOURCE, FLIPS, isStringy = (node) => node.type === "StringLiteral" || no
104142
104313
  return error.code === "EPERM";
104143
104314
  }
104144
104315
  }, inside4 = (root, file) => {
104145
- const relative = path65.relative(root, file);
104146
- return relative === "" || !relative.startsWith("..") && !path65.isAbsolute(relative);
104316
+ const relative = path66.relative(root, file);
104317
+ return relative === "" || !relative.startsWith("..") && !path66.isAbsolute(relative);
104147
104318
  }, active, killTree = (child) => {
104148
104319
  try {
104149
104320
  if (child.pid && process.platform !== "win32")
@@ -104191,8 +104362,8 @@ var exports_test_audit = {};
104191
104362
  __export(exports_test_audit, {
104192
104363
  run: () => run22
104193
104364
  });
104194
- import { existsSync as existsSync24 } from "node:fs";
104195
- import path66 from "node:path";
104365
+ import { existsSync as existsSync25 } from "node:fs";
104366
+ import path67 from "node:path";
104196
104367
  function parse8(argv) {
104197
104368
  const options = {
104198
104369
  paths: [],
@@ -104297,8 +104468,8 @@ async function run22(argv, io) {
104297
104468
  return emit(io, fail2("invalid_input", `${options}
104298
104469
  usage: ${USAGE14}`));
104299
104470
  const top = git7(io.cwd, ["rev-parse", "--show-toplevel"]);
104300
- const repo = top.ok ? path66.resolve(top.stdout.trim()) : null;
104301
- const display = (file) => toPosix(path66.relative(io.cwd, file) || file);
104471
+ const repo = top.ok ? path67.resolve(top.stdout.trim()) : null;
104472
+ const display = (file) => toPosix(path67.relative(io.cwd, file) || file);
104302
104473
  let base = null;
104303
104474
  let changed = null;
104304
104475
  if (options.diff || options.mutate) {
@@ -104315,7 +104486,7 @@ usage: ${USAGE14}`));
104315
104486
  }
104316
104487
  let files;
104317
104488
  if (options.diff && changed)
104318
- files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) && existsSync24(file)).toSorted();
104489
+ files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) && existsSync25(file)).toSorted();
104319
104490
  else {
104320
104491
  const expanded = expandPaths(io.cwd, options.paths);
104321
104492
  if (expanded.missing.length > 0)
@@ -104436,8 +104607,8 @@ var exports_youtrack = {};
104436
104607
  __export(exports_youtrack, {
104437
104608
  run: () => run24
104438
104609
  });
104439
- import { readFileSync as readFileSync27 } from "node:fs";
104440
- import path67 from "node:path";
104610
+ import { readFileSync as readFileSync28 } from "node:fs";
104611
+ import path68 from "node:path";
104441
104612
  async function run24(argv, io) {
104442
104613
  const [sub, ...rest] = argv;
104443
104614
  if (sub !== "note" && sub !== "time" && sub !== "meeting")
@@ -104483,7 +104654,7 @@ async function run24(argv, io) {
104483
104654
  let markdown = flags.values.markdown ?? "";
104484
104655
  if (flags.values.file)
104485
104656
  try {
104486
- markdown = readFileSync27(path67.resolve(io.cwd, flags.values.file), "utf8");
104657
+ markdown = readFileSync28(path68.resolve(io.cwd, flags.values.file), "utf8");
104487
104658
  } catch (error) {
104488
104659
  return usage3(io, `cannot read ${flags.values.file}: ${String(error)}`, USAGE16);
104489
104660
  }
@@ -104551,8 +104722,8 @@ var exports_changelog = {};
104551
104722
  __export(exports_changelog, {
104552
104723
  run: () => run25
104553
104724
  });
104554
- import { readFileSync as readFileSync28 } from "node:fs";
104555
- import path68 from "node:path";
104725
+ import { readFileSync as readFileSync29 } from "node:fs";
104726
+ import path69 from "node:path";
104556
104727
  async function run25(argv, io) {
104557
104728
  const [sub, ...rest] = argv;
104558
104729
  if (sub !== "apply")
@@ -104598,7 +104769,7 @@ async function run25(argv, io) {
104598
104769
  ]);
104599
104770
  }
104600
104771
  var USAGE17 = "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]", readEntries = (raw, cwd) => {
104601
- const text = raw === "-" ? readFileSync28(0, "utf8") : raw.startsWith("@") ? readFileSync28(path68.resolve(cwd, raw.slice(1)), "utf8") : raw;
104772
+ const text = raw === "-" ? readFileSync29(0, "utf8") : raw.startsWith("@") ? readFileSync29(path69.resolve(cwd, raw.slice(1)), "utf8") : raw;
104602
104773
  return JSON.parse(text);
104603
104774
  };
104604
104775
  var init_changelog2 = __esm(() => {
@@ -104695,7 +104866,7 @@ var init_handoff = __esm(() => {
104695
104866
  // packages/workit-cli/src/main.ts
104696
104867
  init_host_session();
104697
104868
  init_package();
104698
- import path69 from "node:path";
104869
+ import path70 from "node:path";
104699
104870
 
104700
104871
  // packages/workit-cli/src/verbs/registry.ts
104701
104872
  var TASK_FAMILY_NAMES = [
@@ -104940,7 +105111,7 @@ var VERBS = [
104940
105111
  subcommands: [
104941
105112
  {
104942
105113
  name: "show",
104943
- usage: "workit models show [--role <role>] [--tier <mundane|standard|hard>] [--host <host>] [--json]",
105114
+ usage: "workit models show [--role <role>] [--tier <mundane|standard|hard>] [--host <host>] [--report [--days <n>]] [--json]",
104944
105115
  summary: "Print the resolved model and effort per role for a host (default: the lead's host, else claude_code) and where each came from"
104945
105116
  }
104946
105117
  ],
@@ -105557,7 +105728,7 @@ var defaultIo = (json) => ({
105557
105728
  });
105558
105729
  async function main(argv, overrides = {}, options = {}) {
105559
105730
  const parsed = parseGlobals(argv);
105560
- const cwd = path69.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
105731
+ const cwd = path70.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
105561
105732
  const io = { ...defaultIo(parsed.json), ...overrides, json: parsed.json, cwd };
105562
105733
  if (parsed.error)
105563
105734
  return emit(io, fail2("invalid_input", parsed.error));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-cli",
3
- "version": "8.27.0",
3
+ "version": "8.28.0",
4
4
  "private": false,
5
5
  "description": "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
6
6
  "keywords": [
@@ -38,13 +38,13 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@babel/parser": "7.29.9",
41
- "@brainervirus/workit-cursor": "^8.27.0",
41
+ "@brainervirus/workit-cursor": "^8.28.0",
42
42
  "@inkjs/ui": "2.0.0",
43
43
  "ink": "7.1.1",
44
44
  "react": "19.2.8"
45
45
  },
46
46
  "devDependencies": {
47
- "@brainervirus/workit-core": "^8.27.0"
47
+ "@brainervirus/workit-core": "^8.28.0"
48
48
  },
49
49
  "engines": {
50
50
  "node": ">=24"