@brainervirus/workit-cursor 8.20.0 → 8.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10767,11 +10767,62 @@ var init_host_session = __esm(() => {
10767
10767
  OWN_CHILD_SHELL = new Set(["opencode", "pi"]);
10768
10768
  });
10769
10769
 
10770
- // packages/workit-core/src/ledger.ts
10771
- import { spawnSync as spawnSync8 } from "node:child_process";
10772
- import { createHash as createHash8, randomBytes as randomBytes2 } from "node:crypto";
10770
+ // packages/workit-core/src/hooks/standing-signal.ts
10771
+ import { createHash as createHash8 } from "node:crypto";
10773
10772
  import fs6 from "node:fs";
10774
10773
  import path8 from "node:path";
10774
+ var gitStoreDir = (cwd) => {
10775
+ try {
10776
+ for (let dir = path8.resolve(cwd);; dir = path8.dirname(dir)) {
10777
+ const dotGit = path8.join(dir, ".git");
10778
+ if (fs6.existsSync(dotGit)) {
10779
+ let gitDir = dotGit;
10780
+ if (fs6.statSync(dotGit).isFile()) {
10781
+ const target = /^gitdir:\s*(.+)$/mu.exec(fs6.readFileSync(dotGit, "utf8"))?.[1]?.trim();
10782
+ if (!target)
10783
+ return null;
10784
+ gitDir = path8.resolve(dir, target);
10785
+ const common = path8.join(gitDir, "commondir");
10786
+ if (fs6.existsSync(common))
10787
+ gitDir = path8.resolve(gitDir, fs6.readFileSync(common, "utf8").trim());
10788
+ }
10789
+ return path8.join(gitDir, "workit");
10790
+ }
10791
+ if (path8.dirname(dir) === dir)
10792
+ return null;
10793
+ }
10794
+ } catch {
10795
+ return null;
10796
+ }
10797
+ }, standingRevFile = (store) => path8.join(store, "standing", "rev"), standingSeenFile = (store, session, agentId) => path8.join(store, "standing", "seen", `${createHash8("sha256").update(`${session}\x00${agentId ?? ""}`).digest("hex").slice(0, 32)}.json`), readStandingRev = (store) => {
10798
+ try {
10799
+ return fs6.readFileSync(standingRevFile(store), "utf8").trim() || null;
10800
+ } catch {
10801
+ return null;
10802
+ }
10803
+ }, readStandingSeen = (file) => {
10804
+ try {
10805
+ const value = JSON.parse(fs6.readFileSync(file, "utf8"));
10806
+ return {
10807
+ rev: typeof value.rev === "string" ? value.rev : null,
10808
+ ids: Array.isArray(value.ids) ? value.ids.filter((id) => typeof id === "string") : []
10809
+ };
10810
+ } catch {
10811
+ return { rev: null, ids: [] };
10812
+ }
10813
+ }, writeStandingSeen = (file, seen) => {
10814
+ try {
10815
+ fs6.mkdirSync(path8.dirname(file), { recursive: true });
10816
+ fs6.writeFileSync(file, JSON.stringify(seen));
10817
+ } catch {}
10818
+ };
10819
+ var init_standing_signal = () => {};
10820
+
10821
+ // packages/workit-core/src/ledger.ts
10822
+ import { spawnSync as spawnSync8 } from "node:child_process";
10823
+ import { createHash as createHash9, randomBytes as randomBytes2 } from "node:crypto";
10824
+ import fs7 from "node:fs";
10825
+ import path9 from "node:path";
10775
10826
  function resolveCommit(cwd, ref) {
10776
10827
  if (!safeRef(ref))
10777
10828
  return null;
@@ -10825,7 +10876,7 @@ function diffHash(cwd, base, head) {
10825
10876
  ], GIT_TIMEOUTS.worktree);
10826
10877
  if (!diff.ok || !diff.stdout)
10827
10878
  return null;
10828
- const hash = createHash8("sha256");
10879
+ const hash = createHash9("sha256");
10829
10880
  for (const line of diff.stdout.split(`
10830
10881
  `)) {
10831
10882
  if (line.startsWith("index "))
@@ -10837,14 +10888,14 @@ function diffHash(cwd, base, head) {
10837
10888
  return `sha256:${hash.digest("hex")}`;
10838
10889
  }
10839
10890
  function storeRoot(cwd) {
10840
- const location = resolveStore(path8.resolve(cwd));
10891
+ const location = resolveStore(path9.resolve(cwd));
10841
10892
  if (location instanceof Error)
10842
10893
  return err("unavailable", location.message.replace(/; fix the repository.*$/u, ""), "fix the repository (git status should work here) or run from a non-git directory");
10843
10894
  return { ok: true, value: { root: location.dir, shared: location.shared } };
10844
10895
  }
10845
10896
  function ledgerPath(cwd) {
10846
10897
  const root = storeRoot(cwd);
10847
- return root.ok ? { ok: true, value: path8.join(root.value.root, "ledger", "ledger.jsonl") } : root;
10898
+ return root.ok ? { ok: true, value: path9.join(root.value.root, "ledger", "ledger.jsonl") } : root;
10848
10899
  }
10849
10900
  function withLedgerLock(file, fn, waitMs = hostAwareLockTimeout(LOCK_WAIT_MS)) {
10850
10901
  const lock = `${file}.lock`;
@@ -10870,15 +10921,15 @@ function withLedgerLock(file, fn, waitMs = hostAwareLockTimeout(LOCK_WAIT_MS)) {
10870
10921
  }
10871
10922
  function appendLine(file, build, options) {
10872
10923
  const write = () => {
10873
- const fd = fs6.openSync(file, "a+", 384);
10924
+ const fd = fs7.openSync(file, "a+", 384);
10874
10925
  try {
10875
10926
  if (process.platform !== "win32")
10876
10927
  tighten(fd);
10877
- const size = fs6.fstatSync(fd).size;
10928
+ const size = fs7.fstatSync(fd).size;
10878
10929
  let fence = "";
10879
10930
  if (size > 0) {
10880
10931
  const last = Buffer.alloc(1);
10881
- fs6.readSync(fd, last, 0, 1, size - 1);
10932
+ fs7.readSync(fd, last, 0, 1, size - 1);
10882
10933
  if (last[0] !== 10)
10883
10934
  fence = `
10884
10935
  `;
@@ -10887,17 +10938,17 @@ function appendLine(file, build, options) {
10887
10938
  if (!line.ok)
10888
10939
  return line;
10889
10940
  const bytes = Buffer.from(fence + line.value);
10890
- const written = fs6.writeSync(fd, bytes);
10941
+ const written = fs7.writeSync(fd, bytes);
10891
10942
  if (written !== bytes.length)
10892
10943
  return err("unavailable", `short write to ${file}: ${written} of ${bytes.length} bytes; the row is torn and will be skipped`);
10893
10944
  return { ok: true, value: undefined };
10894
10945
  } finally {
10895
- fs6.closeSync(fd);
10946
+ fs7.closeSync(fd);
10896
10947
  }
10897
10948
  };
10898
10949
  try {
10899
- fs6.mkdirSync(path8.dirname(file), { recursive: true });
10900
- if (!options.forceLock && !onNetworkFs(path8.dirname(file)))
10950
+ fs7.mkdirSync(path9.dirname(file), { recursive: true });
10951
+ if (!options.forceLock && !onNetworkFs(path9.dirname(file)))
10901
10952
  return write();
10902
10953
  const locked = withLedgerLock(file, write);
10903
10954
  return locked ?? err("busy", `ledger lock ${file}.lock is held`, "retry; remove the .lock directory if no workit process is running");
@@ -10952,8 +11003,8 @@ function readLedger(cwd, options = {}) {
10952
11003
  let text = "";
10953
11004
  let stat = null;
10954
11005
  try {
10955
- stat = fs6.statSync(file.value);
10956
- text = fs6.readFileSync(file.value, "utf8");
11006
+ stat = fs7.statSync(file.value);
11007
+ text = fs7.readFileSync(file.value, "utf8");
10957
11008
  } catch (error) {
10958
11009
  if (error.code === "ENOENT")
10959
11010
  return {
@@ -11085,7 +11136,7 @@ function ledgerTampering(cwd) {
11085
11136
  if (!file.ok)
11086
11137
  return [];
11087
11138
  try {
11088
- const stat = fs6.statSync(file.value);
11139
+ const stat = fs7.statSync(file.value);
11089
11140
  const cached = tamperCache.get(file.value);
11090
11141
  if (cached && cached.size === stat.size && cached.stamp === fileStamp(stat))
11091
11142
  return cached.breaks;
@@ -11367,6 +11418,27 @@ function checkVerdicts(cwd, branch, ledgerRows) {
11367
11418
  warnings
11368
11419
  };
11369
11420
  }
11421
+ function activeStanding(rows, fanout, leads = null) {
11422
+ const active = [];
11423
+ for (const row of rows) {
11424
+ if (row.fanout !== fanout || !fromLead(row, leads))
11425
+ continue;
11426
+ if (row.type === "standing" && typeof row.what === "string" && row.what.trim()) {
11427
+ if (!row.superseded)
11428
+ active.push(row);
11429
+ } else if (row.type === "standing.cleared") {
11430
+ const target = str(row.target);
11431
+ if (target === null)
11432
+ active.length = 0;
11433
+ else {
11434
+ const index = active.findIndex((order) => order.id === target);
11435
+ if (index >= 0)
11436
+ active.splice(index, 1);
11437
+ }
11438
+ }
11439
+ }
11440
+ return active;
11441
+ }
11370
11442
  var LEDGER_VERSION = 1, MAX_LINE_BYTES = 4096, PASSING, FAILING, STRONG_RESULTS, PR_ROW_TYPES, err = (code, error, unblock) => ({
11371
11443
  ok: false,
11372
11444
  code,
@@ -11411,28 +11483,28 @@ var LEDGER_VERSION = 1, MAX_LINE_BYTES = 4096, PASSING, FAILING, STRONG_RESULTS,
11411
11483
  if (process.platform !== "linux")
11412
11484
  return false;
11413
11485
  try {
11414
- return isNetworkFsType(fs6.statfsSync(dir).type);
11486
+ return isNetworkFsType(fs7.statfsSync(dir).type);
11415
11487
  } catch {
11416
11488
  return false;
11417
11489
  }
11418
11490
  }, LOCK_WAIT_MS = 5000, LOCK_STALE_MS = 30000, LOCK_OWNER = "owner", lockToken = (lock) => {
11419
11491
  try {
11420
- return fs6.readFileSync(path8.join(lock, LOCK_OWNER), "utf8");
11492
+ return fs7.readFileSync(path9.join(lock, LOCK_OWNER), "utf8");
11421
11493
  } catch {
11422
11494
  return null;
11423
11495
  }
11424
11496
  }, lockAgeMs = (lock) => {
11425
- for (const target of [path8.join(lock, LOCK_OWNER), lock]) {
11497
+ for (const target of [path9.join(lock, LOCK_OWNER), lock]) {
11426
11498
  try {
11427
- return Date.now() - fs6.statSync(target).mtimeMs;
11499
+ return Date.now() - fs7.statSync(target).mtimeMs;
11428
11500
  } catch {}
11429
11501
  }
11430
11502
  return null;
11431
- }, ledgerLock, sha2562 = (text) => createHash8("sha256").update(text).digest("hex"), chainHash = (prevHash, body) => sha2562(`${prevHash ?? ""}
11503
+ }, ledgerLock, sha2562 = (text) => createHash9("sha256").update(text).digest("hex"), chainHash = (prevHash, body) => sha2562(`${prevHash ?? ""}
11432
11504
  ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
11433
11505
  for (let span = Math.min(size, TAIL_BYTES);span > 0; span = Math.min(size, span * 2)) {
11434
11506
  const buffer = Buffer.alloc(span);
11435
- fs6.readSync(fd, buffer, 0, span, size - span);
11507
+ fs7.readSync(fd, buffer, 0, span, size - span);
11436
11508
  const end = buffer.lastIndexOf(10);
11437
11509
  if (end < 0) {
11438
11510
  if (span === size)
@@ -11462,8 +11534,8 @@ ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
11462
11534
  return null;
11463
11535
  }, tighten = (fd) => {
11464
11536
  try {
11465
- if ((fs6.fstatSync(fd).mode & 63) !== 0)
11466
- fs6.fchmodSync(fd, 384);
11537
+ if ((fs7.fstatSync(fd).mode & 63) !== 0)
11538
+ fs7.fchmodSync(fd, 384);
11467
11539
  } catch {}
11468
11540
  }, sealed = (row, id, at, previous) => {
11469
11541
  const { prevHash: _prev, rowHash: _row, ...fields } = row;
@@ -11505,12 +11577,13 @@ ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
11505
11577
  if (row.self === true && !reasons.includes("no_session"))
11506
11578
  reasons.push("self");
11507
11579
  return reasons;
11508
- }, OBSERVED_ONLY;
11580
+ }, fromLead = (row, leads) => leads === null || row.actor.session !== null && leads.includes(row.actor.session), OBSERVED_ONLY;
11509
11581
  var init_ledger = __esm(() => {
11510
11582
  init_store_lock();
11511
11583
  init_vcs_config();
11512
11584
  init_rev();
11513
11585
  init_host_session();
11586
+ init_standing_signal();
11514
11587
  init_paths();
11515
11588
  PASSING = new Set(["verified", "tests-verified", "type-check-only"]);
11516
11589
  FAILING = new Set(["failed", "blocked"]);
@@ -11536,14 +11609,14 @@ var init_ledger = __esm(() => {
11536
11609
  ledgerLock = {
11537
11610
  acquire(lock) {
11538
11611
  try {
11539
- fs6.mkdirSync(lock);
11612
+ fs7.mkdirSync(lock);
11540
11613
  } catch (error) {
11541
11614
  if (error.code === "EEXIST")
11542
11615
  return null;
11543
11616
  throw error;
11544
11617
  }
11545
11618
  const token = `${process.pid}-${randomBytes2(8).toString("hex")}`;
11546
- fs6.writeFileSync(path8.join(lock, LOCK_OWNER), token);
11619
+ fs7.writeFileSync(path9.join(lock, LOCK_OWNER), token);
11547
11620
  return token;
11548
11621
  },
11549
11622
  release(lock, token) {
@@ -11551,35 +11624,35 @@ var init_ledger = __esm(() => {
11551
11624
  return false;
11552
11625
  const tomb = `${lock}.release-${randomBytes2(6).toString("hex")}`;
11553
11626
  try {
11554
- fs6.renameSync(lock, tomb);
11627
+ fs7.renameSync(lock, tomb);
11555
11628
  } catch {
11556
11629
  return false;
11557
11630
  }
11558
11631
  if (lockToken(tomb) !== token) {
11559
11632
  try {
11560
- fs6.renameSync(tomb, lock);
11633
+ fs7.renameSync(tomb, lock);
11561
11634
  } catch {}
11562
11635
  return false;
11563
11636
  }
11564
- fs6.rmSync(tomb, { recursive: true, force: true });
11637
+ fs7.rmSync(tomb, { recursive: true, force: true });
11565
11638
  return true;
11566
11639
  },
11567
11640
  token: lockToken,
11568
11641
  reap(lock, observed) {
11569
11642
  const tomb = `${lock}.reap-${randomBytes2(6).toString("hex")}`;
11570
11643
  try {
11571
- fs6.renameSync(lock, tomb);
11644
+ fs7.renameSync(lock, tomb);
11572
11645
  } catch {
11573
11646
  return false;
11574
11647
  }
11575
11648
  if (lockToken(tomb) === observed) {
11576
- fs6.rmSync(tomb, { recursive: true, force: true });
11649
+ fs7.rmSync(tomb, { recursive: true, force: true });
11577
11650
  return true;
11578
11651
  }
11579
11652
  try {
11580
- fs6.renameSync(tomb, lock);
11653
+ fs7.renameSync(tomb, lock);
11581
11654
  } catch {
11582
- fs6.rmSync(tomb, { recursive: true, force: true });
11655
+ fs7.rmSync(tomb, { recursive: true, force: true });
11583
11656
  }
11584
11657
  return false;
11585
11658
  }
@@ -11613,7 +11686,7 @@ var init_ledger = __esm(() => {
11613
11686
 
11614
11687
  // packages/workit-core/src/core/policy/derive.ts
11615
11688
  import { existsSync as existsSync2 } from "node:fs";
11616
- import path9 from "node:path";
11689
+ import path10 from "node:path";
11617
11690
  function deriveRequirements(judgment, scope, constraints, verification = "self") {
11618
11691
  const out = [];
11619
11692
  const base = { scope, dependentAction: null };
@@ -11765,7 +11838,7 @@ var RULES, derived2 = (spec) => ({
11765
11838
  decisionIds: []
11766
11839
  };
11767
11840
  }, planRecorded = (task, root) => {
11768
- const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync2(path9.resolve(root, ref.path)));
11841
+ const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync2(path10.resolve(root, ref.path)));
11769
11842
  if (cited)
11770
11843
  return {
11771
11844
  met: true,
@@ -12362,7 +12435,7 @@ var init_safe_write = () => {};
12362
12435
 
12363
12436
  // packages/workit-core/src/autonomy.ts
12364
12437
  import os4 from "node:os";
12365
- import path10 from "node:path";
12438
+ import path11 from "node:path";
12366
12439
  function endpointOf(entry) {
12367
12440
  const raw = entry?.defaultEndpoint;
12368
12441
  if (raw === undefined)
@@ -12459,9 +12532,9 @@ var accountHome = () => {
12459
12532
  } catch {
12460
12533
  return os4.homedir();
12461
12534
  }
12462
- }, grantsHome, grantsDir = () => path10.join(grantsHome.resolve(), ".config", "workit"), grantsOverride = () => {
12463
- const configured = path10.resolve(resolveConfigDir());
12464
- return configured === path10.resolve(grantsDir()) ? null : `the config directory is redirected to ${configured} (WORKFLOW_TOOLKIT_CONFIG, WORKFLOW_TOOLKIT_CONFIG_DIR or XDG_CONFIG_HOME); grants are read only from ${path10.join(grantsDir(), "workspaces.json")}, so the D4 defaults apply`;
12535
+ }, grantsHome, grantsDir = () => path11.join(grantsHome.resolve(), ".config", "workit"), grantsOverride = () => {
12536
+ const configured = path11.resolve(resolveConfigDir());
12537
+ return configured === path11.resolve(grantsDir()) ? null : `the config directory is redirected to ${configured} (WORKFLOW_TOOLKIT_CONFIG, WORKFLOW_TOOLKIT_CONFIG_DIR or XDG_CONFIG_HOME); grants are read only from ${path11.join(grantsDir(), "workspaces.json")}, so the D4 defaults apply`;
12465
12538
  }, GRANT_KINDS, DEFAULT_GRANTS, DEFAULT_ENDPOINTS, DEFAULT_ENDPOINT = "commit", isDefaultEndpoint = (value) => typeof value === "string" && DEFAULT_ENDPOINTS.includes(value), DEFAULT_VERIFICATION = "self", verificationOf = (entry) => entry?.verification === "independent" ? "independent" : "self", isGrantValue = (value) => value === true || value === false || value === "verified", normalized = (kind, value) => value === "verified" && kind !== "merge" ? true : value, fromAutoApprove = (value) => {
12466
12539
  if (value === true)
12467
12540
  return { push: true, pr: true, merge: "verified" };
@@ -12552,7 +12625,7 @@ function normalizeMaxBytes(value, options = {}) {
12552
12625
  }
12553
12626
 
12554
12627
  // node_modules/@openclaw/fs-safe/dist/bounded-read.js
12555
- import fs7 from "node:fs";
12628
+ import fs8 from "node:fs";
12556
12629
  function createScratchBuffer(maxBytes) {
12557
12630
  const initialReadBytes = Number.isFinite(maxBytes) ? Math.min(READ_CHUNK_BYTES, maxBytes + 1) : READ_CHUNK_BYTES;
12558
12631
  return Buffer.allocUnsafe(Math.max(1, initialReadBytes));
@@ -12575,7 +12648,7 @@ function readFileDescriptorBoundedSync(fd, maxBytes) {
12575
12648
  let total = 0;
12576
12649
  while (true) {
12577
12650
  const length = nextReadLength(total, maxBytes, scratch.length);
12578
- const bytesRead = fs7.readSync(fd, scratch, 0, length, null);
12651
+ const bytesRead = fs8.readSync(fd, scratch, 0, length, null);
12579
12652
  if (bytesRead === 0) {
12580
12653
  return Buffer.concat(chunks, total);
12581
12654
  }
@@ -12589,9 +12662,9 @@ var init_bounded_read = __esm(() => {
12589
12662
  });
12590
12663
 
12591
12664
  // node_modules/@openclaw/fs-safe/dist/read-open-flags.js
12592
- import fs8 from "node:fs";
12665
+ import fs9 from "node:fs";
12593
12666
  function resolveReadOpenFlags(options) {
12594
- const constants = options?.constants ?? fs8.constants;
12667
+ const constants = options?.constants ?? fs9.constants;
12595
12668
  const noFollow = process.platform !== "win32" && options?.followSymlinks !== true && typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
12596
12669
  const nonBlocking = process.platform !== "win32" && typeof constants.O_NONBLOCK === "number" ? constants.O_NONBLOCK : 0;
12597
12670
  return constants.O_RDONLY | noFollow | nonBlocking;
@@ -12601,7 +12674,7 @@ var init_read_open_flags = () => {};
12601
12674
  // node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.js
12602
12675
  import { randomBytes as randomBytes3 } from "node:crypto";
12603
12676
  import fsSync from "node:fs";
12604
- import path11 from "node:path";
12677
+ import path12 from "node:path";
12605
12678
  function parseSidecarLockSnapshot(snapshot, parser) {
12606
12679
  return snapshot && { ...snapshot, payload: parseSidecarLockPayload(snapshot.raw, parser) };
12607
12680
  }
@@ -12629,13 +12702,13 @@ ${ownershipToken}
12629
12702
  return { raw, ownershipToken };
12630
12703
  }
12631
12704
  function relativeSidecarLockPath(lockRoot, lockPath) {
12632
- const resolved = path11.resolve(lockPath);
12633
- const lexicalRelative = path11.relative(lockRoot.rootDir, resolved);
12634
- const relative = lexicalRelative !== ".." && !lexicalRelative.startsWith(`..${path11.sep}`) && !path11.isAbsolute(lexicalRelative) ? lexicalRelative : path11.relative(lockRoot.rootReal, resolved);
12635
- if (!relative || relative === ".." || relative.startsWith(`..${path11.sep}`) || path11.isAbsolute(relative)) {
12705
+ const resolved = path12.resolve(lockPath);
12706
+ const lexicalRelative = path12.relative(lockRoot.rootDir, resolved);
12707
+ const relative = lexicalRelative !== ".." && !lexicalRelative.startsWith(`..${path12.sep}`) && !path12.isAbsolute(lexicalRelative) ? lexicalRelative : path12.relative(lockRoot.rootReal, resolved);
12708
+ if (!relative || relative === ".." || relative.startsWith(`..${path12.sep}`) || path12.isAbsolute(relative)) {
12636
12709
  throw new FsSafeError("outside-workspace", "sidecar lock path is outside lockRoot");
12637
12710
  }
12638
- return relative.split(path11.sep).join(path11.posix.sep);
12711
+ return relative.split(path12.sep).join(path12.posix.sep);
12639
12712
  }
12640
12713
  function parseSidecarLockPayload(raw, parser) {
12641
12714
  if (parser) {
@@ -12804,8 +12877,8 @@ function sleepSync(ms) {
12804
12877
  }
12805
12878
 
12806
12879
  // node_modules/@openclaw/fs-safe/dist/file-lock-sync.js
12807
- import fs9 from "node:fs";
12808
- import path12 from "node:path";
12880
+ import fs10 from "node:fs";
12881
+ import path13 from "node:path";
12809
12882
  function getSyncHeldLocks() {
12810
12883
  const globalWithState = globalThis;
12811
12884
  if (!globalWithState[SYNC_HELD_LOCKS_KEY]) {
@@ -12822,7 +12895,7 @@ function releaseAllSyncHeldLocks() {
12822
12895
  }
12823
12896
  try {
12824
12897
  if (held.fd !== undefined)
12825
- fs9.closeSync(held.fd);
12898
+ fs10.closeSync(held.fd);
12826
12899
  } catch {}
12827
12900
  try {
12828
12901
  removeSidecarLockIfUnchangedSync(held.lockPath, held.snapshot);
@@ -12857,7 +12930,7 @@ function releaseSyncHeldLock(held) {
12857
12930
  if (held.fd !== undefined) {
12858
12931
  const fd = held.fd;
12859
12932
  held.fd = undefined;
12860
- fs9.closeSync(fd);
12933
+ fs10.closeSync(fd);
12861
12934
  }
12862
12935
  removeSidecarLockIfUnchangedSync(held.lockPath, held.snapshot);
12863
12936
  heldLocks.delete(held.normalizedTargetPath);
@@ -12880,29 +12953,29 @@ function createSyncHeldLockHandle(held) {
12880
12953
  };
12881
12954
  }
12882
12955
  function canonicalLockParentSync(parent) {
12883
- return process.platform === "win32" ? fs9.realpathSync.native(parent) : fs9.realpathSync(parent);
12956
+ return process.platform === "win32" ? fs10.realpathSync.native(parent) : fs10.realpathSync(parent);
12884
12957
  }
12885
12958
  function normalizeTargetPath(targetPath) {
12886
- const resolved = path12.resolve(targetPath);
12887
- fs9.mkdirSync(path12.dirname(resolved), { recursive: true });
12959
+ const resolved = path13.resolve(targetPath);
12960
+ fs10.mkdirSync(path13.dirname(resolved), { recursive: true });
12888
12961
  try {
12889
- return path12.join(canonicalLockParentSync(path12.dirname(resolved)), path12.basename(resolved));
12962
+ return path13.join(canonicalLockParentSync(path13.dirname(resolved)), path13.basename(resolved));
12890
12963
  } catch {
12891
12964
  return resolved;
12892
12965
  }
12893
12966
  }
12894
12967
  function boundedLockPath(lockPath, lockRoot) {
12895
- const resolved = path12.resolve(lockPath);
12968
+ const resolved = path13.resolve(lockPath);
12896
12969
  if (!lockRoot)
12897
12970
  return resolved;
12898
12971
  relativeSidecarLockPath(lockRoot, resolved);
12899
- const parent = path12.dirname(resolved);
12972
+ const parent = path13.dirname(resolved);
12900
12973
  const parentReal = canonicalLockParentSync(parent);
12901
- const parentRelative = path12.relative(lockRoot.rootReal, parentReal);
12902
- if (parentRelative === ".." || parentRelative.startsWith(`..${path12.sep}`) || path12.isAbsolute(parentRelative)) {
12974
+ const parentRelative = path13.relative(lockRoot.rootReal, parentReal);
12975
+ if (parentRelative === ".." || parentRelative.startsWith(`..${path13.sep}`) || path13.isAbsolute(parentRelative)) {
12903
12976
  throw new FsSafeError("outside-workspace", "sidecar lock parent is outside lockRoot");
12904
12977
  }
12905
- return path12.join(parentReal, path12.basename(resolved));
12978
+ return path13.join(parentReal, path13.basename(resolved));
12906
12979
  }
12907
12980
  function defaultShouldReclaim(snapshot, staleMs, nowMs) {
12908
12981
  const createdAtMs = sidecarLockPayloadCreatedAtMs(snapshot.payload);
@@ -12912,7 +12985,7 @@ function defaultShouldReclaim(snapshot, staleMs, nowMs) {
12912
12985
  }
12913
12986
  function reclaimGuardExists(reclaimGuardPath) {
12914
12987
  try {
12915
- fs9.lstatSync(reclaimGuardPath);
12988
+ fs10.lstatSync(reclaimGuardPath);
12916
12989
  return true;
12917
12990
  } catch (error) {
12918
12991
  if (error.code === "ENOENT")
@@ -12976,19 +13049,19 @@ function acquireFileLockSync(targetPath, options) {
12976
13049
  const { raw, ownershipToken } = serializeSidecarLockPayload(payload);
12977
13050
  let lockFileCreateDenied = false;
12978
13051
  try {
12979
- const noFollow = process.platform !== "win32" && typeof fs9.constants.O_NOFOLLOW === "number" ? fs9.constants.O_NOFOLLOW : 0;
13052
+ const noFollow = process.platform !== "win32" && typeof fs10.constants.O_NOFOLLOW === "number" ? fs10.constants.O_NOFOLLOW : 0;
12980
13053
  try {
12981
- fd = fs9.openSync(lockPath, fs9.constants.O_WRONLY | fs9.constants.O_CREAT | fs9.constants.O_EXCL | noFollow, 384);
13054
+ fd = fs10.openSync(lockPath, fs10.constants.O_WRONLY | fs10.constants.O_CREAT | fs10.constants.O_EXCL | noFollow, 384);
12982
13055
  } catch (error) {
12983
13056
  lockFileCreateDenied = isTransientLockFileDenial(error, lockPath);
12984
13057
  throw error;
12985
13058
  }
12986
- fs9.writeFileSync(fd, raw, "utf8");
12987
- fs9.fsyncSync(fd);
13059
+ fs10.writeFileSync(fd, raw, "utf8");
13060
+ fs10.fsyncSync(fd);
12988
13061
  const snapshot = {
12989
13062
  raw,
12990
13063
  payload,
12991
- stat: fs9.fstatSync(fd),
13064
+ stat: fs10.fstatSync(fd),
12992
13065
  ownershipToken
12993
13066
  };
12994
13067
  const createdHeld = {
@@ -13023,8 +13096,8 @@ function acquireFileLockSync(targetPath, options) {
13023
13096
  return returnedHandle;
13024
13097
  } catch (error) {
13025
13098
  if (fd !== undefined) {
13026
- const failed = { payload: null, stat: fs9.fstatSync(fd) };
13027
- fs9.closeSync(fd);
13099
+ const failed = { payload: null, stat: fs10.fstatSync(fd) };
13100
+ fs10.closeSync(fd);
13028
13101
  fd = undefined;
13029
13102
  removeSidecarLockIfUnchangedSync(lockPath, failed);
13030
13103
  }
@@ -13073,7 +13146,7 @@ function acquireFileLockSync(targetPath, options) {
13073
13146
  })) {
13074
13147
  let ownsReclaimGuard = false;
13075
13148
  try {
13076
- fs9.mkdirSync(reclaimGuardPath);
13149
+ fs10.mkdirSync(reclaimGuardPath);
13077
13150
  ownsReclaimGuard = true;
13078
13151
  if (removeSidecarLockIfUnchangedSync(lockPath, snapshot))
13079
13152
  continue;
@@ -13086,7 +13159,7 @@ function acquireFileLockSync(targetPath, options) {
13086
13159
  } finally {
13087
13160
  if (ownsReclaimGuard) {
13088
13161
  try {
13089
- fs9.rmdirSync(reclaimGuardPath);
13162
+ fs10.rmdirSync(reclaimGuardPath);
13090
13163
  } catch {}
13091
13164
  }
13092
13165
  }
@@ -13119,13 +13192,13 @@ var init_file_lock = __esm(() => {
13119
13192
 
13120
13193
  // packages/workit-core/src/core/package-root.ts
13121
13194
  import { existsSync as existsSync3 } from "node:fs";
13122
- import path13 from "node:path";
13195
+ import path14 from "node:path";
13123
13196
  import { fileURLToPath } from "node:url";
13124
13197
  var packageRoot = () => {
13125
- let dir = path13.dirname(fileURLToPath(import.meta.url));
13198
+ let dir = path14.dirname(fileURLToPath(import.meta.url));
13126
13199
  while (true) {
13127
- const parent = path13.dirname(dir);
13128
- if (existsSync3(path13.join(dir, "package.json")) || parent === dir)
13200
+ const parent = path14.dirname(dir);
13201
+ if (existsSync3(path14.join(dir, "package.json")) || parent === dir)
13129
13202
  return dir;
13130
13203
  dir = parent;
13131
13204
  }
@@ -13134,12 +13207,12 @@ var init_package_root = () => {};
13134
13207
 
13135
13208
  // packages/workit-core/src/store/event-log.ts
13136
13209
  import { randomUUID as randomUUID2 } from "node:crypto";
13137
- import fs10 from "node:fs";
13138
- import path14 from "node:path";
13210
+ import fs11 from "node:fs";
13211
+ import path15 from "node:path";
13139
13212
  function readLog(file, from = 0, expectSeq = null) {
13140
13213
  let fd;
13141
13214
  try {
13142
- fd = fs10.openSync(file, "r");
13215
+ fd = fs11.openSync(file, "r");
13143
13216
  } catch (error) {
13144
13217
  if (error.code === "ENOENT")
13145
13218
  return null;
@@ -13148,13 +13221,13 @@ function readLog(file, from = 0, expectSeq = null) {
13148
13221
  let bytes;
13149
13222
  let size;
13150
13223
  try {
13151
- size = fs10.fstatSync(fd).size;
13224
+ size = fs11.fstatSync(fd).size;
13152
13225
  if (from > size)
13153
13226
  throw new LogDamage(`${file}: shorter than its snapshot`);
13154
13227
  bytes = Buffer.alloc(size - from);
13155
13228
  let read = 0;
13156
13229
  while (read < bytes.length) {
13157
- const got = fs10.readSync(fd, bytes, read, bytes.length - read, from + read);
13230
+ const got = fs11.readSync(fd, bytes, read, bytes.length - read, from + read);
13158
13231
  if (got === 0)
13159
13232
  break;
13160
13233
  read += got;
@@ -13162,7 +13235,7 @@ function readLog(file, from = 0, expectSeq = null) {
13162
13235
  bytes = bytes.subarray(0, read);
13163
13236
  size = from + read;
13164
13237
  } finally {
13165
- fs10.closeSync(fd);
13238
+ fs11.closeSync(fd);
13166
13239
  }
13167
13240
  const events = [];
13168
13241
  let start = 0;
@@ -13188,46 +13261,46 @@ function readLog(file, from = 0, expectSeq = null) {
13188
13261
  function appendEvent(file, event, validEnd) {
13189
13262
  const line = Buffer.from(`${JSON.stringify(event)}
13190
13263
  `, "utf8");
13191
- const created = !fs10.existsSync(file);
13192
- if (!created && fs10.statSync(file).size !== validEnd) {
13193
- const cut = fs10.openSync(file, "r+");
13264
+ const created = !fs11.existsSync(file);
13265
+ if (!created && fs11.statSync(file).size !== validEnd) {
13266
+ const cut = fs11.openSync(file, "r+");
13194
13267
  try {
13195
- fs10.ftruncateSync(cut, validEnd);
13196
- fs10.fsyncSync(cut);
13268
+ fs11.ftruncateSync(cut, validEnd);
13269
+ fs11.fsyncSync(cut);
13197
13270
  } finally {
13198
- fs10.closeSync(cut);
13271
+ fs11.closeSync(cut);
13199
13272
  }
13200
13273
  }
13201
- const fd = fs10.openSync(file, "a", 384);
13274
+ const fd = fs11.openSync(file, "a", 384);
13202
13275
  try {
13203
13276
  let written = 0;
13204
13277
  while (written < line.length)
13205
- written += fs10.writeSync(fd, line, written, line.length - written);
13206
- fs10.fsyncSync(fd);
13278
+ written += fs11.writeSync(fd, line, written, line.length - written);
13279
+ fs11.fsyncSync(fd);
13207
13280
  } finally {
13208
- fs10.closeSync(fd);
13281
+ fs11.closeSync(fd);
13209
13282
  }
13210
13283
  if (created)
13211
- fsyncDirectory(path14.dirname(file));
13284
+ fsyncDirectory(path15.dirname(file));
13212
13285
  return validEnd;
13213
13286
  }
13214
13287
  function replaceFile(file, bytes, durable) {
13215
13288
  const temporary = `${file}.${process.pid}.${randomUUID2()}.tmp`;
13216
13289
  try {
13217
- const fd = fs10.openSync(temporary, "wx", 384);
13290
+ const fd = fs11.openSync(temporary, "wx", 384);
13218
13291
  try {
13219
- fs10.writeSync(fd, bytes);
13292
+ fs11.writeSync(fd, bytes);
13220
13293
  if (durable)
13221
- fs10.fsyncSync(fd);
13294
+ fs11.fsyncSync(fd);
13222
13295
  } finally {
13223
- fs10.closeSync(fd);
13296
+ fs11.closeSync(fd);
13224
13297
  }
13225
13298
  renameWithRetry(temporary, file);
13226
13299
  if (durable)
13227
- fsyncDirectory(path14.dirname(file));
13300
+ fsyncDirectory(path15.dirname(file));
13228
13301
  } catch (error) {
13229
13302
  try {
13230
- fs10.unlinkSync(temporary);
13303
+ fs11.unlinkSync(temporary);
13231
13304
  } catch {}
13232
13305
  throw error;
13233
13306
  }
@@ -13248,11 +13321,11 @@ var EVENT_VERSION = 1, LogDamage, isObject4 = (value) => typeof value === "objec
13248
13321
  return value;
13249
13322
  }, fsyncDirectory = (dir) => {
13250
13323
  try {
13251
- const fd = fs10.openSync(dir, "r");
13324
+ const fd = fs11.openSync(dir, "r");
13252
13325
  try {
13253
- fs10.fsyncSync(fd);
13326
+ fs11.fsyncSync(fd);
13254
13327
  } finally {
13255
- fs10.closeSync(fd);
13328
+ fs11.closeSync(fd);
13256
13329
  }
13257
13330
  } catch (error) {
13258
13331
  if (process.platform !== "win32")
@@ -13275,7 +13348,7 @@ var EVENT_VERSION = 1, LogDamage, isObject4 = (value) => typeof value === "objec
13275
13348
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 5 * (attempt + 1));
13276
13349
  }
13277
13350
  }
13278
- }, renameWithRetry = (from, to) => retryTransient(() => fs10.renameSync(from, to));
13351
+ }, renameWithRetry = (from, to) => retryTransient(() => fs11.renameSync(from, to));
13279
13352
  var init_event_log = __esm(() => {
13280
13353
  LogDamage = class LogDamage extends Error {
13281
13354
  upgrade;
@@ -13394,7 +13467,7 @@ var isPlainObject2 = (value) => typeof value === "object" && value !== null && !
13394
13467
  });
13395
13468
 
13396
13469
  // packages/workit-core/src/store/reduce.ts
13397
- import { createHash as createHash9 } from "node:crypto";
13470
+ import { createHash as createHash10 } from "node:crypto";
13398
13471
  function reduce(state, event, blobs) {
13399
13472
  const data = event.data;
13400
13473
  const known = KNOWN_TYPES.has(event.type);
@@ -13461,7 +13534,7 @@ function eventType(before, after) {
13461
13534
  return "task.noted";
13462
13535
  return "task.updated";
13463
13536
  }
13464
- var OPENING_TYPES, KNOWN_TYPES, isObject5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), isKey = (value) => isObject5(value) && typeof value.key === "string" && (value.kind === "branch" || value.kind === "detached" || value.kind === "dir") && (value.branch === null || typeof value.branch === "string"), BLOB_REF = "$blob", blobRef = (value) => isObject5(value) && Object.keys(value).length === 1 && typeof value[BLOB_REF] === "string" && /^[0-9a-f]{64}$/.test(value[BLOB_REF]) ? value[BLOB_REF] : null, blobDigest = (value) => createHash9("sha256").update(JSON.stringify(value)).digest("hex"), toBlob = (value, blobs) => {
13537
+ var OPENING_TYPES, KNOWN_TYPES, isObject5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), isKey = (value) => isObject5(value) && typeof value.key === "string" && (value.kind === "branch" || value.kind === "detached" || value.kind === "dir") && (value.branch === null || typeof value.branch === "string"), BLOB_REF = "$blob", blobRef = (value) => isObject5(value) && Object.keys(value).length === 1 && typeof value[BLOB_REF] === "string" && /^[0-9a-f]{64}$/.test(value[BLOB_REF]) ? value[BLOB_REF] : null, blobDigest = (value) => createHash10("sha256").update(JSON.stringify(value)).digest("hex"), toBlob = (value, blobs) => {
13465
13538
  if (!isObject5(value))
13466
13539
  return value;
13467
13540
  const digest = blobDigest(value);
@@ -13532,9 +13605,9 @@ var init_notes = __esm(() => {
13532
13605
  });
13533
13606
 
13534
13607
  // packages/workit-core/src/core/task-store.ts
13535
- import { createHash as createHash10, randomUUID as randomUUID3 } from "node:crypto";
13536
- import * as fs11 from "node:fs";
13537
- import path15 from "node:path";
13608
+ import { createHash as createHash11, randomUUID as randomUUID3 } from "node:crypto";
13609
+ import * as fs12 from "node:fs";
13610
+ import path16 from "node:path";
13538
13611
 
13539
13612
  class TaskStore {
13540
13613
  root;
@@ -13546,8 +13619,8 @@ class TaskStore {
13546
13619
  migrationChecked = false;
13547
13620
  compactDue = new Set;
13548
13621
  constructor(root, options = {}) {
13549
- const resolved = path15.resolve(root);
13550
- this.origin = fs11.existsSync(resolved) ? fs11.realpathSync(resolved) : resolved;
13622
+ const resolved = path16.resolve(root);
13623
+ this.origin = fs12.existsSync(resolved) ? fs12.realpathSync(resolved) : resolved;
13551
13624
  this.located = resolveStore(this.origin);
13552
13625
  this.root = checkoutRootOf(this.origin, this.located);
13553
13626
  this.lockTimeoutMs = options.lockTimeoutMs ?? defaultLockTimeout();
@@ -13555,7 +13628,7 @@ class TaskStore {
13555
13628
  this.migrateOnRead = options.migrateOnRead;
13556
13629
  }
13557
13630
  location() {
13558
- if (this.located !== undefined && !(this.located instanceof Error) && !this.located.shared && fs11.existsSync(path15.join(this.root, ".git"))) {
13631
+ if (this.located !== undefined && !(this.located instanceof Error) && !this.located.shared && fs12.existsSync(path16.join(this.root, ".git"))) {
13559
13632
  this.located = undefined;
13560
13633
  this.migrationChecked = false;
13561
13634
  }
@@ -13619,7 +13692,7 @@ class TaskStore {
13619
13692
  const tasksDir = this.paths().tasks;
13620
13693
  let names;
13621
13694
  try {
13622
- names = fs11.existsSync(tasksDir) ? fs11.readdirSync(tasksDir).filter((name) => validId(name)) : [];
13695
+ names = fs12.existsSync(tasksDir) ? fs12.readdirSync(tasksDir).filter((name) => validId(name)) : [];
13623
13696
  } catch (error) {
13624
13697
  return failure2("storage_error", `unable to list tasks: ${String(error)}`, {
13625
13698
  path: tasksDir
@@ -13660,7 +13733,7 @@ class TaskStore {
13660
13733
  const file = this.paths().workspace;
13661
13734
  let bytes;
13662
13735
  try {
13663
- bytes = retryTransient(() => fs11.readFileSync(file, "utf8"));
13736
+ bytes = retryTransient(() => fs12.readFileSync(file, "utf8"));
13664
13737
  } catch (error) {
13665
13738
  if (error.code === "ENOENT")
13666
13739
  return success(null, null, null);
@@ -13711,7 +13784,7 @@ class TaskStore {
13711
13784
  const moved = this.bindLocked(again.data.id, key, input.now);
13712
13785
  return moved.ok ? success(moved.data.revision, null, { task: moved.data, created: false, key }) : moved;
13713
13786
  }
13714
- const label = key.kind === "branch" ? `branch ${key.branch}` : key.kind === "detached" ? "a detached HEAD" : path15.basename(this.root) || this.root;
13787
+ const label = key.kind === "branch" ? `branch ${key.branch}` : key.kind === "detached" ? "a detached HEAD" : path16.basename(this.root) || this.root;
13715
13788
  const intent = {
13716
13789
  objective: input.objective?.trim() || `Work on ${label}`,
13717
13790
  scope: { description: `the checkout (${label})`, paths: ["."], exclusions: [] },
@@ -13777,14 +13850,14 @@ class TaskStore {
13777
13850
  const branch = key.ok ? key.data.branch : null;
13778
13851
  if (!branch || !location.ok)
13779
13852
  return success(null, null, null);
13780
- const common = path15.dirname(location.data.dir);
13781
- const heads = path15.join(common, "logs", "refs", "heads");
13782
- const headLog = location.data.git ? path15.join(location.data.git.gitDir, "logs", "HEAD") : "";
13853
+ const common = path16.dirname(location.data.dir);
13854
+ const heads = path16.join(common, "logs", "refs", "heads");
13855
+ const headLog = location.data.git ? path16.join(location.data.git.gitDir, "logs", "HEAD") : "";
13783
13856
  const signatures = [
13784
- path15.join(heads, branch),
13857
+ path16.join(heads, branch),
13785
13858
  headLog,
13786
13859
  heads,
13787
- path15.join(common, "packed-refs")
13860
+ path16.join(common, "packed-refs")
13788
13861
  ].map((file) => fileSignature(file) ?? "-");
13789
13862
  const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
13790
13863
  let resolved = origins.get(slot);
@@ -13796,7 +13869,7 @@ class TaskStore {
13796
13869
  aliases.push(rename.from);
13797
13870
  const start = branchStart(location.data, branch, aliases);
13798
13871
  const slash = start?.indexOf("/") ?? -1;
13799
- const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(path15.join(common, "config")).includes(`[remote "${start.slice(0, slash)}"]`));
13872
+ const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(path16.join(common, "config")).includes(`[remote "${start.slice(0, slash)}"]`));
13800
13873
  const name = start && (remote ? start.slice(slash + 1) : start);
13801
13874
  resolved = {
13802
13875
  signature: signatures.join("|"),
@@ -14034,13 +14107,13 @@ class TaskStore {
14034
14107
  if (!ready.ok)
14035
14108
  return ready;
14036
14109
  const dirs = this.paths();
14037
- const recovery = path15.join(this.root, ".workit", "recovery");
14038
- if (fs11.existsSync(recovery)) {
14110
+ const recovery = path16.join(this.root, ".workit", "recovery");
14111
+ if (fs12.existsSync(recovery)) {
14039
14112
  let files = 0;
14040
14113
  let bytes = 0;
14041
14114
  try {
14042
- for (const name of fs11.readdirSync(recovery)) {
14043
- const stat = fs11.lstatSync(path15.join(recovery, name));
14115
+ for (const name of fs12.readdirSync(recovery)) {
14116
+ const stat = fs12.lstatSync(path16.join(recovery, name));
14044
14117
  if (!stat.isFile())
14045
14118
  continue;
14046
14119
  files += 1;
@@ -14049,17 +14122,17 @@ class TaskStore {
14049
14122
  } catch {}
14050
14123
  const remove = options.pruneRecovery === true && !dryRun;
14051
14124
  if (remove)
14052
- fs11.rmSync(recovery, { recursive: true, force: true });
14125
+ fs12.rmSync(recovery, { recursive: true, force: true });
14053
14126
  report.legacyRecovery = { path: recovery, files, bytes, removed: remove };
14054
14127
  }
14055
- if (!fs11.existsSync(dirs.tasks))
14128
+ if (!fs12.existsSync(dirs.tasks))
14056
14129
  return success(null, null, report);
14057
- const names = fs11.readdirSync(dirs.tasks).filter((name) => validId(name));
14130
+ const names = fs12.readdirSync(dirs.tasks).filter((name) => validId(name));
14058
14131
  for (const name of names) {
14059
14132
  const file = this.eventsPath(name);
14060
14133
  let size = 0;
14061
14134
  try {
14062
- size = fs11.statSync(file).size;
14135
+ size = fs12.statSync(file).size;
14063
14136
  } catch {
14064
14137
  continue;
14065
14138
  }
@@ -14087,16 +14160,16 @@ class TaskStore {
14087
14160
  const references = new Set;
14088
14161
  for (const name of names)
14089
14162
  try {
14090
- for (const match of fs11.readFileSync(this.eventsPath(name), "utf8").matchAll(/"\$blob":"([0-9a-f]{64})"/g))
14163
+ for (const match of fs12.readFileSync(this.eventsPath(name), "utf8").matchAll(/"\$blob":"([0-9a-f]{64})"/g))
14091
14164
  references.add(match[1]);
14092
14165
  } catch {}
14093
- if (fs11.existsSync(dirs.blobs))
14094
- for (const name of fs11.readdirSync(dirs.blobs)) {
14166
+ if (fs12.existsSync(dirs.blobs))
14167
+ for (const name of fs12.readdirSync(dirs.blobs)) {
14095
14168
  const digest = name.replace(/\.json$/, "");
14096
- const file = path15.join(dirs.blobs, name);
14169
+ const file = path16.join(dirs.blobs, name);
14097
14170
  let stat;
14098
14171
  try {
14099
- stat = fs11.lstatSync(file);
14172
+ stat = fs12.lstatSync(file);
14100
14173
  } catch {
14101
14174
  continue;
14102
14175
  }
@@ -14107,11 +14180,11 @@ class TaskStore {
14107
14180
  report.blobs.removed += 1;
14108
14181
  report.blobs.removedBytes += stat.size;
14109
14182
  if (!dryRun)
14110
- fs11.rmSync(file, { force: true });
14183
+ fs12.rmSync(file, { force: true });
14111
14184
  }
14112
14185
  return success(null, null, null);
14113
14186
  };
14114
- const swept = dryRun ? sweep() : this.withLock(path15.join(dirs.dir, "gc.lock"), sweep);
14187
+ const swept = dryRun ? sweep() : this.withLock(path16.join(dirs.dir, "gc.lock"), sweep);
14115
14188
  if (!swept.ok)
14116
14189
  return swept;
14117
14190
  const temporaryDirs = [
@@ -14119,17 +14192,17 @@ class TaskStore {
14119
14192
  dirs.tasks,
14120
14193
  dirs.blobs,
14121
14194
  dirs.checkout,
14122
- ...names.map((name) => path15.join(dirs.tasks, name))
14195
+ ...names.map((name) => path16.join(dirs.tasks, name))
14123
14196
  ];
14124
14197
  for (const directory of temporaryDirs) {
14125
- if (!fs11.existsSync(directory))
14198
+ if (!fs12.existsSync(directory))
14126
14199
  continue;
14127
- for (const name of fs11.readdirSync(directory)) {
14200
+ for (const name of fs12.readdirSync(directory)) {
14128
14201
  if (!name.endsWith(".tmp") && !name.endsWith(".probe"))
14129
14202
  continue;
14130
- const file = path15.join(directory, name);
14203
+ const file = path16.join(directory, name);
14131
14204
  try {
14132
- const stat = fs11.lstatSync(file);
14205
+ const stat = fs12.lstatSync(file);
14133
14206
  if (!stat.isFile() || nowMs - stat.mtimeMs <= STALE_TEMPORARY_MS)
14134
14207
  continue;
14135
14208
  } catch {
@@ -14137,37 +14210,37 @@ class TaskStore {
14137
14210
  }
14138
14211
  report.temporary.removed += 1;
14139
14212
  if (!dryRun)
14140
- fs11.rmSync(file, { force: true });
14213
+ fs12.rmSync(file, { force: true });
14141
14214
  }
14142
14215
  }
14143
14216
  return success(null, null, report);
14144
14217
  }
14145
14218
  paths() {
14146
14219
  const location = this.location();
14147
- const dir = location.ok ? location.data.dir : path15.join(this.root, ".workit");
14148
- const checkout = path15.join(dir, "checkouts", checkoutSlug(this.root));
14220
+ const dir = location.ok ? location.data.dir : path16.join(this.root, ".workit");
14221
+ const checkout = path16.join(dir, "checkouts", checkoutSlug(this.root));
14149
14222
  return {
14150
14223
  dir,
14151
14224
  shared: location.ok ? location.data.shared : false,
14152
- marker: path15.join(dir, "store.json"),
14225
+ marker: path16.join(dir, "store.json"),
14153
14226
  checkout,
14154
- workspace: path15.join(checkout, "workspace.json"),
14155
- checkoutLock: path15.join(checkout, "metadata.lock"),
14156
- tasks: path15.join(dir, "tasks"),
14157
- index: path15.join(dir, "task-index.json"),
14158
- blobs: path15.join(dir, "blobs", "candidates"),
14159
- legacy: path15.join(dir, "legacy", checkoutSlug(this.root), "v2"),
14160
- v2: path15.join(this.root, ".workit")
14227
+ workspace: path16.join(checkout, "workspace.json"),
14228
+ checkoutLock: path16.join(checkout, "metadata.lock"),
14229
+ tasks: path16.join(dir, "tasks"),
14230
+ index: path16.join(dir, "task-index.json"),
14231
+ blobs: path16.join(dir, "blobs", "candidates"),
14232
+ legacy: path16.join(dir, "legacy", checkoutSlug(this.root), "v2"),
14233
+ v2: path16.join(this.root, ".workit")
14161
14234
  };
14162
14235
  }
14163
14236
  eventsPath(taskId) {
14164
- return path15.join(this.paths().tasks, taskId, "events.jsonl");
14237
+ return path16.join(this.paths().tasks, taskId, "events.jsonl");
14165
14238
  }
14166
14239
  snapshotPath(taskId) {
14167
- return path15.join(this.paths().tasks, taskId, "snapshot.json");
14240
+ return path16.join(this.paths().tasks, taskId, "snapshot.json");
14168
14241
  }
14169
14242
  taskLockPath(taskId) {
14170
- return path15.join(this.paths().tasks, taskId, "lock");
14243
+ return path16.join(this.paths().tasks, taskId, "lock");
14171
14244
  }
14172
14245
  ready(write = false) {
14173
14246
  const location = this.location();
@@ -14177,7 +14250,7 @@ class TaskStore {
14177
14250
  return success(null, null, null);
14178
14251
  const dirs = this.paths();
14179
14252
  try {
14180
- const marker = JSON.parse(fs11.readFileSync(dirs.marker, "utf8"));
14253
+ const marker = JSON.parse(fs12.readFileSync(dirs.marker, "utf8"));
14181
14254
  if (typeof marker.version === "number" && marker.version > STORE_FORMAT)
14182
14255
  return failure2("recovery_required", `the workit store at ${dirs.dir} has format ${marker.version}; upgrade Workit to use it`, { path: dirs.marker });
14183
14256
  } catch {}
@@ -14206,21 +14279,21 @@ class TaskStore {
14206
14279
  return {
14207
14280
  read: (digest) => {
14208
14281
  try {
14209
- return JSON.parse(fs11.readFileSync(path15.join(dir, `${digest}.json`), "utf8"));
14282
+ return JSON.parse(fs12.readFileSync(path16.join(dir, `${digest}.json`), "utf8"));
14210
14283
  } catch (error) {
14211
14284
  throw new LogDamage(`stored candidate ${digest} is missing or unreadable: ${String(error)}`);
14212
14285
  }
14213
14286
  },
14214
14287
  write: (digest, value) => {
14215
- const file = path15.join(dir, `${digest}.json`);
14216
- if (fs11.existsSync(file)) {
14288
+ const file = path16.join(dir, `${digest}.json`);
14289
+ if (fs12.existsSync(file)) {
14217
14290
  const stamp = new Date;
14218
14291
  try {
14219
- fs11.utimesSync(file, stamp, stamp);
14292
+ fs12.utimesSync(file, stamp, stamp);
14220
14293
  return;
14221
14294
  } catch {}
14222
14295
  }
14223
- fs11.mkdirSync(dir, { recursive: true });
14296
+ fs12.mkdirSync(dir, { recursive: true });
14224
14297
  replaceFile(file, JSON.stringify(value), true);
14225
14298
  }
14226
14299
  };
@@ -14302,7 +14375,7 @@ class TaskStore {
14302
14375
  }
14303
14376
  readSnapshot(taskId) {
14304
14377
  try {
14305
- const value = JSON.parse(fs11.readFileSync(this.snapshotPath(taskId), "utf8"));
14378
+ const value = JSON.parse(fs12.readFileSync(this.snapshotPath(taskId), "utf8"));
14306
14379
  if (!isObject6(value) || value.v !== 1 || value.task !== taskId || typeof value.seq !== "number" || typeof value.lastId !== "string" || typeof value.lastStart !== "number" || typeof value.end !== "number" || !isObject6(value.record))
14307
14380
  return null;
14308
14381
  return value;
@@ -14404,8 +14477,8 @@ class TaskStore {
14404
14477
  }
14405
14478
  }
14406
14479
  openTask(record, type, key, legacy = null) {
14407
- const dir = path15.join(this.paths().tasks, record.id);
14408
- fs11.mkdirSync(dir, { recursive: true });
14480
+ const dir = path16.join(this.paths().tasks, record.id);
14481
+ fs12.mkdirSync(dir, { recursive: true });
14409
14482
  const blobs = this.blobStore();
14410
14483
  const bound = key ? { ...key, boundAt: key.boundAt ?? new Date().toISOString() } : null;
14411
14484
  const event = this.event(record.id, 1, type, {
@@ -14457,11 +14530,11 @@ class TaskStore {
14457
14530
  } catch {}
14458
14531
  if (!latest || latest.events[0]?.id !== last.id)
14459
14532
  return failure2("busy", "the task log changed during compaction; retry", { taskId });
14460
- const appended = fs11.readFileSync(file).subarray(log.end, latest.end);
14533
+ const appended = fs12.readFileSync(file).subarray(log.end, latest.end);
14461
14534
  const bytes = Buffer.concat([Buffer.from(prefix, "utf8"), appended]);
14462
14535
  replaceFile(file, bytes.toString("utf8"), true);
14463
14536
  try {
14464
- fs11.rmSync(this.snapshotPath(taskId), { force: true });
14537
+ fs12.rmSync(this.snapshotPath(taskId), { force: true });
14465
14538
  } catch {}
14466
14539
  const reloaded = this.load(taskId);
14467
14540
  if (reloaded.ok && reloaded.data)
@@ -14474,7 +14547,7 @@ class TaskStore {
14474
14547
  }
14475
14548
  countEvents(file) {
14476
14549
  try {
14477
- const bytes = fs11.readFileSync(file);
14550
+ const bytes = fs12.readFileSync(file);
14478
14551
  let count = 0;
14479
14552
  for (let index = bytes.indexOf(10);index >= 0; index = bytes.indexOf(10, index + 1))
14480
14553
  count += 1;
@@ -14496,8 +14569,8 @@ class TaskStore {
14496
14569
  return bound.ok ? success(null, null, bound.data[0] ?? null) : bound;
14497
14570
  }
14498
14571
  withKeyLock(key, operation) {
14499
- const digest = createHash10("sha256").update(key).digest("hex").slice(0, 32);
14500
- return this.withLock(path15.join(this.paths().dir, "keys", `${digest}.lock`), operation);
14572
+ const digest = createHash11("sha256").update(key).digest("hex").slice(0, 32);
14573
+ return this.withLock(path16.join(this.paths().dir, "keys", `${digest}.lock`), operation);
14501
14574
  }
14502
14575
  bindLocked(taskId, key, timestamp) {
14503
14576
  const current = this.readWorkspace();
@@ -14638,7 +14711,7 @@ class TaskStore {
14638
14711
  writeWorkspace(record) {
14639
14712
  const file = this.paths().workspace;
14640
14713
  try {
14641
- fs11.mkdirSync(path15.dirname(file), { recursive: true });
14714
+ fs12.mkdirSync(path16.dirname(file), { recursive: true });
14642
14715
  replaceFile(file, `${canonicalJson(record)}
14643
14716
  `, true);
14644
14717
  return success(null, null, null);
@@ -14648,7 +14721,7 @@ class TaskStore {
14648
14721
  }
14649
14722
  readIndex() {
14650
14723
  try {
14651
- const value = JSON.parse(fs11.readFileSync(this.paths().index, "utf8"));
14724
+ const value = JSON.parse(fs12.readFileSync(this.paths().index, "utf8"));
14652
14725
  if (!isObject6(value) || value.version !== INDEX_VERSION || !isObject6(value.tasks))
14653
14726
  return {};
14654
14727
  const tasks = {};
@@ -14662,7 +14735,7 @@ class TaskStore {
14662
14735
  }
14663
14736
  writeIndex(entries) {
14664
14737
  try {
14665
- fs11.mkdirSync(this.paths().tasks, { recursive: true });
14738
+ fs12.mkdirSync(this.paths().tasks, { recursive: true });
14666
14739
  replaceFile(this.paths().index, JSON.stringify({
14667
14740
  version: INDEX_VERSION,
14668
14741
  tasks: Object.fromEntries(entries.map((entry) => [entry.id, entry]))
@@ -14716,23 +14789,23 @@ class TaskStore {
14716
14789
  return failure2("revision_conflict", "workspace revision does not match; omit expectedWorkspaceRevision to use the current record", { expectedWorkspaceRevision: expected, actualWorkspaceRevision: actual });
14717
14790
  }
14718
14791
  v2Dirs() {
14719
- return [...new Set([this.root, this.origin])].map((dir) => path15.join(dir, ".workit"));
14792
+ return [...new Set([this.root, this.origin])].map((dir) => path16.join(dir, ".workit"));
14720
14793
  }
14721
14794
  pendingMigrations() {
14722
14795
  return this.v2Dirs().filter((dir) => {
14723
- const raw = this.readV2Workspace(path15.join(dir, "workspace.json"));
14796
+ const raw = this.readV2Workspace(path16.join(dir, "workspace.json"));
14724
14797
  return raw !== null && raw !== TOMBSTONE;
14725
14798
  });
14726
14799
  }
14727
14800
  migrateV2(v2) {
14728
14801
  const dirs = this.paths();
14729
- const v2Workspace = path15.join(v2, "workspace.json");
14730
- const v2Tasks = path15.join(v2, "tasks");
14731
- const legacy = path15.join(dirs.dir, "legacy", checkoutSlug(path15.dirname(v2)), "v2");
14802
+ const v2Workspace = path16.join(v2, "workspace.json");
14803
+ const v2Tasks = path16.join(v2, "tasks");
14804
+ const legacy = path16.join(dirs.dir, "legacy", checkoutSlug(path16.dirname(v2)), "v2");
14732
14805
  const raw = this.readV2Workspace(v2Workspace);
14733
14806
  if (raw === null || raw === TOMBSTONE)
14734
14807
  return success(null, null, null);
14735
- return this.withLock(dirs.checkoutLock, () => this.withLock(path15.join(v2, "metadata.lock"), () => {
14808
+ return this.withLock(dirs.checkoutLock, () => this.withLock(path16.join(v2, "metadata.lock"), () => {
14736
14809
  const workspace = this.readV2Workspace(v2Workspace);
14737
14810
  if (workspace === null || workspace === TOMBSTONE)
14738
14811
  return success(null, null, null);
@@ -14741,7 +14814,7 @@ class TaskStore {
14741
14814
  return failure2("recovery_required", `cannot migrate the 2.x store at ${v2}: ${parsedWorkspace.error}; move it aside to start fresh`, { path: v2Workspace });
14742
14815
  let files = [];
14743
14816
  try {
14744
- files = fs11.readdirSync(v2Tasks).filter((name) => name.endsWith(".json") && validId(name.slice(0, -5))).filter((name) => !this.isStub(path15.join(v2Tasks, name)));
14817
+ files = fs12.readdirSync(v2Tasks).filter((name) => name.endsWith(".json") && validId(name.slice(0, -5))).filter((name) => !this.isStub(path16.join(v2Tasks, name)));
14745
14818
  } catch {}
14746
14819
  const current = this.readWorkspace();
14747
14820
  if (!current.ok)
@@ -14759,22 +14832,22 @@ class TaskStore {
14759
14832
  let skipped = 0;
14760
14833
  const done = new Map;
14761
14834
  try {
14762
- fs11.mkdirSync(path15.join(legacy, "tasks"), { recursive: true });
14835
+ fs12.mkdirSync(path16.join(legacy, "tasks"), { recursive: true });
14763
14836
  for (const name of ["workspace.json", "index.json"])
14764
- if (fs11.existsSync(path15.join(v2, name)))
14765
- fs11.copyFileSync(path15.join(v2, name), path15.join(legacy, name));
14837
+ if (fs12.existsSync(path16.join(v2, name)))
14838
+ fs12.copyFileSync(path16.join(v2, name), path16.join(legacy, name));
14766
14839
  for (const name of files) {
14767
14840
  const id = name.slice(0, -5);
14768
- const file = path15.join(v2Tasks, name);
14769
- const bytes = fs11.readFileSync(file, "utf8");
14841
+ const file = path16.join(v2Tasks, name);
14842
+ const bytes = fs12.readFileSync(file, "utf8");
14770
14843
  const digest = sha256(bytes);
14771
- fs11.writeFileSync(path15.join(legacy, "tasks", name), bytes);
14844
+ fs12.writeFileSync(path16.join(legacy, "tasks", name), bytes);
14772
14845
  const parsed = this.parseRecord(bytes, taskRecordSchema, "2.x task");
14773
14846
  if (!parsed.ok || parsed.data.id !== id)
14774
14847
  return failure2("recovery_required", `cannot migrate 2.x task ${id}: ${parsed.ok ? "file name and record ID differ" : parsed.error}; move ${file} aside to continue`, { path: file });
14775
14848
  const record = { ...parsed.data, workspaceId: target.id };
14776
- const origin = { path: path15.join(legacy, "tasks", name), digest };
14777
- if (!fs11.existsSync(this.eventsPath(id))) {
14849
+ const origin = { path: path16.join(legacy, "tasks", name), digest };
14850
+ if (!fs12.existsSync(this.eventsPath(id))) {
14778
14851
  this.openTask(record, "migrated.from_v2", null, origin);
14779
14852
  migrated += 1;
14780
14853
  } else {
@@ -14809,8 +14882,8 @@ class TaskStore {
14809
14882
  try {
14810
14883
  let complete = true;
14811
14884
  for (const [name, digest] of done) {
14812
- const file = path15.join(v2Tasks, name);
14813
- if (sha256(fs11.readFileSync(file, "utf8")) !== digest) {
14885
+ const file = path16.join(v2Tasks, name);
14886
+ if (sha256(fs12.readFileSync(file, "utf8")) !== digest) {
14814
14887
  complete = false;
14815
14888
  continue;
14816
14889
  }
@@ -14820,7 +14893,7 @@ class TaskStore {
14820
14893
  return failure2("busy", `the 2.x store at ${v2} changed during migration; retry`, {
14821
14894
  path: v2
14822
14895
  });
14823
- fs11.rmSync(path15.join(v2, "index.json"), { force: true });
14896
+ fs12.rmSync(path16.join(v2, "index.json"), { force: true });
14824
14897
  this.writeTombstone(v2, target.id);
14825
14898
  } catch (error) {
14826
14899
  return failure2("storage_error", `cannot finish the 2.x migration: ${String(error)}`, {
@@ -14840,45 +14913,45 @@ class TaskStore {
14840
14913
  }
14841
14914
  adoptLocalStore() {
14842
14915
  const dirs = this.paths();
14843
- const marker = path15.join(dirs.v2, "store.json");
14844
- if (!dirs.shared || !fs11.existsSync(marker))
14916
+ const marker = path16.join(dirs.v2, "store.json");
14917
+ if (!dirs.shared || !fs12.existsSync(marker))
14845
14918
  return success(null, null, null);
14846
14919
  return this.withLock(dirs.checkoutLock, () => {
14847
- if (!fs11.existsSync(marker))
14920
+ if (!fs12.existsSync(marker))
14848
14921
  return success(null, null, null);
14849
14922
  let tasks = 0;
14850
14923
  try {
14851
14924
  const merge = (from, to) => {
14852
- if (!fs11.existsSync(to)) {
14853
- fs11.mkdirSync(path15.dirname(to), { recursive: true });
14925
+ if (!fs12.existsSync(to)) {
14926
+ fs12.mkdirSync(path16.dirname(to), { recursive: true });
14854
14927
  try {
14855
- fs11.renameSync(from, to);
14928
+ fs12.renameSync(from, to);
14856
14929
  } catch {
14857
- fs11.cpSync(from, to, { recursive: true, errorOnExist: true, force: false });
14858
- fs11.rmSync(from, { recursive: true, force: true });
14930
+ fs12.cpSync(from, to, { recursive: true, errorOnExist: true, force: false });
14931
+ fs12.rmSync(from, { recursive: true, force: true });
14859
14932
  }
14860
14933
  return;
14861
14934
  }
14862
- if (fs11.lstatSync(from).isDirectory() && fs11.lstatSync(to).isDirectory())
14863
- for (const name of fs11.readdirSync(from))
14864
- merge(path15.join(from, name), path15.join(to, name));
14935
+ if (fs12.lstatSync(from).isDirectory() && fs12.lstatSync(to).isDirectory())
14936
+ for (const name of fs12.readdirSync(from))
14937
+ merge(path16.join(from, name), path16.join(to, name));
14865
14938
  };
14866
14939
  for (const sub of ["tasks", "checkouts", "blobs", "legacy"]) {
14867
- const from = path15.join(dirs.v2, sub);
14868
- if (!fs11.existsSync(from))
14940
+ const from = path16.join(dirs.v2, sub);
14941
+ if (!fs12.existsSync(from))
14869
14942
  continue;
14870
14943
  if (sub === "tasks") {
14871
- for (const name of fs11.readdirSync(from))
14872
- if (validId(name) && !fs11.existsSync(path15.join(dirs.dir, sub, name)))
14944
+ for (const name of fs12.readdirSync(from))
14945
+ if (validId(name) && !fs12.existsSync(path16.join(dirs.dir, sub, name)))
14873
14946
  tasks += 1;
14874
14947
  }
14875
- merge(from, path15.join(dirs.dir, sub));
14948
+ merge(from, path16.join(dirs.dir, sub));
14876
14949
  }
14877
- const ledger = path15.join(dirs.v2, "ledger");
14878
- if (fs11.existsSync(ledger) && !fs11.existsSync(path15.join(dirs.dir, "ledger")))
14879
- merge(ledger, path15.join(dirs.dir, "ledger"));
14880
- fs11.rmSync(path15.join(dirs.v2, "task-index.json"), { force: true });
14881
- fs11.renameSync(marker, path15.join(dirs.v2, "store.moved.json"));
14950
+ const ledger = path16.join(dirs.v2, "ledger");
14951
+ if (fs12.existsSync(ledger) && !fs12.existsSync(path16.join(dirs.dir, "ledger")))
14952
+ merge(ledger, path16.join(dirs.dir, "ledger"));
14953
+ fs12.rmSync(path16.join(dirs.v2, "task-index.json"), { force: true });
14954
+ fs12.renameSync(marker, path16.join(dirs.v2, "store.moved.json"));
14882
14955
  } catch (error) {
14883
14956
  return failure2("storage_error", `cannot move ${dirs.v2} into ${dirs.dir}: ${String(error)}`, {
14884
14957
  path: dirs.v2
@@ -14898,7 +14971,7 @@ class TaskStore {
14898
14971
  readV2Workspace(file) {
14899
14972
  let bytes;
14900
14973
  try {
14901
- bytes = fs11.readFileSync(file, "utf8");
14974
+ bytes = fs12.readFileSync(file, "utf8");
14902
14975
  } catch {
14903
14976
  return null;
14904
14977
  }
@@ -14916,7 +14989,7 @@ class TaskStore {
14916
14989
  schemaVersion: SCHEMA_VERSION,
14917
14990
  id: workspaceId ?? newId(),
14918
14991
  revision: newRevision(),
14919
- root: path15.dirname(v2),
14992
+ root: path16.dirname(v2),
14920
14993
  runtime: { createdWith: version, updatedWith: version },
14921
14994
  writer: null,
14922
14995
  store: {
@@ -14927,12 +15000,12 @@ class TaskStore {
14927
15000
  },
14928
15001
  critical: ["store"]
14929
15002
  };
14930
- fs11.mkdirSync(v2, { recursive: true });
14931
- const ignore = path15.join(v2, ".gitignore");
14932
- if (!fs11.existsSync(ignore))
14933
- fs11.writeFileSync(ignore, `*
15003
+ fs12.mkdirSync(v2, { recursive: true });
15004
+ const ignore = path16.join(v2, ".gitignore");
15005
+ if (!fs12.existsSync(ignore))
15006
+ fs12.writeFileSync(ignore, `*
14934
15007
  `);
14935
- replaceFile(path15.join(v2, "workspace.json"), `${JSON.stringify(marker, null, 2)}
15008
+ replaceFile(path16.join(v2, "workspace.json"), `${JSON.stringify(marker, null, 2)}
14936
15009
  `, true);
14937
15010
  }
14938
15011
  stubFor(taskId) {
@@ -14948,7 +15021,7 @@ class TaskStore {
14948
15021
  }
14949
15022
  isStub(file) {
14950
15023
  try {
14951
- const value = JSON.parse(fs11.readFileSync(file, "utf8"));
15024
+ const value = JSON.parse(fs12.readFileSync(file, "utf8"));
14952
15025
  return isObject6(value) && isObject6(value.store) && value.store.format === "workit-store";
14953
15026
  } catch {
14954
15027
  return false;
@@ -14956,32 +15029,32 @@ class TaskStore {
14956
15029
  }
14957
15030
  writeTombstoneIfMissing() {
14958
15031
  try {
14959
- const v2 = path15.join(this.root, ".workit");
14960
- if (fs11.existsSync(path15.join(v2, "workspace.json")))
15032
+ const v2 = path16.join(this.root, ".workit");
15033
+ if (fs12.existsSync(path16.join(v2, "workspace.json")))
14961
15034
  return;
14962
15035
  let id = null;
14963
15036
  try {
14964
- id = JSON.parse(fs11.readFileSync(this.paths().workspace, "utf8")).id ?? null;
15037
+ id = JSON.parse(fs12.readFileSync(this.paths().workspace, "utf8")).id ?? null;
14965
15038
  } catch {}
14966
15039
  this.writeTombstone(v2, id);
14967
15040
  } catch {}
14968
15041
  }
14969
15042
  initializeStorage() {
14970
15043
  const dirs = this.paths();
14971
- retryTransient(() => fs11.mkdirSync(dirs.checkout, { recursive: true }));
14972
- retryTransient(() => fs11.mkdirSync(dirs.tasks, { recursive: true }));
14973
- if (!fs11.existsSync(dirs.marker))
15044
+ retryTransient(() => fs12.mkdirSync(dirs.checkout, { recursive: true }));
15045
+ retryTransient(() => fs12.mkdirSync(dirs.tasks, { recursive: true }));
15046
+ if (!fs12.existsSync(dirs.marker))
14974
15047
  replaceFile(dirs.marker, `${JSON.stringify({ format: "workit-store", version: STORE_FORMAT, createdWith: runtimeVersion() })}
14975
15048
  `, false);
14976
15049
  if (!dirs.shared) {
14977
- const ignore = path15.join(dirs.dir, ".gitignore");
15050
+ const ignore = path16.join(dirs.dir, ".gitignore");
14978
15051
  let current = null;
14979
15052
  try {
14980
- current = fs11.readFileSync(ignore, "utf8");
15053
+ current = fs12.readFileSync(ignore, "utf8");
14981
15054
  } catch {}
14982
15055
  if (current !== `*
14983
15056
  `)
14984
- retryTransient(() => fs11.writeFileSync(ignore, `*
15057
+ retryTransient(() => fs12.writeFileSync(ignore, `*
14985
15058
  `));
14986
15059
  }
14987
15060
  this.writeTombstoneIfMissing();
@@ -14997,7 +15070,7 @@ class TaskStore {
14997
15070
  shouldReclaim: ({ payload, nowMs }) => {
14998
15071
  let ageMs = null;
14999
15072
  try {
15000
- ageMs = nowMs - fs11.lstatSync(lockPath).mtimeMs;
15073
+ ageMs = nowMs - fs12.lstatSync(lockPath).mtimeMs;
15001
15074
  } catch {}
15002
15075
  return classifyLockOwner(payload, ageMs, localLockHost(), TASK_STORE_LOCK).state === "stale";
15003
15076
  },
@@ -15034,7 +15107,7 @@ class TaskStore {
15034
15107
  withLock(lockPath, operation) {
15035
15108
  try {
15036
15109
  this.initializeStorage();
15037
- fs11.mkdirSync(path15.dirname(lockPath), { recursive: true });
15110
+ fs12.mkdirSync(path16.dirname(lockPath), { recursive: true });
15038
15111
  } catch (error) {
15039
15112
  return failure2("storage_error", `unable to initialize store: ${String(error)}`, {
15040
15113
  path: this.paths().dir
@@ -15074,18 +15147,18 @@ class TaskStore {
15074
15147
  lockDirWritable(lockPath) {
15075
15148
  const probe = `${lockPath}.${process.pid}.${randomUUID3()}.probe`;
15076
15149
  try {
15077
- fs11.closeSync(fs11.openSync(probe, "wx", 384));
15150
+ fs12.closeSync(fs12.openSync(probe, "wx", 384));
15078
15151
  } catch {
15079
15152
  return false;
15080
15153
  }
15081
15154
  try {
15082
- fs11.rmSync(probe, { force: true });
15155
+ fs12.rmSync(probe, { force: true });
15083
15156
  } catch {}
15084
15157
  return true;
15085
15158
  }
15086
15159
  lockHolderPresent(lockPath) {
15087
15160
  try {
15088
- fs11.lstatSync(lockPath);
15161
+ fs12.lstatSync(lockPath);
15089
15162
  return true;
15090
15163
  } catch (error) {
15091
15164
  return error?.code !== "ENOENT";
@@ -15097,12 +15170,12 @@ class TaskStore {
15097
15170
  if (isTransientWindowsError(error) && !this.lockHolderPresent(lockPath) && !this.lockDirWritable(lockPath))
15098
15171
  return failure2("storage_error", `cannot create the workit lock (${code}); no other Workit call holds it`, {
15099
15172
  path: lockPath,
15100
- guidance: `Check permissions and the read-only attribute on ${path15.dirname(lockPath)}.`
15173
+ guidance: `Check permissions and the read-only attribute on ${path16.dirname(lockPath)}.`
15101
15174
  });
15102
15175
  if (code === "EEXIST" || code === "file_lock_timeout" || code === "file_lock_stale" || isTransientWindowsError(error)) {
15103
15176
  let lock = null;
15104
15177
  try {
15105
- lock = parseMetadataLockOrNull(fs11.readFileSync(lockPath, "utf8"));
15178
+ lock = parseMetadataLockOrNull(fs12.readFileSync(lockPath, "utf8"));
15106
15179
  } catch {}
15107
15180
  return failure2("busy", `workit lock is held by another Workit call${lock ? ` (pid ${lock.pid} on ${lock.host})` : ""}; retry shortly`, {
15108
15181
  outcome: "not_started",
@@ -15143,7 +15216,7 @@ var MIGRATION_PENDING = "workit migration pending", STORE_FORMAT = 3, STORE_MIN_
15143
15216
  };
15144
15217
  }, fileSignature = (file) => {
15145
15218
  try {
15146
- const stat = fs11.statSync(file, { bigint: true });
15219
+ const stat = fs12.statSync(file, { bigint: true });
15147
15220
  return `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}`;
15148
15221
  } catch {
15149
15222
  return null;
@@ -15155,7 +15228,7 @@ var MIGRATION_PENDING = "workit migration pending", STORE_FORMAT = 3, STORE_MIN_
15155
15228
  }, now = () => new Date().toISOString().replace(/\.\d{3}Z$/, "Z"), oldestFirst = (left, right) => left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id), cachedRuntimeVersion = null, runtimeVersion = () => {
15156
15229
  if (cachedRuntimeVersion === null) {
15157
15230
  try {
15158
- const pkg = JSON.parse(fs11.readFileSync(path15.join(packageRoot(), "package.json"), "utf8"));
15231
+ const pkg = JSON.parse(fs12.readFileSync(path16.join(packageRoot(), "package.json"), "utf8"));
15159
15232
  cachedRuntimeVersion = typeof pkg.version === "string" && pkg.version ? pkg.version : "0.0.0";
15160
15233
  } catch {
15161
15234
  cachedRuntimeVersion = "0.0.0";
@@ -15177,12 +15250,12 @@ var MIGRATION_PENDING = "workit migration pending", STORE_FORMAT = 3, STORE_MIN_
15177
15250
  return false;
15178
15251
  }, validId = (value) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value), readText = (file) => {
15179
15252
  try {
15180
- return fs11.readFileSync(file, "utf8");
15253
+ return fs12.readFileSync(file, "utf8");
15181
15254
  } catch {
15182
15255
  return "";
15183
15256
  }
15184
15257
  }, REFLOG_LINE, branchStart = (location, branch, aliases) => {
15185
- const first = readText(path15.join(path15.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
15258
+ const first = readText(path16.join(path16.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
15186
15259
  `, 1)[0];
15187
15260
  const created = REFLOG_LINE.exec(first);
15188
15261
  const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
@@ -15192,7 +15265,7 @@ var MIGRATION_PENDING = "workit migration pending", STORE_FORMAT = 3, STORE_MIN_
15192
15265
  return start;
15193
15266
  if (!location.git)
15194
15267
  return null;
15195
- for (const line of readText(path15.join(location.git.gitDir, "logs", "HEAD")).split(`
15268
+ for (const line of readText(path16.join(location.git.gitDir, "logs", "HEAD")).split(`
15196
15269
  `)) {
15197
15270
  const entry = REFLOG_LINE.exec(line);
15198
15271
  const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
@@ -15201,21 +15274,21 @@ var MIGRATION_PENDING = "workit migration pending", STORE_FORMAT = 3, STORE_MIN_
15201
15274
  return moved[1];
15202
15275
  }
15203
15276
  return null;
15204
- }, refExists = (common, ref) => fs11.existsSync(path15.join(common, ref)) || readText(path15.join(common, "packed-refs")).includes(` ${ref}
15277
+ }, refExists = (common, ref) => fs12.existsSync(path16.join(common, ref)) || readText(path16.join(common, "packed-refs")).includes(` ${ref}
15205
15278
  `), origins, sameDirectoryIdentity = (left, right) => {
15206
- if (!path15.isAbsolute(left) || !path15.isAbsolute(right))
15279
+ if (!path16.isAbsolute(left) || !path16.isAbsolute(right))
15207
15280
  return false;
15208
- const normalizedLeft = path15.resolve(left);
15209
- const normalizedRight = path15.resolve(right);
15281
+ const normalizedLeft = path16.resolve(left);
15282
+ const normalizedRight = path16.resolve(right);
15210
15283
  try {
15211
- const a = fs11.statSync(normalizedLeft, { bigint: true });
15212
- const b = fs11.statSync(normalizedRight, { bigint: true });
15284
+ const a = fs12.statSync(normalizedLeft, { bigint: true });
15285
+ const b = fs12.statSync(normalizedRight, { bigint: true });
15213
15286
  if (!a.isDirectory() || !b.isDirectory())
15214
15287
  return false;
15215
15288
  if (process.platform === "win32" ? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase() : normalizedLeft === normalizedRight)
15216
15289
  return true;
15217
- const canonicalLeft = fs11.realpathSync(normalizedLeft);
15218
- const canonicalRight = fs11.realpathSync(normalizedRight);
15290
+ const canonicalLeft = fs12.realpathSync(normalizedLeft);
15291
+ const canonicalRight = fs12.realpathSync(normalizedRight);
15219
15292
  if (process.platform === "win32" ? canonicalLeft.toLowerCase() === canonicalRight.toLowerCase() : canonicalLeft === canonicalRight)
15220
15293
  return true;
15221
15294
  return a.dev === b.dev && a.ino !== 0n && a.ino === b.ino;
@@ -15263,16 +15336,16 @@ var init_workers = __esm(() => {
15263
15336
 
15264
15337
  // packages/workit-core/src/check-config.ts
15265
15338
  import { spawnSync as spawnSync9 } from "node:child_process";
15266
- import fs12 from "node:fs";
15267
- import path16 from "node:path";
15339
+ import fs13 from "node:fs";
15340
+ import path17 from "node:path";
15268
15341
  function checksConfigFile(root) {
15269
- const current = path16.join(root, CHECKS_FILE);
15270
- const legacy = path16.join(root, LEGACY_CHECKS_FILE);
15271
- return !fs12.existsSync(current) && fs12.existsSync(legacy) ? legacy : current;
15342
+ const current = path17.join(root, CHECKS_FILE);
15343
+ const legacy = path17.join(root, LEGACY_CHECKS_FILE);
15344
+ return !fs13.existsSync(current) && fs13.existsSync(legacy) ? legacy : current;
15272
15345
  }
15273
15346
  function repoHeavyCommands(root) {
15274
15347
  try {
15275
- const value = JSON.parse(fs12.readFileSync(checksConfigFile(root), "utf8"));
15348
+ const value = JSON.parse(fs13.readFileSync(checksConfigFile(root), "utf8"));
15276
15349
  const resources = isRecord3(value) ? value.resources : undefined;
15277
15350
  const list = isRecord3(resources) ? resources.heavyCommands : undefined;
15278
15351
  return Array.isArray(list) ? list.filter((item) => typeof item === "string") : [];
@@ -15317,12 +15390,12 @@ function splitCommand(command) {
15317
15390
  return argv.length ? argv : new Error("empty command");
15318
15391
  }
15319
15392
  function checkRoot(cwd) {
15320
- return path16.resolve(git4(cwd, ["rev-parse", "--show-toplevel"]) ?? cwd);
15393
+ return path17.resolve(git4(cwd, ["rev-parse", "--show-toplevel"]) ?? cwd);
15321
15394
  }
15322
15395
  function detectedChecks(root) {
15323
15396
  const read = (file) => {
15324
15397
  try {
15325
- return fs12.readFileSync(path16.join(root, file), "utf8");
15398
+ return fs13.readFileSync(path17.join(root, file), "utf8");
15326
15399
  } catch {
15327
15400
  return null;
15328
15401
  }
@@ -15361,7 +15434,7 @@ function detectedChecks(root) {
15361
15434
  function loadCheckConfig(cwd) {
15362
15435
  const root = checkRoot(cwd);
15363
15436
  const file = checksConfigFile(root);
15364
- const legacy = path16.basename(file) === LEGACY_CHECKS_FILE;
15437
+ const legacy = path17.basename(file) === LEGACY_CHECKS_FILE;
15365
15438
  const label = legacy ? LEGACY_CHECKS_FILE : CHECKS_FILE;
15366
15439
  const note = legacy ? {
15367
15440
  note: `${LEGACY_CHECKS_FILE} is deprecated; move it to ${CHECKS_FILE} (workit doctor --fix)`
@@ -15376,7 +15449,7 @@ function loadCheckConfig(cwd) {
15376
15449
  });
15377
15450
  let text = null;
15378
15451
  try {
15379
- text = fs12.readFileSync(file, "utf8");
15452
+ text = fs13.readFileSync(file, "utf8");
15380
15453
  } catch (error) {
15381
15454
  if (error.code !== "ENOENT")
15382
15455
  return none(`cannot read ${label}: ${error.message}`);
@@ -15437,10 +15510,10 @@ function workitAvailable(env = process.env) {
15437
15510
  return workitOnPath;
15438
15511
  const windows = process.platform === "win32";
15439
15512
  const exts = windows ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
15440
- const dirs = (env.PATH ?? env.Path ?? "").split(path16.delimiter).filter(Boolean);
15513
+ const dirs = (env.PATH ?? env.Path ?? "").split(path17.delimiter).filter(Boolean);
15441
15514
  workitOnPath = dirs.some((dir) => exts.some((ext) => {
15442
15515
  try {
15443
- return fs12.statSync(path16.join(dir, `workit${ext}`)).isFile();
15516
+ return fs13.statSync(path17.join(dir, `workit${ext}`)).isFile();
15444
15517
  } catch {
15445
15518
  return false;
15446
15519
  }
@@ -15461,7 +15534,7 @@ var SCRIPT_CHECKS, CHECKS_FILE = ".workit/checks.json", LEGACY_CHECKS_FILE = "wo
15461
15534
  const value = run.status === 0 ? (run.stdout ?? "").trim() : "";
15462
15535
  return value || null;
15463
15536
  }, packageManager = (root) => {
15464
- const has = (file) => fs12.existsSync(path16.join(root, file));
15537
+ const has = (file) => fs13.existsSync(path17.join(root, file));
15465
15538
  if (has("bun.lock") || has("bun.lockb"))
15466
15539
  return "bun";
15467
15540
  if (has("pnpm-lock.yaml"))
@@ -15484,14 +15557,14 @@ var init_check_config = __esm(() => {
15484
15557
  });
15485
15558
 
15486
15559
  // packages/workit-core/src/core/task-evaluation.ts
15487
- import { createHash as createHash11 } from "node:crypto";
15488
- import * as fs13 from "node:fs";
15560
+ import { createHash as createHash12 } from "node:crypto";
15561
+ import * as fs14 from "node:fs";
15489
15562
  import { spawnSync as spawnSync10 } from "node:child_process";
15490
- import path17 from "node:path";
15563
+ import path18 from "node:path";
15491
15564
  function captureCandidate(root, scope, environment = []) {
15492
15565
  let checkout;
15493
15566
  try {
15494
- checkout = fs13.realpathSync(root);
15567
+ checkout = fs14.realpathSync(root);
15495
15568
  } catch {
15496
15569
  return failure2("invalid_input", "candidate root does not exist");
15497
15570
  }
@@ -15509,11 +15582,11 @@ function captureCandidate(root, scope, environment = []) {
15509
15582
  if (item === ".git" || item === ".workit")
15510
15583
  continue;
15511
15584
  names.add(item);
15512
- if (!fs13.existsSync(target))
15585
+ if (!fs14.existsSync(target))
15513
15586
  continue;
15514
15587
  let stat;
15515
15588
  try {
15516
- stat = fs13.lstatSync(target);
15589
+ stat = fs14.lstatSync(target);
15517
15590
  } catch {
15518
15591
  uncertain = true;
15519
15592
  continue;
@@ -15529,17 +15602,17 @@ function captureCandidate(root, scope, environment = []) {
15529
15602
  for (const item of [...names].toSorted()) {
15530
15603
  if (!scopeMatches(item, normalizedScope))
15531
15604
  continue;
15532
- const target = path17.join(checkout, item);
15605
+ const target = path18.join(checkout, item);
15533
15606
  try {
15534
- const stat = fs13.lstatSync(target);
15607
+ const stat = fs14.lstatSync(target);
15535
15608
  if (stat.isSymbolicLink()) {
15536
- const link = fs13.readlinkSync(target);
15609
+ const link = fs14.readlinkSync(target);
15537
15610
  files.push({ path: item, kind: "symlink", digest: digestBytes(link), executable: null });
15538
15611
  } else if (stat.isFile()) {
15539
15612
  files.push({
15540
15613
  path: item,
15541
15614
  kind: "file",
15542
- digest: digestBytes(fs13.readFileSync(target)),
15615
+ digest: digestBytes(fs14.readFileSync(target)),
15543
15616
  executable: (stat.mode & 73) !== 0
15544
15617
  });
15545
15618
  } else if (!stat.isDirectory()) {
@@ -15938,12 +16011,12 @@ function boundTaskSummary(summary) {
15938
16011
  brief.truncated = JSON.stringify(brief).includes("…") || progress.blockers.length > BRIEF_BLOCKERS || unmet.length > BRIEF_OPEN;
15939
16012
  return brief;
15940
16013
  }
15941
- var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"), inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path17.sep}`), relative = (root, candidate) => path17.relative(root, candidate).split(path17.sep).join("/") || ".", canonicalPath = (value) => {
16014
+ var digestBytes = (value) => createHash12("sha256").update(value).digest("hex"), inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path18.sep}`), relative = (root, candidate) => path18.relative(root, candidate).split(path18.sep).join("/") || ".", canonicalPath = (value) => {
15942
16015
  if (typeof value !== "string" || !value)
15943
16016
  return null;
15944
16017
  if (value.includes("\\") || value.split("/").includes(".."))
15945
16018
  return null;
15946
- const normalized = path17.posix.normalize(value);
16019
+ const normalized = path18.posix.normalize(value);
15947
16020
  if (normalized === ".." || normalized.startsWith("../") || normalized.startsWith("/"))
15948
16021
  return null;
15949
16022
  return normalized === "." ? "." : normalized.replace(/\/$/, "");
@@ -15985,20 +16058,20 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
15985
16058
  git: !/not a git repository/i.test(stderr)
15986
16059
  };
15987
16060
  }
15988
- const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path17.sep).join("/")) : [];
16061
+ const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path18.sep).join("/")) : [];
15989
16062
  const stagedDeleted = spawnSync10("git", ["diff", "--cached", "--name-only", "--diff-filter=D", "-z"], { cwd: root, encoding: "buffer" });
15990
16063
  if (stagedDeleted.status !== 0) {
15991
16064
  const stderr = stagedDeleted.stderr?.toString("utf8") ?? "";
15992
16065
  if (!/not a git repository/i.test(stderr))
15993
16066
  return { paths, uncertain: true, git: true };
15994
16067
  } else if (stagedDeleted.stdout) {
15995
- paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path17.sep).join("/")));
16068
+ paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path18.sep).join("/")));
15996
16069
  }
15997
16070
  return { paths: [...new Set(paths)], uncertain: false, git: true };
15998
16071
  }, walk = (root, directory, output) => {
15999
16072
  let names;
16000
16073
  try {
16001
- names = fs13.readdirSync(directory);
16074
+ names = fs14.readdirSync(directory);
16002
16075
  } catch {
16003
16076
  return true;
16004
16077
  }
@@ -16006,10 +16079,10 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
16006
16079
  for (const name of names) {
16007
16080
  if (name === ".git" || name === ".workit")
16008
16081
  continue;
16009
- const target = path17.join(directory, name);
16082
+ const target = path18.join(directory, name);
16010
16083
  let stat;
16011
16084
  try {
16012
- stat = fs13.lstatSync(target);
16085
+ stat = fs14.lstatSync(target);
16013
16086
  } catch {
16014
16087
  uncertain = true;
16015
16088
  continue;
@@ -16023,14 +16096,14 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
16023
16096
  }, scopeRoots = (root, scope) => {
16024
16097
  const roots = [];
16025
16098
  for (const item of scope.paths.length ? scope.paths : ["."]) {
16026
- const target = path17.resolve(root, item);
16099
+ const target = path18.resolve(root, item);
16027
16100
  if (!inside(root, target))
16028
16101
  return failure2("invalid_input", `candidate scope escapes checkout: ${item} — keep one task per repository and coordinate a separate linked task in the other checkout`, { fields: [{ path: "scope.paths", reason: `${item} is outside the checkout` }] });
16029
16102
  let ancestor = target;
16030
- while (!fs13.existsSync(ancestor) && ancestor !== root)
16031
- ancestor = path17.dirname(ancestor);
16103
+ while (!fs14.existsSync(ancestor) && ancestor !== root)
16104
+ ancestor = path18.dirname(ancestor);
16032
16105
  try {
16033
- if (!inside(root, fs13.realpathSync(ancestor)))
16106
+ if (!inside(root, fs14.realpathSync(ancestor)))
16034
16107
  return failure2("invalid_input", `candidate scope escapes checkout through a symlink: ${item} — keep one task per repository and coordinate a separate linked task in the other checkout`, { fields: [{ path: "scope.paths", reason: `${item} resolves outside the checkout` }] });
16035
16108
  } catch {
16036
16109
  return failure2("invalid_input", `candidate scope cannot be inspected: ${item}`);
@@ -16083,7 +16156,7 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
16083
16156
  }, findingVerificationPasses = (findingCandidateId, evidence) => evidence.status === "passed" && (evidence.kind === "check" || evidence.kind === "review") && ((findingCandidateId ?? null) === null || evidence.candidateId != null), verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
16084
16157
  let root;
16085
16158
  try {
16086
- root = fs13.realpathSync(checkoutRoot);
16159
+ root = fs14.realpathSync(checkoutRoot);
16087
16160
  } catch {
16088
16161
  return failure2("permission_denied", "checkout root is unavailable");
16089
16162
  }
@@ -16092,23 +16165,23 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
16092
16165
  continue;
16093
16166
  if (!reference.digest)
16094
16167
  return failure2("invalid_input", "document references require a byte digest");
16095
- const target = path17.resolve(root, reference.path);
16096
- if (target !== root && !target.startsWith(`${root}${path17.sep}`))
16168
+ const target = path18.resolve(root, reference.path);
16169
+ if (target !== root && !target.startsWith(`${root}${path18.sep}`))
16097
16170
  return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
16098
16171
  fields: [
16099
16172
  { path: "contentRefs.path", reason: `${reference.path} is outside the checkout` }
16100
16173
  ]
16101
16174
  });
16102
16175
  try {
16103
- const below = path17.relative(root, target);
16176
+ const below = path18.relative(root, target);
16104
16177
  let current = root;
16105
- for (const segment of below.split(path17.sep)) {
16178
+ for (const segment of below.split(path18.sep)) {
16106
16179
  if (!segment)
16107
16180
  continue;
16108
- current = path17.join(current, segment);
16109
- const stat = fs13.lstatSync(current);
16110
- const real = fs13.realpathSync(current);
16111
- if (real !== root && !real.startsWith(`${root}${path17.sep}`))
16181
+ current = path18.join(current, segment);
16182
+ const stat = fs14.lstatSync(current);
16183
+ const real = fs14.realpathSync(current);
16184
+ if (real !== root && !real.startsWith(`${root}${path18.sep}`))
16112
16185
  return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
16113
16186
  fields: [
16114
16187
  {
@@ -16124,7 +16197,7 @@ var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"),
16124
16197
  if (current !== target && !stat.isDirectory())
16125
16198
  return failure2("invalid_input", "document reference ancestor is not a directory");
16126
16199
  }
16127
- if (digestBytes(fs13.readFileSync(target)) !== reference.digest)
16200
+ if (digestBytes(fs14.readFileSync(target)) !== reference.digest)
16128
16201
  return failure2("permission_denied", "decision document bytes have changed");
16129
16202
  } catch {
16130
16203
  return failure2("invalid_input", "decision document is unavailable");
@@ -18104,9 +18177,9 @@ var support = (descriptor, axis) => {
18104
18177
  });
18105
18178
 
18106
18179
  // packages/workit-core/src/hooks/context.ts
18107
- import { createHash as createHash12 } from "node:crypto";
18108
- import fs14 from "node:fs";
18109
- import path18 from "node:path";
18180
+ import { createHash as createHash13 } from "node:crypto";
18181
+ import fs15 from "node:fs";
18182
+ import path19 from "node:path";
18110
18183
  function sessionCompactContext(store, session, context, selection = "session-bound") {
18111
18184
  const listed = store.listTaskIndex();
18112
18185
  if (!listed.ok)
@@ -18141,7 +18214,7 @@ function entryCompactContext(store, entry, session, context) {
18141
18214
  return null;
18142
18215
  const freshness = { mode: "signal", current: () => recentSignal(store.root) };
18143
18216
  const observed = task?.data.evidence.some(isObservedCheck) ?? false;
18144
- const files = (task?.data.decisions ?? []).flatMap((decision) => decision.data.binding.contentRefs.flatMap((ref) => ref.kind === "file" ? [path18.resolve(store.root, ref.path)] : []));
18217
+ const files = (task?.data.decisions ?? []).flatMap((decision) => decision.data.binding.contentRefs.flatMap((ref) => ref.kind === "file" ? [path19.resolve(store.root, ref.path)] : []));
18145
18218
  const observedFiles = filesKey(files);
18146
18219
  const compact = new WorkitCore(store, context).compactContext(entry?.id ?? null, freshness, origin && { origin: origin.origin, taskId: origin.entry.id });
18147
18220
  if (!compact.ok || !compact.data)
@@ -18239,7 +18312,7 @@ ${options.addendum}` : ""}
18239
18312
  } catch {
18240
18313
  return null;
18241
18314
  }
18242
- }, TURN_TTL_MS, digestOf = (text) => createHash12("sha256").update(text).digest("hex"), turnMarker = (input) => {
18315
+ }, TURN_TTL_MS, digestOf = (text) => createHash13("sha256").update(text).digest("hex"), turnMarker = (input) => {
18243
18316
  if (!input.session.id)
18244
18317
  return null;
18245
18318
  try {
@@ -18247,29 +18320,29 @@ ${options.addendum}` : ""}
18247
18320
  if (location instanceof Error)
18248
18321
  return null;
18249
18322
  const session = [input.host, input.session.id, input.session.agentId ?? ""].join("\x00");
18250
- return path18.join(location.dir, "hooks", `turn-${digestOf(session).slice(0, 32)}.json`);
18323
+ return path19.join(location.dir, "hooks", `turn-${digestOf(session).slice(0, 32)}.json`);
18251
18324
  } catch {
18252
18325
  return null;
18253
18326
  }
18254
18327
  }, writeTurnDigest = (file, digest) => {
18255
18328
  try {
18256
- fs14.mkdirSync(path18.dirname(file), { recursive: true });
18257
- fs14.writeFileSync(file, `${JSON.stringify({ digest })}
18329
+ fs15.mkdirSync(path19.dirname(file), { recursive: true });
18330
+ fs15.writeFileSync(file, `${JSON.stringify({ digest })}
18258
18331
  `);
18259
18332
  } catch {}
18260
18333
  }, clearTurnDigest = (file) => {
18261
18334
  try {
18262
- fs14.rmSync(file, { force: true });
18335
+ fs15.rmSync(file, { force: true });
18263
18336
  } catch {}
18264
18337
  }, pruneTurnDigests = (dir, now) => {
18265
18338
  try {
18266
- for (const name of fs14.readdirSync(dir)) {
18339
+ for (const name of fs15.readdirSync(dir)) {
18267
18340
  if (!name.startsWith("turn-"))
18268
18341
  continue;
18269
- const file = path18.join(dir, name);
18342
+ const file = path19.join(dir, name);
18270
18343
  try {
18271
- if (now - fs14.statSync(file).mtimeMs > TURN_TTL_MS)
18272
- fs14.rmSync(file, { force: true });
18344
+ if (now - fs15.statSync(file).mtimeMs > TURN_TTL_MS)
18345
+ fs15.rmSync(file, { force: true });
18273
18346
  } catch {}
18274
18347
  }
18275
18348
  } catch {}
@@ -18284,7 +18357,7 @@ ${options.addendum}` : ""}
18284
18357
  return text;
18285
18358
  const digest = digestOf(text);
18286
18359
  try {
18287
- const previous = JSON.parse(fs14.readFileSync(file, "utf8"));
18360
+ const previous = JSON.parse(fs15.readFileSync(file, "utf8"));
18288
18361
  if (previous.digest === digest)
18289
18362
  return null;
18290
18363
  } catch {}
@@ -18294,7 +18367,7 @@ ${options.addendum}` : ""}
18294
18367
  const file = turnMarker(input);
18295
18368
  if (!file)
18296
18369
  return;
18297
- pruneTurnDigests(path18.dirname(file), Date.now());
18370
+ pruneTurnDigests(path19.dirname(file), Date.now());
18298
18371
  if (text)
18299
18372
  writeTurnDigest(file, digestOf(text));
18300
18373
  else
@@ -18314,9 +18387,9 @@ var init_context = __esm(() => {
18314
18387
  });
18315
18388
 
18316
18389
  // packages/workit-core/src/hooks/session-marker.ts
18317
- import { createHash as createHash13 } from "node:crypto";
18318
- import fs15 from "node:fs";
18319
- import path19 from "node:path";
18390
+ import { createHash as createHash14 } from "node:crypto";
18391
+ import fs16 from "node:fs";
18392
+ import path20 from "node:path";
18320
18393
  var sessionMarkerFile = (input, session, store) => {
18321
18394
  let dir = store;
18322
18395
  if (dir === undefined) {
@@ -18325,19 +18398,19 @@ var sessionMarkerFile = (input, session, store) => {
18325
18398
  return null;
18326
18399
  dir = location.dir;
18327
18400
  }
18328
- const name = createHash13("sha256").update(`${input.host}\x00${session}`).digest("hex").slice(0, 32);
18329
- return path19.join(dir, "hooks", `skills-${name}.json`);
18401
+ const name = createHash14("sha256").update(`${input.host}\x00${session}`).digest("hex").slice(0, 32);
18402
+ return path20.join(dir, "hooks", `skills-${name}.json`);
18330
18403
  }, list2 = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [], readSessionMarker = (file) => {
18331
18404
  try {
18332
- const value = JSON.parse(fs15.readFileSync(file, "utf8"));
18405
+ const value = JSON.parse(fs16.readFileSync(file, "utf8"));
18333
18406
  return { nudged: list2(value.nudged), loaded: list2(value.loaded), raw: list2(value.raw) };
18334
18407
  } catch {
18335
18408
  return { nudged: [], loaded: [], raw: [] };
18336
18409
  }
18337
18410
  }, writeSessionMarker = (file, marker) => {
18338
18411
  try {
18339
- fs15.mkdirSync(path19.dirname(file), { recursive: true });
18340
- fs15.writeFileSync(file, JSON.stringify(marker));
18412
+ fs16.mkdirSync(path20.dirname(file), { recursive: true });
18413
+ fs16.writeFileSync(file, JSON.stringify(marker));
18341
18414
  } catch {}
18342
18415
  };
18343
18416
  var init_session_marker = __esm(() => {
@@ -18772,10 +18845,10 @@ var init_shell_words = __esm(() => {
18772
18845
 
18773
18846
  // packages/workit-core/src/hooks/raw-git.ts
18774
18847
  import { spawnSync as spawnSync11 } from "node:child_process";
18775
- import { createHash as createHash14 } from "node:crypto";
18776
- import fs16 from "node:fs";
18848
+ import { createHash as createHash15 } from "node:crypto";
18849
+ import fs17 from "node:fs";
18777
18850
  import os5 from "node:os";
18778
- import path20 from "node:path";
18851
+ import path21 from "node:path";
18779
18852
  function rawInvocations(command, dialect = "posix", depth = 0) {
18780
18853
  if (depth > 0)
18781
18854
  return walk2(command, dialect, depth);
@@ -19057,8 +19130,8 @@ function noteRawCommit(input, command, key) {
19057
19130
  if (action.kind !== "commit")
19058
19131
  continue;
19059
19132
  const file = markerFile(repo, input.session.id, key);
19060
- fs16.mkdirSync(path20.dirname(file), { recursive: true });
19061
- fs16.writeFileSync(file, `${JSON.stringify({ head: headSha2(repo), at })}
19133
+ fs17.mkdirSync(path21.dirname(file), { recursive: true });
19134
+ fs17.writeFileSync(file, `${JSON.stringify({ head: headSha2(repo), at })}
19062
19135
  `);
19063
19136
  }
19064
19137
  } catch {}
@@ -19080,16 +19153,16 @@ function settlePendingCommit(input) {
19080
19153
  if (!repo)
19081
19154
  return;
19082
19155
  const file = markerFile(repo, input.session.id, NEXT_COMMAND);
19083
- if (fs16.existsSync(file))
19156
+ if (fs17.existsSync(file))
19084
19157
  settle2(input, repo, file);
19085
19158
  } catch {}
19086
19159
  }
19087
- var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLARATIONS, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, GIT_CONFIG_OPTIONS, GIT_CONFIG_ENV, ASSIGNMENT, MAX_DEPTH = 4, MAX_EXPANSIONS = 16, isAbsolute = (value) => path20.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\"), HERE, joinDir = (base, raw) => {
19160
+ var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLARATIONS, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, GIT_CONFIG_OPTIONS, GIT_CONFIG_ENV, ASSIGNMENT, MAX_DEPTH = 4, MAX_EXPANSIONS = 16, isAbsolute = (value) => path21.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\"), HERE, joinDir = (base, raw) => {
19088
19161
  const next = raw.replace(HERE, ".");
19089
19162
  if (base === undefined || /[$`*?]/.test(next) || next === "-")
19090
19163
  return;
19091
- const expanded = next === "~" || next.startsWith("~/") ? path20.join(os5.homedir(), next.slice(1)) : next;
19092
- return base === null || isAbsolute(expanded) ? expanded : path20.join(base, expanded);
19164
+ const expanded = next === "~" || next.startsWith("~/") ? path21.join(os5.homedir(), next.slice(1)) : next;
19165
+ return base === null || isAbsolute(expanded) ? expanded : path21.join(base, expanded);
19093
19166
  }, rebase = (base, inner) => inner === null ? base : inner === undefined ? undefined : joinDir(base, inner), cdTarget = (words) => {
19094
19167
  const args = words.slice(1);
19095
19168
  const flag = args.findIndex((word) => /^-(?:literal)?path$/i.test(word));
@@ -19558,7 +19631,7 @@ var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLA
19558
19631
  return null;
19559
19632
  return { location, dir, branch: resolveTaskKey(dir, location).branch };
19560
19633
  }, isWorkitWorkspace = (repo) => {
19561
- if (fs16.existsSync(repo.location.dir))
19634
+ if (fs17.existsSync(repo.location.dir))
19562
19635
  return true;
19563
19636
  try {
19564
19637
  return resolveRuntimeWorkspaceVcs(repo.location.top ?? repo.dir) !== null;
@@ -19577,17 +19650,17 @@ var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLA
19577
19650
  if (!git || git.reftable)
19578
19651
  return null;
19579
19652
  try {
19580
- const head = fs16.readFileSync(path20.join(git.gitDir, "HEAD"), "utf8").trim();
19653
+ const head = fs17.readFileSync(path21.join(git.gitDir, "HEAD"), "utf8").trim();
19581
19654
  if (/^[0-9a-f]{40,64}$/.test(head))
19582
19655
  return head;
19583
19656
  const ref = /^ref: (refs\/.+)$/.exec(head)?.[1];
19584
19657
  if (!ref)
19585
19658
  return null;
19586
- const common = path20.dirname(repo.location.dir);
19659
+ const common = path21.dirname(repo.location.dir);
19587
19660
  try {
19588
- return fs16.readFileSync(path20.join(common, ref), "utf8").trim() || null;
19661
+ return fs17.readFileSync(path21.join(common, ref), "utf8").trim() || null;
19589
19662
  } catch {}
19590
- const packed = fs16.readFileSync(path20.join(common, "packed-refs"), "utf8");
19663
+ const packed = fs17.readFileSync(path21.join(common, "packed-refs"), "utf8");
19591
19664
  return new RegExp(`^([0-9a-f]{40,64}) ${ref.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`, "m").exec(packed)?.[1] ?? null;
19592
19665
  } catch {
19593
19666
  return null;
@@ -19653,8 +19726,8 @@ var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLA
19653
19726
  const sub = invocation.args[0];
19654
19727
  if (invocation.tool !== "git" || invocation.dir === undefined || !sub || sub.startsWith("-") || GIT_COMMANDS.has(sub) || depth >= MAX_DEPTH)
19655
19728
  return [invocation];
19656
- const dir = path20.resolve(root, invocation.dir ?? ".");
19657
- if (!fs16.existsSync(dir))
19729
+ const dir = path21.resolve(root, invocation.dir ?? ".");
19730
+ if (!fs17.existsSync(dir))
19658
19731
  return [invocation];
19659
19732
  const config = gitConfig(dir, invocation, cache);
19660
19733
  const alias = configValue(config, `alias.${sub.toLowerCase()}`);
@@ -19675,11 +19748,11 @@ var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLA
19675
19748
  }, normalizedUrl = (url, dir) => {
19676
19749
  const trimmed = url.trim();
19677
19750
  if (/^file:\/\//i.test(trimmed))
19678
- return path20.resolve(dir, trimmed.slice(7)).replace(/\/+$/, "").replace(/\.git$/, "");
19751
+ return path21.resolve(dir, trimmed.slice(7)).replace(/\/+$/, "").replace(/\.git$/, "");
19679
19752
  const scheme = /^[a-z][a-z0-9+.-]*:\/\//i.exec(trimmed);
19680
19753
  const scp = !scheme && /^(?:[^@/\\]+@)?[^/\\:]{2,}:/.test(trimmed);
19681
19754
  if (!scheme && !scp)
19682
- return path20.resolve(dir, trimmed).replace(/\/+$/, "").replace(/\.git$/, "");
19755
+ return path21.resolve(dir, trimmed).replace(/\/+$/, "").replace(/\.git$/, "");
19683
19756
  const value = scheme ? trimmed.slice(scheme[0].length).replace(/^[^@/]*@/, "").replace(/^([^/:]+):\d+(?=\/)/, "$1") : trimmed.replace(/^[^@/]*@/, "").replace(":", "/");
19684
19757
  return value.toLowerCase().replace(/\/{2,}/g, "/").replace(/^www\./, "").replace(/\/+$/, "").replace(/\.git$/, "");
19685
19758
  }, rewrittenUrl = (url, config) => {
@@ -19885,7 +19958,7 @@ var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLA
19885
19958
  const out = [];
19886
19959
  const repos = new Map;
19887
19960
  const repoFor = (relative) => {
19888
- const dir = path20.resolve(cwd, relative ?? ".");
19961
+ const dir = path21.resolve(cwd, relative ?? ".");
19889
19962
  if (!repos.has(dir)) {
19890
19963
  const repo = repoAt(dir);
19891
19964
  repos.set(dir, repo && isWorkitWorkspace(repo) ? repo : null);
@@ -19929,7 +20002,7 @@ var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLA
19929
20002
  kind: "deny",
19930
20003
  reason: `workit: the shell hook could not analyze this command (${error.message}), so it does not run. ${SPLIT_IT}`,
19931
20004
  unblock: SPLIT_IT
19932
- }), NEXT_COMMAND = "next", MARKER_TTL_SECONDS = 3600, markerFile = (repo, session, key) => path20.join(repo.location.dir, "hooks", `commit-${createHash14("sha256").update(`${session}\x00${key}`).digest("hex").slice(0, 32)}.json`), callKey = (toolUseId, command) => toolUseId ?? `cmd:${createHash14("sha256").update(command).digest("hex")}`, headCommit = (dir) => {
20005
+ }), NEXT_COMMAND = "next", MARKER_TTL_SECONDS = 3600, markerFile = (repo, session, key) => path21.join(repo.location.dir, "hooks", `commit-${createHash15("sha256").update(`${session}\x00${key}`).digest("hex").slice(0, 32)}.json`), callKey = (toolUseId, command) => toolUseId ?? `cmd:${createHash15("sha256").update(command).digest("hex")}`, headCommit = (dir) => {
19933
20006
  const run = spawnSync11("git", [
19934
20007
  "log",
19935
20008
  "-1",
@@ -19946,11 +20019,11 @@ var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLA
19946
20019
  }, settle2 = (input, repo, file) => {
19947
20020
  let marker;
19948
20021
  try {
19949
- marker = JSON.parse(fs16.readFileSync(file, "utf8"));
20022
+ marker = JSON.parse(fs17.readFileSync(file, "utf8"));
19950
20023
  } catch {
19951
20024
  return;
19952
20025
  }
19953
- fs16.rmSync(file, { force: true });
20026
+ fs17.rmSync(file, { force: true });
19954
20027
  const session = input.session.id;
19955
20028
  const now = Date.now() / 1000;
19956
20029
  if (typeof marker.at !== "number" || now - marker.at > MARKER_TTL_SECONDS)
@@ -20128,7 +20201,7 @@ var init_raw_git = __esm(() => {
20128
20201
  // packages/workit-core/src/core/route-intent.ts
20129
20202
  import { spawnSync as spawnSync12 } from "node:child_process";
20130
20203
  import { existsSync as existsSync6 } from "node:fs";
20131
- import path21 from "node:path";
20204
+ import path22 from "node:path";
20132
20205
  var UNKNOWABLE, SWITCH_CREATE, CHECKOUT_CREATE, WORKTREE_CREATE, SUBTREE_CREATE, BRANCH_NO_CREATE, BRANCH_RENAME, longOption = (name, flags) => flags.has(name) || name.length >= 3 && [...flags].some((flag) => flag.startsWith("--") && flag.startsWith(name)), shortsOf = (flags) => [...flags].filter((flag) => /^-[^-]$/u.test(flag)).join("").replaceAll("-", ""), flagValue = (args, flags) => {
20133
20206
  const shorts = shortsOf(flags);
20134
20207
  for (let index = 1;index < args.length; index++) {
@@ -20254,7 +20327,7 @@ var UNKNOWABLE, SWITCH_CREATE, CHECKOUT_CREATE, WORKTREE_CREATE, SUBTREE_CREATE,
20254
20327
  return null;
20255
20328
  if (dir === null)
20256
20329
  return root;
20257
- const resolved = path21.resolve(root, dir);
20330
+ const resolved = path22.resolve(root, dir);
20258
20331
  return existsSync6(resolved) && inWorkitWorkspace(resolved) ? resolved : null;
20259
20332
  }, shellBranchPolicyViolation = (root, command, dialect = "posix") => {
20260
20333
  let judged = false;
@@ -20307,9 +20380,9 @@ var init_policy = __esm(() => {
20307
20380
  });
20308
20381
 
20309
20382
  // packages/workit-core/src/core/heavy-rules.ts
20310
- import fs17 from "node:fs";
20383
+ import fs18 from "node:fs";
20311
20384
  import os6 from "node:os";
20312
- import path22 from "node:path";
20385
+ import path23 from "node:path";
20313
20386
  function parseJsonc(text) {
20314
20387
  let out = "";
20315
20388
  for (let index = 0;index < text.length; index += 1) {
@@ -20339,21 +20412,21 @@ function parseJsonc(text) {
20339
20412
  return JSON.parse(out.replace(/,(\s*[}\]])/gu, "$1"));
20340
20413
  }
20341
20414
  function gitTop(cwd) {
20342
- for (let dir = path22.resolve(cwd);; dir = path22.dirname(dir)) {
20343
- if (fs17.existsSync(path22.join(dir, ".git")))
20415
+ for (let dir = path23.resolve(cwd);; dir = path23.dirname(dir)) {
20416
+ if (fs18.existsSync(path23.join(dir, ".git")))
20344
20417
  return dir;
20345
- if (path22.dirname(dir) === dir)
20418
+ if (path23.dirname(dir) === dir)
20346
20419
  return null;
20347
20420
  }
20348
20421
  }
20349
20422
  function claudeSettingsFiles(cwd, env, platform = process.platform) {
20350
20423
  const project = env.CLAUDE_PROJECT_DIR || gitTop(cwd) || cwd;
20351
- const user = env.CLAUDE_CONFIG_DIR || path22.join(homeOf(env), ".claude");
20424
+ const user = env.CLAUDE_CONFIG_DIR || path23.join(homeOf(env), ".claude");
20352
20425
  return [
20353
20426
  ...CLAUDE_MANAGED[platform] ? [CLAUDE_MANAGED[platform]] : [],
20354
- path22.join(user, "settings.json"),
20355
- path22.join(project, ".claude", "settings.json"),
20356
- path22.join(project, ".claude", "settings.local.json")
20427
+ path23.join(user, "settings.json"),
20428
+ path23.join(project, ".claude", "settings.json"),
20429
+ path23.join(project, ".claude", "settings.local.json")
20357
20430
  ];
20358
20431
  }
20359
20432
  function claudeRules(cwd, env = process.env) {
@@ -20398,10 +20471,10 @@ function claudeRules(cwd, env = process.env) {
20398
20471
  function opencodeRules(cwd, env = process.env) {
20399
20472
  const rules = EMPTY();
20400
20473
  try {
20401
- const config = env.XDG_CONFIG_HOME || path22.join(homeOf(env), ".config");
20474
+ const config = env.XDG_CONFIG_HOME || path23.join(homeOf(env), ".config");
20402
20475
  const files = [
20403
- ...OPENCODE_NAMES.map((name) => path22.join(config, "opencode", name)),
20404
- ...projectDirs(cwd).flatMap((dir) => OPENCODE_NAMES.flatMap((name) => [path22.join(dir, name), path22.join(dir, ".opencode", name)])),
20476
+ ...OPENCODE_NAMES.map((name) => path23.join(config, "opencode", name)),
20477
+ ...projectDirs(cwd).flatMap((dir) => OPENCODE_NAMES.flatMap((name) => [path23.join(dir, name), path23.join(dir, ".opencode", name)])),
20405
20478
  ...env.OPENCODE_CONFIG ? [env.OPENCODE_CONFIG] : []
20406
20479
  ];
20407
20480
  for (const file of files) {
@@ -20419,19 +20492,19 @@ function opencodeRules(cwd, env = process.env) {
20419
20492
  function codexRules(cwd, env = process.env) {
20420
20493
  const rules = EMPTY();
20421
20494
  try {
20422
- const home = env.CODEX_HOME || path22.join(homeOf(env), ".codex");
20495
+ const home = env.CODEX_HOME || path23.join(homeOf(env), ".codex");
20423
20496
  const top = gitTop(cwd) ?? cwd;
20424
- for (const dir of [path22.join(home, "rules"), path22.join(top, ".codex", "rules")]) {
20497
+ for (const dir of [path23.join(home, "rules"), path23.join(top, ".codex", "rules")]) {
20425
20498
  let files;
20426
20499
  try {
20427
- files = fs17.readdirSync(dir).filter((name) => name.endsWith(".rules"));
20500
+ files = fs18.readdirSync(dir).filter((name) => name.endsWith(".rules"));
20428
20501
  } catch (error) {
20429
20502
  if (error.code === "ENOENT")
20430
20503
  continue;
20431
20504
  return "unreadable";
20432
20505
  }
20433
20506
  for (const name of files) {
20434
- const text = readText2(path22.join(dir, name)) ?? "";
20507
+ const text = readText2(path23.join(dir, name)) ?? "";
20435
20508
  for (const part of text.split(/\bprefix_rule\s*\(/u).slice(1)) {
20436
20509
  const rule = codexRule(part);
20437
20510
  if (!rule)
@@ -20450,8 +20523,8 @@ function cursorRules(cwd, env = process.env) {
20450
20523
  try {
20451
20524
  const top = gitTop(cwd) ?? cwd;
20452
20525
  for (const file of [
20453
- path22.join(homeOf(env), ".cursor", "cli-config.json"),
20454
- path22.join(top, ".cursor", "cli.json")
20526
+ path23.join(homeOf(env), ".cursor", "cli-config.json"),
20527
+ path23.join(top, ".cursor", "cli.json")
20455
20528
  ]) {
20456
20529
  const text = readText2(file);
20457
20530
  if (text === null)
@@ -20504,7 +20577,7 @@ function wrapAllowed(read, words, command, options = {}) {
20504
20577
  }
20505
20578
  var EMPTY = () => ({ deny: [], allow: [] }), readText2 = (file) => {
20506
20579
  try {
20507
- return fs17.readFileSync(file, "utf8");
20580
+ return fs18.readFileSync(file, "utf8");
20508
20581
  } catch (error) {
20509
20582
  if (error.code === "ENOENT")
20510
20583
  return null;
@@ -20513,9 +20586,9 @@ var EMPTY = () => ({ deny: [], allow: [] }), readText2 = (file) => {
20513
20586
  }, isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), projectDirs = (cwd) => {
20514
20587
  const top = gitTop(cwd);
20515
20588
  const dirs = [];
20516
- for (let dir = path22.resolve(cwd);; dir = path22.dirname(dir)) {
20589
+ for (let dir = path23.resolve(cwd);; dir = path23.dirname(dir)) {
20517
20590
  dirs.push(dir);
20518
- if (!top || dir === top || path22.dirname(dir) === dir)
20591
+ if (!top || dir === top || path23.dirname(dir) === dir)
20519
20592
  return dirs;
20520
20593
  }
20521
20594
  }, homeOf = (env) => env.HOME || os6.homedir(), CLAUDE_MANAGED, bashPattern = (entry) => {
@@ -20611,20 +20684,20 @@ var init_heavy_rules = __esm(() => {
20611
20684
  });
20612
20685
 
20613
20686
  // packages/workit-core/src/core/heavy.ts
20614
- import fs18 from "node:fs";
20687
+ import fs19 from "node:fs";
20615
20688
  import os7 from "node:os";
20616
- import path23 from "node:path";
20689
+ import path24 from "node:path";
20617
20690
  function stateDir(env, platform = process.platform) {
20618
20691
  if (env.WORKFLOW_TOOLKIT_STATE)
20619
20692
  return env.WORKFLOW_TOOLKIT_STATE;
20620
20693
  if (env.XDG_STATE_HOME)
20621
- return path23.join(env.XDG_STATE_HOME, "workit");
20694
+ return path24.join(env.XDG_STATE_HOME, "workit");
20622
20695
  const home = env.HOME || os7.homedir();
20623
20696
  if (platform === "darwin")
20624
- return path23.join(home, "Library", "Application Support", "workit");
20697
+ return path24.join(home, "Library", "Application Support", "workit");
20625
20698
  if (platform === "win32")
20626
- return path23.join(env.LOCALAPPDATA ?? path23.join(home, "AppData", "Local"), "workit");
20627
- return path23.join(home, ".local", "state", "workit");
20699
+ return path24.join(env.LOCALAPPDATA ?? path24.join(home, "AppData", "Local"), "workit");
20700
+ return path24.join(home, ".local", "state", "workit");
20628
20701
  }
20629
20702
  function positional2(words, from, values = PM_VALUES) {
20630
20703
  let index = from;
@@ -20764,7 +20837,7 @@ function machinePatterns(env) {
20764
20837
  return isRecord5(value) ? stringList(value.patterns) : [];
20765
20838
  }
20766
20839
  function repoPatterns(cwd) {
20767
- return repoHeavyCommands(gitTop(cwd) ?? path23.resolve(cwd));
20840
+ return repoHeavyCommands(gitTop(cwd) ?? path24.resolve(cwd));
20768
20841
  }
20769
20842
  function heavyLines(lines, options) {
20770
20843
  const found = [];
@@ -20833,12 +20906,12 @@ function heavyPlan(command, options) {
20833
20906
  }
20834
20907
  function workitOnPath2(env = process.env) {
20835
20908
  const names = process.platform === "win32" ? ["workit.exe", "workit.cmd", "workit"] : ["workit"];
20836
- for (const dir of (env.PATH ?? "").split(path23.delimiter))
20909
+ for (const dir of (env.PATH ?? "").split(path24.delimiter))
20837
20910
  for (const name of names) {
20838
20911
  if (!dir)
20839
20912
  continue;
20840
20913
  try {
20841
- fs18.accessSync(path23.join(dir, name), fs18.constants.X_OK);
20914
+ fs19.accessSync(path24.join(dir, name), fs19.constants.X_OK);
20842
20915
  return true;
20843
20916
  } catch {}
20844
20917
  }
@@ -20852,9 +20925,9 @@ function leaseRewrite(command) {
20852
20925
  return null;
20853
20926
  return `${prefix}workit check --heavy -- ${rest}`;
20854
20927
  }
20855
- var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path23.join(stateDir(env), HEAVY_COMMANDS_FILE), HEAVY_SCRIPT, INFO_FLAGS, WATCH_FLAG, WATCH_SCRIPT, sub = (...names) => new Set(names), TOOLS, PM_VALUES, baseName2 = (word) => (word?.split(/[\\/]/u).at(-1) ?? "").toLowerCase().replace(/\.(?:exe|cmd|bat|ps1)$/u, ""), WORKIT, PYTHONS, NPM_INSTALL, NPM_RUN, NPM_TEST, EXEC, globWord = (word) => new RegExp(`^${word.replace(/[.+?^${}()|[\]\\]/gu, "\\$&").replaceAll("*", ".*")}$`, "u"), matches = (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])), readJson = (file) => {
20928
+ var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path24.join(stateDir(env), HEAVY_COMMANDS_FILE), HEAVY_SCRIPT, INFO_FLAGS, WATCH_FLAG, WATCH_SCRIPT, sub = (...names) => new Set(names), TOOLS, PM_VALUES, baseName2 = (word) => (word?.split(/[\\/]/u).at(-1) ?? "").toLowerCase().replace(/\.(?:exe|cmd|bat|ps1)$/u, ""), WORKIT, PYTHONS, NPM_INSTALL, NPM_RUN, NPM_TEST, EXEC, globWord = (word) => new RegExp(`^${word.replace(/[.+?^${}()|[\]\\]/gu, "\\$&").replaceAll("*", ".*")}$`, "u"), matches = (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])), readJson = (file) => {
20856
20929
  try {
20857
- return JSON.parse(fs18.readFileSync(file, "utf8"));
20930
+ return JSON.parse(fs19.readFileSync(file, "utf8"));
20858
20931
  } catch {
20859
20932
  return;
20860
20933
  }
@@ -20996,9 +21069,9 @@ var init_heavy = __esm(() => {
20996
21069
  });
20997
21070
 
20998
21071
  // packages/workit-core/src/core/heavy-words.ts
20999
- import fs19 from "node:fs";
21072
+ import fs20 from "node:fs";
21000
21073
  import os8 from "node:os";
21001
- import path24 from "node:path";
21074
+ import path25 from "node:path";
21002
21075
  function maybeHeavy(command, cwd, env = process.env) {
21003
21076
  try {
21004
21077
  const words = wordsOf(command);
@@ -21014,30 +21087,30 @@ var HEAVY_WORDS, wordsOf = (command) => command.split(/[\s;&|()<>`'"]+/u).map((w
21014
21087
  if (env.WORKFLOW_TOOLKIT_STATE)
21015
21088
  return env.WORKFLOW_TOOLKIT_STATE;
21016
21089
  if (env.XDG_STATE_HOME)
21017
- return path24.join(env.XDG_STATE_HOME, "workit");
21090
+ return path25.join(env.XDG_STATE_HOME, "workit");
21018
21091
  const home = env.HOME || os8.homedir();
21019
21092
  if (process.platform === "darwin")
21020
- return path24.join(home, "Library", "Application Support", "workit");
21093
+ return path25.join(home, "Library", "Application Support", "workit");
21021
21094
  if (process.platform === "win32")
21022
- return path24.join(env.LOCALAPPDATA ?? path24.join(home, "AppData", "Local"), "workit");
21023
- return path24.join(home, ".local", "state", "workit");
21095
+ return path25.join(env.LOCALAPPDATA ?? path25.join(home, "AppData", "Local"), "workit");
21096
+ return path25.join(home, ".local", "state", "workit");
21024
21097
  }, readJson2 = (file) => {
21025
21098
  try {
21026
- return JSON.parse(fs19.readFileSync(file, "utf8"));
21099
+ return JSON.parse(fs20.readFileSync(file, "utf8"));
21027
21100
  } catch {
21028
21101
  return;
21029
21102
  }
21030
21103
  }, patternWords = (cwd, env) => {
21031
21104
  const patterns = [];
21032
- const machine = readJson2(path24.join(stateDir2(env), "heavy-commands.json"));
21105
+ const machine = readJson2(path25.join(stateDir2(env), "heavy-commands.json"));
21033
21106
  if (Array.isArray(machine?.patterns))
21034
21107
  patterns.push(...machine.patterns);
21035
- for (let dir = path24.resolve(cwd);; dir = path24.dirname(dir)) {
21036
- if (fs19.existsSync(path24.join(dir, ".git"))) {
21108
+ for (let dir = path25.resolve(cwd);; dir = path25.dirname(dir)) {
21109
+ if (fs20.existsSync(path25.join(dir, ".git"))) {
21037
21110
  patterns.push(...repoHeavyCommands(dir));
21038
21111
  break;
21039
21112
  }
21040
- if (path24.dirname(dir) === dir)
21113
+ if (path25.dirname(dir) === dir)
21041
21114
  break;
21042
21115
  }
21043
21116
  const words = new Set;
@@ -21104,10 +21177,10 @@ var init_heavy_gate = __esm(() => {
21104
21177
 
21105
21178
  // packages/workit-core/src/core/live-session.ts
21106
21179
  import { spawnSync as spawnSync13 } from "node:child_process";
21107
- import { createHash as createHash15 } from "node:crypto";
21108
- import fs20 from "node:fs";
21180
+ import { createHash as createHash16 } from "node:crypto";
21181
+ import fs21 from "node:fs";
21109
21182
  import os9 from "node:os";
21110
- import path25 from "node:path";
21183
+ import path26 from "node:path";
21111
21184
  var LIVE_SESSION_TTL_MS, HEARTBEAT_EVERY_MS = 30000, liveProbe, leadOf = (session) => session.split(":")[0].replace(/-w-.*$/su, "") || session, familyOf = (host) => host.replace(/_(?:cli|desktop)$/u, ""), processAlive = (pid) => {
21112
21185
  try {
21113
21186
  process.kill(pid, 0);
@@ -21118,9 +21191,9 @@ var LIVE_SESSION_TTL_MS, HEARTBEAT_EVERY_MS = 30000, liveProbe, leadOf = (sessio
21118
21191
  }, processInfo = (pid) => {
21119
21192
  try {
21120
21193
  if (liveProbe.platform === "linux") {
21121
- const stat = fs20.readFileSync(`/proc/${pid}/stat`, "utf8");
21194
+ const stat = fs21.readFileSync(`/proc/${pid}/stat`, "utf8");
21122
21195
  const ppid = Number(stat.slice(stat.lastIndexOf(")") + 2).split(" ")[1]);
21123
- const command = fs20.readFileSync(`/proc/${pid}/cmdline`, "utf8").replaceAll("\x00", " ");
21196
+ const command = fs21.readFileSync(`/proc/${pid}/cmdline`, "utf8").replaceAll("\x00", " ");
21124
21197
  return Number.isInteger(ppid) ? { ppid, command: command.trim() } : null;
21125
21198
  }
21126
21199
  if (liveProbe.platform === "win32")
@@ -21165,32 +21238,32 @@ var LIVE_SESSION_TTL_MS, HEARTBEAT_EVERY_MS = 30000, liveProbe, leadOf = (sessio
21165
21238
  pid: () => hostPid(transport)
21166
21239
  };
21167
21240
  }, checkoutOf = (target) => {
21168
- let dir = path25.resolve(target);
21169
- while (!fs20.existsSync(dir) && path25.dirname(dir) !== dir)
21170
- dir = path25.dirname(dir);
21171
- if (fs20.existsSync(dir) && !fs20.statSync(dir).isDirectory())
21172
- dir = path25.dirname(dir);
21173
- const parts = dir.split(path25.sep);
21241
+ let dir = path26.resolve(target);
21242
+ while (!fs21.existsSync(dir) && path26.dirname(dir) !== dir)
21243
+ dir = path26.dirname(dir);
21244
+ if (fs21.existsSync(dir) && !fs21.statSync(dir).isDirectory())
21245
+ dir = path26.dirname(dir);
21246
+ const parts = dir.split(path26.sep);
21174
21247
  const dotGit = parts.lastIndexOf(".git");
21175
21248
  if (dotGit > 0)
21176
- dir = parts.slice(0, dotGit).join(path25.sep) || path25.sep;
21249
+ dir = parts.slice(0, dotGit).join(path26.sep) || path26.sep;
21177
21250
  const location = resolveStore(dir);
21178
21251
  if (location instanceof Error || !location.shared || !location.top)
21179
21252
  return null;
21180
21253
  let top = location.top;
21181
21254
  try {
21182
- top = fs20.realpathSync.native(top);
21255
+ top = fs21.realpathSync.native(top);
21183
21256
  } catch {}
21184
21257
  return top;
21185
- }, markerFile2 = (top) => path25.join(resolveStateDir(), "live-sessions", `${createHash15("sha256").update(checkoutKey(top)).digest("hex").slice(0, 32)}.json`), checkoutKey = (top, platform = process.platform) => {
21186
- let key = path25.resolve(top);
21258
+ }, markerFile2 = (top) => path26.join(resolveStateDir(), "live-sessions", `${createHash16("sha256").update(checkoutKey(top)).digest("hex").slice(0, 32)}.json`), checkoutKey = (top, platform = process.platform) => {
21259
+ let key = path26.resolve(top);
21187
21260
  try {
21188
- key = fs20.realpathSync.native(key);
21261
+ key = fs21.realpathSync.native(key);
21189
21262
  } catch {}
21190
21263
  return platform === "win32" ? key.replaceAll("/", "\\").toLowerCase() : key;
21191
21264
  }, readMarker = (file) => {
21192
21265
  try {
21193
- const value = JSON.parse(fs20.readFileSync(file, "utf8"));
21266
+ const value = JSON.parse(fs21.readFileSync(file, "utf8"));
21194
21267
  if (value?.version !== 1 || typeof value.session !== "string" || typeof value.host !== "string" || typeof value.heartbeatAt !== "string" || Number.isNaN(Date.parse(value.heartbeatAt)))
21195
21268
  return null;
21196
21269
  return {
@@ -21271,10 +21344,10 @@ var LIVE_SESSION_TTL_MS, HEARTBEAT_EVERY_MS = 30000, liveProbe, leadOf = (sessio
21271
21344
  checkout,
21272
21345
  heartbeatAt: now.toISOString()
21273
21346
  };
21274
- fs20.mkdirSync(path25.dirname(file), { recursive: true });
21347
+ fs21.mkdirSync(path26.dirname(file), { recursive: true });
21275
21348
  const temp = `${file}.${process.pid}.tmp`;
21276
- fs20.writeFileSync(temp, JSON.stringify(marker));
21277
- fs20.renameSync(temp, file);
21349
+ fs21.writeFileSync(temp, JSON.stringify(marker));
21350
+ fs21.renameSync(temp, file);
21278
21351
  } catch {}
21279
21352
  };
21280
21353
  var init_live_session = __esm(() => {
@@ -21294,7 +21367,7 @@ var init_live_session = __esm(() => {
21294
21367
  // packages/workit-core/src/hooks/write-gate.ts
21295
21368
  import { realpathSync as realpathSync5 } from "node:fs";
21296
21369
  import os10 from "node:os";
21297
- import path26 from "node:path";
21370
+ import path27 from "node:path";
21298
21371
  function writeGate(cwd, paths, owner, deps) {
21299
21372
  const forged = paths?.length ? issuedTarget(cwd, paths) : null;
21300
21373
  if (forged)
@@ -21322,7 +21395,7 @@ function shellGate(cwd, command, owner, dialect = "posix", deps) {
21322
21395
  try {
21323
21396
  targets = [
21324
21397
  ...segmentTargets(cwd, command, dialect),
21325
- ...gitMutationDirs(cwd, command, dialect).map((dir) => path26.join(dir, DIR_TARGET))
21398
+ ...gitMutationDirs(cwd, command, dialect).map((dir) => path27.join(dir, DIR_TARGET))
21326
21399
  ];
21327
21400
  } catch {
21328
21401
  targets = [];
@@ -21360,21 +21433,21 @@ function beforeWriteGate(cwd, paths) {
21360
21433
  }
21361
21434
  var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21362
21435
  let rest = "";
21363
- for (let dir = path26.resolve(file);; dir = path26.dirname(dir)) {
21436
+ for (let dir = path27.resolve(file);; dir = path27.dirname(dir)) {
21364
21437
  try {
21365
- return path26.join(realpathSync5.native(dir), rest);
21438
+ return path27.join(realpathSync5.native(dir), rest);
21366
21439
  } catch {
21367
- if (path26.dirname(dir) === dir)
21368
- return path26.resolve(file);
21369
- rest = rest ? path26.join(path26.basename(dir), rest) : path26.basename(dir);
21440
+ if (path27.dirname(dir) === dir)
21441
+ return path27.resolve(file);
21442
+ rest = rest ? path27.join(path27.basename(dir), rest) : path27.basename(dir);
21370
21443
  }
21371
21444
  }
21372
21445
  }, exempt = (cwd, root, file, plans) => {
21373
21446
  const fold = (value) => CASE_INSENSITIVE ? value.toLowerCase() : value;
21374
- const relative = path26.relative(fold(canonical2(root)), fold(canonical2(path26.resolve(cwd, file))));
21375
- if (relative.startsWith("..") || path26.isAbsolute(relative))
21447
+ const relative = path27.relative(fold(canonical2(root)), fold(canonical2(path27.resolve(cwd, file))));
21448
+ if (relative.startsWith("..") || path27.isAbsolute(relative))
21376
21449
  return true;
21377
- const posix = relative.split(path26.sep).join("/");
21450
+ const posix = relative.split(path27.sep).join("/");
21378
21451
  const segments = posix.split("/");
21379
21452
  return /\.mdx?$/i.test(posix) || segments[0] === "docs" || segments.includes("plans") || [...plans].some((plan) => fold(plan) === posix);
21380
21453
  }, PREFIXES2, operands = (words) => words.filter((item) => !item.startsWith("-")), SCRIPT_SHELLS, wrappedScript = (input) => {
@@ -21487,7 +21560,7 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21487
21560
  if (!unknown && targets.length === 0)
21488
21561
  return { writes: false, targets: null };
21489
21562
  return { writes: true, targets: unknown ? null : targets };
21490
- }, cache2, planKeyOf = (root, plans) => [...plans].map((file) => fileSignature(path26.resolve(root, file)) ?? "-").join("\x00"), gateFor = (cwd) => {
21563
+ }, cache2, planKeyOf = (root, plans) => [...plans].map((file) => fileSignature(path27.resolve(root, file)) ?? "-").join("\x00"), gateFor = (cwd) => {
21491
21564
  const store = new TaskStore(cwd);
21492
21565
  const listed = store.listTaskIndex();
21493
21566
  if (!listed.ok)
@@ -21540,14 +21613,14 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21540
21613
  return [];
21541
21614
  if (sub === "stash" && ["list", "show"].includes(rest[0] ?? ""))
21542
21615
  return [];
21543
- return [path26.resolve(cwd, invocation.dir ?? ".")];
21616
+ return [path27.resolve(cwd, invocation.dir ?? ".")];
21544
21617
  });
21545
21618
  }, CD2, PUSHD2, POPD2, cdInto = (dir, words) => {
21546
21619
  const named = words.slice(1).find((word) => !word.startsWith("-") || word === "-");
21547
21620
  const target = named === undefined ? undefined : homeExpanded(named);
21548
21621
  if (dir === undefined || target === "-" || target && /^~|[$`*?]/.test(target))
21549
21622
  return;
21550
- return target === undefined ? os10.homedir() : path26.resolve(dir, target);
21623
+ return target === undefined ? os10.homedir() : path27.resolve(dir, target);
21551
21624
  }, quoteWord2 = (word) => /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replaceAll("'", "'\\''")}'`, homeExpanded = (file) => {
21552
21625
  const match = /^(?:~|\$HOME|\$\{HOME\})(?=\/|$)/.exec(file);
21553
21626
  return match ? (process.env.HOME || os10.homedir()) + file.slice(match[0].length) : file;
@@ -21558,7 +21631,7 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21558
21631
  const groups = [];
21559
21632
  const at = (file) => {
21560
21633
  const home = homeExpanded(file);
21561
- return path26.isAbsolute(home) ? home : dir === undefined ? null : path26.resolve(dir, home);
21634
+ return path27.isAbsolute(home) ? home : dir === undefined ? null : path27.resolve(dir, home);
21562
21635
  };
21563
21636
  for (const segment of segmentsOf(command, dialect)) {
21564
21637
  if (segment.group === "open") {
@@ -21599,7 +21672,7 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21599
21672
  const edits = editsOf(segment.words);
21600
21673
  if (edits === null) {
21601
21674
  if (dir !== undefined)
21602
- targets.push(path26.join(dir, DIR_TARGET));
21675
+ targets.push(path27.join(dir, DIR_TARGET));
21603
21676
  } else
21604
21677
  for (const file of edits) {
21605
21678
  const resolved = at(file);
@@ -21607,7 +21680,7 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21607
21680
  targets.push(resolved);
21608
21681
  }
21609
21682
  if (dir !== undefined && workitInvocations(segment.words.map(quoteWord2).join(" "), "posix").some((args) => args[0] === "git" && MUTATING_WORKIT_GIT.has(args[1] ?? "") && !inert(args.slice(2), "")))
21610
- targets.push(path26.join(dir, DIR_TARGET));
21683
+ targets.push(path27.join(dir, DIR_TARGET));
21611
21684
  }
21612
21685
  return targets;
21613
21686
  }, overridden = (command, dialect) => {
@@ -21630,7 +21703,7 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21630
21703
  }, guarded = (targets) => {
21631
21704
  const seen = new Set;
21632
21705
  return targets.filter((target) => {
21633
- const dir = path26.dirname(target);
21706
+ const dir = path27.dirname(target);
21634
21707
  if (seen.has(dir))
21635
21708
  return false;
21636
21709
  seen.add(dir);
@@ -21648,13 +21721,13 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
21648
21721
  }, claimAll = (owner, targets, deps) => {
21649
21722
  for (const target of guarded(targets))
21650
21723
  claimLiveSession(target, owner, deps);
21651
- }, liveTargets = (cwd, paths) => paths?.length ? paths.map((file) => path26.resolve(cwd, file)) : [path26.join(cwd, DIR_TARGET)], issuedTarget = (cwd, targets) => {
21724
+ }, liveTargets = (cwd, paths) => paths?.length ? paths.map((file) => path27.resolve(cwd, file)) : [path27.join(cwd, DIR_TARGET)], issuedTarget = (cwd, targets) => {
21652
21725
  const state = resolveStateDir();
21653
21726
  const found = targets.find((target) => underIssued(state, cwd, homeExpanded(target), process.platform, canonical2));
21654
21727
  return found ?? null;
21655
21728
  }, underIssued = (state, cwd, target, platform = process.platform, real = (file) => file) => {
21656
21729
  const win = platform === "win32";
21657
- const p = win ? path26.win32 : path26.posix;
21730
+ const p = win ? path27.win32 : path27.posix;
21658
21731
  const fold = (value) => win || platform === "darwin" ? value.toLowerCase() : value;
21659
21732
  const named = win ? target.replace(/^\/([a-zA-Z])(?=\/|$)/, "$1:") : target;
21660
21733
  const relative = p.relative(fold(real(p.resolve(state))), fold(real(p.resolve(cwd, named))));
@@ -22111,9 +22184,9 @@ var init_skill_nudge = __esm(() => {
22111
22184
 
22112
22185
  // packages/workit-core/src/hooks/hosts/fields.ts
22113
22186
  import { existsSync as existsSync7, realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
22114
- import path27 from "node:path";
22187
+ import path28 from "node:path";
22115
22188
  var isRecord6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), nonEmpty2 = (value) => typeof value === "string" && value.trim() !== "", optionalText = (value) => typeof value === "string" ? value : null, existingDirectory = (value) => {
22116
- if (!nonEmpty2(value) || !path27.isAbsolute(value) || !existsSync7(value))
22189
+ if (!nonEmpty2(value) || !path28.isAbsolute(value) || !existsSync7(value))
22117
22190
  return null;
22118
22191
  try {
22119
22192
  return statSync2(value).isDirectory() ? realpathSync6(value) : null;
@@ -22177,8 +22250,119 @@ var init_fields = __esm(() => {
22177
22250
  PATCH_HEADER = /^[ \t]*\*\*\* (?:(?:Add|Update|Delete) File|Move to): (.+)$/gm;
22178
22251
  });
22179
22252
 
22253
+ // packages/workit-core/src/hooks/standing.ts
22254
+ import fs22 from "node:fs";
22255
+ import path29 from "node:path";
22256
+ var readPlans = (store) => {
22257
+ const dir = path29.join(store, "fanouts");
22258
+ let names;
22259
+ try {
22260
+ names = fs22.readdirSync(dir).filter((name) => name.endsWith(".json"));
22261
+ } catch {
22262
+ return [];
22263
+ }
22264
+ const plans = [];
22265
+ for (const name of names) {
22266
+ try {
22267
+ const raw = JSON.parse(fs22.readFileSync(path29.join(dir, name), "utf8"));
22268
+ if (typeof raw.name !== "string" || !Array.isArray(raw.slices))
22269
+ continue;
22270
+ const texts = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string" && item !== "") : [];
22271
+ plans.push({
22272
+ name: raw.name,
22273
+ leads: texts([raw.leadSession, ...texts(raw.formerLeads)]),
22274
+ branches: texts(raw.slices.map((slice) => slice && typeof slice === "object" ? slice.branch : null))
22275
+ });
22276
+ } catch {}
22277
+ }
22278
+ return plans;
22279
+ }, leadOf2 = (input) => input.session.parentId ?? (input.session.agentId ? input.session.id : null) ?? (input.session.id.includes(":") ? input.session.id.split(":")[0] : null), worksFor = (plan, input, branch) => {
22280
+ const session = input.session.id;
22281
+ if (plan.leads.includes(session) && !input.session.agentId)
22282
+ return false;
22283
+ const lead = leadOf2(input);
22284
+ if (lead && plan.leads.includes(lead))
22285
+ return true;
22286
+ if (plan.leads.some((each) => session.startsWith(`${each}-w-`)))
22287
+ return true;
22288
+ const current = branch();
22289
+ return current !== null && plan.branches.includes(current);
22290
+ }, standingFor = (input, store, rev) => {
22291
+ const orders = new Map;
22292
+ const ledger = readLedger(input.cwd);
22293
+ const rows = ledger.ok ? ledger.value.rows : [];
22294
+ let branch;
22295
+ const lazyBranch = () => branch === undefined ? branch = currentBranch(input.cwd) : branch;
22296
+ for (const plan of readPlans(store))
22297
+ if (worksFor(plan, input, lazyBranch))
22298
+ for (const row of activeStanding(rows, plan.name, plan.leads.length ? plan.leads : null))
22299
+ orders.set(row.id, row);
22300
+ return { rev, orders, rows };
22301
+ }, located = (input) => {
22302
+ const store = input.session.id ? gitStoreDir(input.cwd) : null;
22303
+ const rev = store ? readStandingRev(store) : null;
22304
+ if (!store || rev === null)
22305
+ return null;
22306
+ return { store, rev, file: standingSeenFile(store, input.session.id, input.session.agentId) };
22307
+ }, seedStanding = (input) => {
22308
+ try {
22309
+ const where = located(input);
22310
+ if (!where)
22311
+ return;
22312
+ const now = standingFor(input, where.store, where.rev);
22313
+ writeStandingSeen(where.file, { rev: where.rev, ids: [...now.orders.keys()] });
22314
+ } catch {}
22315
+ }, fanoutOf = (row) => typeof row.fanout === "string" ? row.fanout : "?", changedSince = (now, ids) => {
22316
+ const known = new Set(ids);
22317
+ const added = [...now.orders.values()].filter((row) => !known.has(row.id));
22318
+ const byId = new Map(now.rows.map((row) => [row.id, row]));
22319
+ const dropped = ids.filter((id) => !now.orders.has(id)).map((id) => byId.get(id)).filter((row) => row !== undefined);
22320
+ if (!added.length && !dropped.length)
22321
+ return null;
22322
+ const fanouts = [...new Set([...added, ...dropped].map(fanoutOf))].join(", ");
22323
+ const lines = [
22324
+ `Workit: the lead changed the standing orders for fanout ${fanouts} while you run. They apply to you now and override your brief's STANDING list.`,
22325
+ ...added.map((row) => ` - new: ${String(row.what)}`),
22326
+ ...dropped.map((row) => ` - no longer in force: ${String(row.what)}${row.stop ? " (the stop is lifted: continue your brief)" : ""}`)
22327
+ ];
22328
+ if (added.some((row) => row.stop === true))
22329
+ lines.push("Stop now: make no further changes, close what you opened, and report to the lead with your branch, head SHA, what is done and what is not.");
22330
+ return lines.join(`
22331
+ `);
22332
+ }, standingDelta = (input) => {
22333
+ try {
22334
+ const where = located(input);
22335
+ if (!where)
22336
+ return null;
22337
+ const seen = readStandingSeen(where.file);
22338
+ if (seen.rev === where.rev)
22339
+ return null;
22340
+ const now = standingFor(input, where.store, where.rev);
22341
+ writeStandingSeen(where.file, { rev: where.rev, ids: [...now.orders.keys()] });
22342
+ return changedSince(now, seen.ids);
22343
+ } catch {
22344
+ return null;
22345
+ }
22346
+ }, sinceStart;
22347
+ var init_standing = __esm(() => {
22348
+ init_rev();
22349
+ init_ledger();
22350
+ init_standing_signal();
22351
+ sinceStart = new Map;
22352
+ });
22353
+
22180
22354
  // packages/workit-core/src/hooks/handle.ts
22181
22355
  function handleHook(input, deps) {
22356
+ const decision = decide(input, deps);
22357
+ if (deps.descriptor.transport !== "hook-process" || !PRE_TOOL.has(input.event.kind) || decision.kind === "deny")
22358
+ return decision;
22359
+ const delta = standingDelta(input);
22360
+ if (!delta)
22361
+ return decision;
22362
+ return decision.kind === "rewrite" ? { ...decision, text: [decision.text, delta].filter(Boolean).join(`
22363
+ `) } : withContextLine(decision, delta);
22364
+ }
22365
+ function decide(input, deps) {
22182
22366
  const { descriptor } = deps;
22183
22367
  const event = input.event;
22184
22368
  switch (event.kind) {
@@ -22255,6 +22439,7 @@ function handleHook(input, deps) {
22255
22439
  case "write.pre":
22256
22440
  return usable2(descriptor.events["write.pre"].support) ? writeGate(input.cwd, event.paths, liveOwner(input, descriptor.transport)) : NONE5;
22257
22441
  case "subagent.start":
22442
+ seedStanding({ ...input, session: { ...input.session, agentId: event.agentId } });
22258
22443
  return {
22259
22444
  kind: "context",
22260
22445
  text: subagentStartText(input, descriptor, event)
@@ -22304,7 +22489,7 @@ ${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
22304
22489
  const line = verdictCommand({ branch: judgeBranch(cwd), judge, session: own, token });
22305
22490
  const pick = judge === "verifier" ? ", --kind live when you drove the real surface" : "";
22306
22491
  return `${readOnly} Its own Workit session is ${own}, so the ledger tells its verdicts apart from the author's. Record the verdict with exactly this command (pick the result${pick}, name the candidate branch if it differs, say what you ran): \`${line}\`.${token ? " The token is this subagent's alone: never write it into a report, a file or a commit. --token needs a workit CLI at least as new as this plugin; if the CLI answers that --token is an unknown option, update the workit CLI (workit upgrade --cli) and record again." : ""}`;
22307
- }, failureDecision = (descriptor, event, error) => {
22492
+ }, PRE_TOOL, failureDecision = (descriptor, event, error) => {
22308
22493
  if (event === "shell.pre" || event === "tool.pre" || event === "write.pre")
22309
22494
  return descriptor.shellPolicy.failClosed ? { kind: "deny", reason: error, unblock: null } : NONE5;
22310
22495
  if (event === "session.start" || event === "subagent.start")
@@ -22341,6 +22526,7 @@ var init_handle = __esm(() => {
22341
22526
  init_policy();
22342
22527
  init_raw_git();
22343
22528
  init_skill_nudge();
22529
+ init_standing();
22344
22530
  init_stop();
22345
22531
  init_live_session();
22346
22532
  init_write_gate();
@@ -22352,18 +22538,19 @@ var init_handle = __esm(() => {
22352
22538
  reviewer: "judge"
22353
22539
  };
22354
22540
  CLAUDE_WORKTREE = /[\\/]\.claude[\\/]worktrees[\\/]/;
22541
+ PRE_TOOL = new Set(["shell.pre", "write.pre", "tool.pre"]);
22355
22542
  });
22356
22543
 
22357
22544
  // packages/workit-core/src/hooks/deadline.ts
22358
22545
  import { appendFileSync, mkdirSync as mkdirSync3 } from "node:fs";
22359
- import path28 from "node:path";
22546
+ import path30 from "node:path";
22360
22547
  var HOOK_SKIP_TEXT = "workit context skipped: host under load", HOOK_DEADLINE_MS = 8000, HOST_DEADLINES, HOOK_SKIPS_FILE = "hook-skips.jsonl", override = (env) => {
22361
22548
  const value = Number(env.WORKIT_HOOK_DEADLINE_MS);
22362
22549
  return Number.isFinite(value) && value > 0 ? value : null;
22363
22550
  }, hookDeadlineMs = (env, host = "", native) => {
22364
22551
  const row = HOST_DEADLINES[host];
22365
22552
  return override(env) ?? (row ? native === undefined ? Math.min(...Object.values(row)) : row[native] ?? row[""] : HOOK_DEADLINE_MS);
22366
- }, skipsFile = (stateDir) => path28.join(stateDir, HOOK_SKIPS_FILE), recordHookSkip = (skip, stateDir = resolveStateDir()) => {
22553
+ }, skipsFile = (stateDir) => path30.join(stateDir, HOOK_SKIPS_FILE), recordHookSkip = (skip, stateDir = resolveStateDir()) => {
22367
22554
  try {
22368
22555
  mkdirSync3(stateDir, { recursive: true });
22369
22556
  appendFileSync(skipsFile(stateDir), `${JSON.stringify(skip)}
@@ -23007,8 +23194,8 @@ var init_codex = __esm(() => {
23007
23194
  });
23008
23195
 
23009
23196
  // packages/workit-core/src/hooks/hosts/cursor.ts
23010
- import fs21 from "node:fs";
23011
- import path29 from "node:path";
23197
+ import fs23 from "node:fs";
23198
+ import path31 from "node:path";
23012
23199
  var undocumented, none, CURSOR_DESCRIPTOR, EVENTS3, parseCursorHookInput = (value) => {
23013
23200
  if (!isRecord6(value) || !Object.hasOwn(EVENTS3, String(value.hook_event_name)))
23014
23201
  return { ok: false, error: "hook_event_name is required" };
@@ -23089,17 +23276,17 @@ var undocumented, none, CURSOR_DESCRIPTOR, EVENTS3, parseCursorHookInput = (valu
23089
23276
  };
23090
23277
  }
23091
23278
  }, TRANSCRIPT_TAIL_BYTES, lastAssistantText = (file) => {
23092
- if (!file || !path29.isAbsolute(file))
23279
+ if (!file || !path31.isAbsolute(file))
23093
23280
  return null;
23094
23281
  try {
23095
- const size = fs21.statSync(file).size;
23282
+ const size = fs23.statSync(file).size;
23096
23283
  const start = Math.max(0, size - TRANSCRIPT_TAIL_BYTES);
23097
23284
  const buffer = Buffer.alloc(size - start);
23098
- const fd = fs21.openSync(file, "r");
23285
+ const fd = fs23.openSync(file, "r");
23099
23286
  try {
23100
- fs21.readSync(fd, buffer, 0, buffer.length, start);
23287
+ fs23.readSync(fd, buffer, 0, buffer.length, start);
23101
23288
  } finally {
23102
- fs21.closeSync(fd);
23289
+ fs23.closeSync(fd);
23103
23290
  }
23104
23291
  const lines = buffer.toString("utf8").split(`
23105
23292
  `);
@@ -23125,7 +23312,7 @@ var undocumented, none, CURSOR_DESCRIPTOR, EVENTS3, parseCursorHookInput = (valu
23125
23312
  } catch {
23126
23313
  return null;
23127
23314
  }
23128
- }, within2 = (root, dir) => dir === root || dir.startsWith(root.endsWith(path29.sep) ? root : `${root}${path29.sep}`), hookCwd = (input) => {
23315
+ }, within2 = (root, dir) => dir === root || dir.startsWith(root.endsWith(path31.sep) ? root : `${root}${path31.sep}`), hookCwd = (input) => {
23129
23316
  const cwd = existingDirectory(input.cwd);
23130
23317
  if (cwd && input.hook_event_name === "beforeShellExecution")
23131
23318
  return cwd;
@@ -23359,6 +23546,7 @@ var init_hooks = __esm(async () => {
23359
23546
  init_raw_git();
23360
23547
  init_skill_nudge();
23361
23548
  init_fields();
23549
+ init_standing();
23362
23550
  init_handle();
23363
23551
  init_claude_code();
23364
23552
  init_codex();