@brainervirus/workit-cursor 8.20.0 → 8.21.2

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.
@@ -8389,7 +8389,7 @@ import { realpathSync as realpathSync4 } from "node:fs";
8389
8389
 
8390
8390
  // packages/workit-core/src/core/policy/derive.ts
8391
8391
  import { existsSync as existsSync2 } from "node:fs";
8392
- import path9 from "node:path";
8392
+ import path10 from "node:path";
8393
8393
 
8394
8394
  // packages/workit-core/src/git/rev.ts
8395
8395
  import { spawnSync } from "node:child_process";
@@ -8574,9 +8574,9 @@ function pushRemoteName(cwd, branch) {
8574
8574
 
8575
8575
  // packages/workit-core/src/ledger.ts
8576
8576
  import { spawnSync as spawnSync8 } from "node:child_process";
8577
- import { createHash as createHash8, randomBytes as randomBytes2 } from "node:crypto";
8578
- import fs6 from "node:fs";
8579
- import path8 from "node:path";
8577
+ import { createHash as createHash9, randomBytes as randomBytes2 } from "node:crypto";
8578
+ import fs7 from "node:fs";
8579
+ import path9 from "node:path";
8580
8580
 
8581
8581
  // packages/workit-core/src/core/store-lock.ts
8582
8582
  import { spawnSync as spawnSync3 } from "node:child_process";
@@ -10764,6 +10764,61 @@ function issuedBinding(cwd, claimed) {
10764
10764
  }
10765
10765
  var OWN_CHILD_SHELL = new Set(["opencode", "pi"]);
10766
10766
 
10767
+ // packages/workit-core/src/hooks/standing-signal.ts
10768
+ import { createHash as createHash8 } from "node:crypto";
10769
+ import fs6 from "node:fs";
10770
+ import path8 from "node:path";
10771
+ var gitStoreDir = (cwd) => {
10772
+ try {
10773
+ for (let dir = path8.resolve(cwd);; dir = path8.dirname(dir)) {
10774
+ const dotGit = path8.join(dir, ".git");
10775
+ if (fs6.existsSync(dotGit)) {
10776
+ let gitDir = dotGit;
10777
+ if (fs6.statSync(dotGit).isFile()) {
10778
+ const target = /^gitdir:\s*(.+)$/mu.exec(fs6.readFileSync(dotGit, "utf8"))?.[1]?.trim();
10779
+ if (!target)
10780
+ return null;
10781
+ gitDir = path8.resolve(dir, target);
10782
+ const common = path8.join(gitDir, "commondir");
10783
+ if (fs6.existsSync(common))
10784
+ gitDir = path8.resolve(gitDir, fs6.readFileSync(common, "utf8").trim());
10785
+ }
10786
+ return path8.join(gitDir, "workit");
10787
+ }
10788
+ if (path8.dirname(dir) === dir)
10789
+ return null;
10790
+ }
10791
+ } catch {
10792
+ return null;
10793
+ }
10794
+ };
10795
+ var standingRevFile = (store) => path8.join(store, "standing", "rev");
10796
+ var standingSeenFile = (store, session, agentId) => path8.join(store, "standing", "seen", `${createHash8("sha256").update(`${session}\x00${agentId ?? ""}`).digest("hex").slice(0, 32)}.json`);
10797
+ var readStandingRev = (store) => {
10798
+ try {
10799
+ return fs6.readFileSync(standingRevFile(store), "utf8").trim() || null;
10800
+ } catch {
10801
+ return null;
10802
+ }
10803
+ };
10804
+ var readStandingSeen = (file) => {
10805
+ try {
10806
+ const value = JSON.parse(fs6.readFileSync(file, "utf8"));
10807
+ return {
10808
+ rev: typeof value.rev === "string" ? value.rev : null,
10809
+ ids: Array.isArray(value.ids) ? value.ids.filter((id) => typeof id === "string") : []
10810
+ };
10811
+ } catch {
10812
+ return { rev: null, ids: [] };
10813
+ }
10814
+ };
10815
+ var writeStandingSeen = (file, seen) => {
10816
+ try {
10817
+ fs6.mkdirSync(path8.dirname(file), { recursive: true });
10818
+ fs6.writeFileSync(file, JSON.stringify(seen));
10819
+ } catch {}
10820
+ };
10821
+
10767
10822
  // packages/workit-core/src/ledger.ts
10768
10823
  var LEDGER_VERSION = 1;
10769
10824
  var MAX_LINE_BYTES = 4096;
@@ -10874,7 +10929,7 @@ function diffHash(cwd, base, head) {
10874
10929
  ], GIT_TIMEOUTS.worktree);
10875
10930
  if (!diff.ok || !diff.stdout)
10876
10931
  return null;
10877
- const hash = createHash8("sha256");
10932
+ const hash = createHash9("sha256");
10878
10933
  for (const line of diff.stdout.split(`
10879
10934
  `)) {
10880
10935
  if (line.startsWith("index "))
@@ -10886,14 +10941,14 @@ function diffHash(cwd, base, head) {
10886
10941
  return `sha256:${hash.digest("hex")}`;
10887
10942
  }
10888
10943
  function storeRoot(cwd) {
10889
- const location = resolveStore(path8.resolve(cwd));
10944
+ const location = resolveStore(path9.resolve(cwd));
10890
10945
  if (location instanceof Error)
10891
10946
  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");
10892
10947
  return { ok: true, value: { root: location.dir, shared: location.shared } };
10893
10948
  }
10894
10949
  function ledgerPath(cwd) {
10895
10950
  const root = storeRoot(cwd);
10896
- return root.ok ? { ok: true, value: path8.join(root.value.root, "ledger", "ledger.jsonl") } : root;
10951
+ return root.ok ? { ok: true, value: path9.join(root.value.root, "ledger", "ledger.jsonl") } : root;
10897
10952
  }
10898
10953
  var newId2 = () => `${Date.now().toString(36)}-${randomBytes2(6).toString("hex")}`;
10899
10954
  var NETWORK_FS_TYPES = new Set([
@@ -10913,7 +10968,7 @@ var onNetworkFs = (dir) => {
10913
10968
  if (process.platform !== "linux")
10914
10969
  return false;
10915
10970
  try {
10916
- return isNetworkFsType(fs6.statfsSync(dir).type);
10971
+ return isNetworkFsType(fs7.statfsSync(dir).type);
10917
10972
  } catch {
10918
10973
  return false;
10919
10974
  }
@@ -10923,15 +10978,15 @@ var LOCK_STALE_MS = 30000;
10923
10978
  var LOCK_OWNER = "owner";
10924
10979
  var lockToken = (lock) => {
10925
10980
  try {
10926
- return fs6.readFileSync(path8.join(lock, LOCK_OWNER), "utf8");
10981
+ return fs7.readFileSync(path9.join(lock, LOCK_OWNER), "utf8");
10927
10982
  } catch {
10928
10983
  return null;
10929
10984
  }
10930
10985
  };
10931
10986
  var lockAgeMs = (lock) => {
10932
- for (const target of [path8.join(lock, LOCK_OWNER), lock]) {
10987
+ for (const target of [path9.join(lock, LOCK_OWNER), lock]) {
10933
10988
  try {
10934
- return Date.now() - fs6.statSync(target).mtimeMs;
10989
+ return Date.now() - fs7.statSync(target).mtimeMs;
10935
10990
  } catch {}
10936
10991
  }
10937
10992
  return null;
@@ -10939,14 +10994,14 @@ var lockAgeMs = (lock) => {
10939
10994
  var ledgerLock = {
10940
10995
  acquire(lock) {
10941
10996
  try {
10942
- fs6.mkdirSync(lock);
10997
+ fs7.mkdirSync(lock);
10943
10998
  } catch (error) {
10944
10999
  if (error.code === "EEXIST")
10945
11000
  return null;
10946
11001
  throw error;
10947
11002
  }
10948
11003
  const token = `${process.pid}-${randomBytes2(8).toString("hex")}`;
10949
- fs6.writeFileSync(path8.join(lock, LOCK_OWNER), token);
11004
+ fs7.writeFileSync(path9.join(lock, LOCK_OWNER), token);
10950
11005
  return token;
10951
11006
  },
10952
11007
  release(lock, token) {
@@ -10954,35 +11009,35 @@ var ledgerLock = {
10954
11009
  return false;
10955
11010
  const tomb = `${lock}.release-${randomBytes2(6).toString("hex")}`;
10956
11011
  try {
10957
- fs6.renameSync(lock, tomb);
11012
+ fs7.renameSync(lock, tomb);
10958
11013
  } catch {
10959
11014
  return false;
10960
11015
  }
10961
11016
  if (lockToken(tomb) !== token) {
10962
11017
  try {
10963
- fs6.renameSync(tomb, lock);
11018
+ fs7.renameSync(tomb, lock);
10964
11019
  } catch {}
10965
11020
  return false;
10966
11021
  }
10967
- fs6.rmSync(tomb, { recursive: true, force: true });
11022
+ fs7.rmSync(tomb, { recursive: true, force: true });
10968
11023
  return true;
10969
11024
  },
10970
11025
  token: lockToken,
10971
11026
  reap(lock, observed) {
10972
11027
  const tomb = `${lock}.reap-${randomBytes2(6).toString("hex")}`;
10973
11028
  try {
10974
- fs6.renameSync(lock, tomb);
11029
+ fs7.renameSync(lock, tomb);
10975
11030
  } catch {
10976
11031
  return false;
10977
11032
  }
10978
11033
  if (lockToken(tomb) === observed) {
10979
- fs6.rmSync(tomb, { recursive: true, force: true });
11034
+ fs7.rmSync(tomb, { recursive: true, force: true });
10980
11035
  return true;
10981
11036
  }
10982
11037
  try {
10983
- fs6.renameSync(tomb, lock);
11038
+ fs7.renameSync(tomb, lock);
10984
11039
  } catch {
10985
- fs6.rmSync(tomb, { recursive: true, force: true });
11040
+ fs7.rmSync(tomb, { recursive: true, force: true });
10986
11041
  }
10987
11042
  return false;
10988
11043
  }
@@ -11009,14 +11064,14 @@ function withLedgerLock(file, fn, waitMs = hostAwareLockTimeout(LOCK_WAIT_MS)) {
11009
11064
  ledgerLock.release(lock, token);
11010
11065
  }
11011
11066
  }
11012
- var sha2562 = (text) => createHash8("sha256").update(text).digest("hex");
11067
+ var sha2562 = (text) => createHash9("sha256").update(text).digest("hex");
11013
11068
  var chainHash = (prevHash, body) => sha2562(`${prevHash ?? ""}
11014
11069
  ${body}`);
11015
11070
  var TAIL_BYTES = 64 * 1024;
11016
11071
  var lastLine = (fd, size) => {
11017
11072
  for (let span = Math.min(size, TAIL_BYTES);span > 0; span = Math.min(size, span * 2)) {
11018
11073
  const buffer = Buffer.alloc(span);
11019
- fs6.readSync(fd, buffer, 0, span, size - span);
11074
+ fs7.readSync(fd, buffer, 0, span, size - span);
11020
11075
  const end = buffer.lastIndexOf(10);
11021
11076
  if (end < 0) {
11022
11077
  if (span === size)
@@ -11047,21 +11102,21 @@ var lastLine = (fd, size) => {
11047
11102
  };
11048
11103
  var tighten = (fd) => {
11049
11104
  try {
11050
- if ((fs6.fstatSync(fd).mode & 63) !== 0)
11051
- fs6.fchmodSync(fd, 384);
11105
+ if ((fs7.fstatSync(fd).mode & 63) !== 0)
11106
+ fs7.fchmodSync(fd, 384);
11052
11107
  } catch {}
11053
11108
  };
11054
11109
  function appendLine(file, build, options) {
11055
11110
  const write = () => {
11056
- const fd = fs6.openSync(file, "a+", 384);
11111
+ const fd = fs7.openSync(file, "a+", 384);
11057
11112
  try {
11058
11113
  if (process.platform !== "win32")
11059
11114
  tighten(fd);
11060
- const size = fs6.fstatSync(fd).size;
11115
+ const size = fs7.fstatSync(fd).size;
11061
11116
  let fence = "";
11062
11117
  if (size > 0) {
11063
11118
  const last = Buffer.alloc(1);
11064
- fs6.readSync(fd, last, 0, 1, size - 1);
11119
+ fs7.readSync(fd, last, 0, 1, size - 1);
11065
11120
  if (last[0] !== 10)
11066
11121
  fence = `
11067
11122
  `;
@@ -11070,17 +11125,17 @@ function appendLine(file, build, options) {
11070
11125
  if (!line.ok)
11071
11126
  return line;
11072
11127
  const bytes = Buffer.from(fence + line.value);
11073
- const written = fs6.writeSync(fd, bytes);
11128
+ const written = fs7.writeSync(fd, bytes);
11074
11129
  if (written !== bytes.length)
11075
11130
  return err("unavailable", `short write to ${file}: ${written} of ${bytes.length} bytes; the row is torn and will be skipped`);
11076
11131
  return { ok: true, value: undefined };
11077
11132
  } finally {
11078
- fs6.closeSync(fd);
11133
+ fs7.closeSync(fd);
11079
11134
  }
11080
11135
  };
11081
11136
  try {
11082
- fs6.mkdirSync(path8.dirname(file), { recursive: true });
11083
- if (!options.forceLock && !onNetworkFs(path8.dirname(file)))
11137
+ fs7.mkdirSync(path9.dirname(file), { recursive: true });
11138
+ if (!options.forceLock && !onNetworkFs(path9.dirname(file)))
11084
11139
  return write();
11085
11140
  const locked = withLedgerLock(file, write);
11086
11141
  return locked ?? err("busy", `ledger lock ${file}.lock is held`, "retry; remove the .lock directory if no workit process is running");
@@ -11153,8 +11208,8 @@ function readLedger(cwd, options = {}) {
11153
11208
  let text = "";
11154
11209
  let stat = null;
11155
11210
  try {
11156
- stat = fs6.statSync(file.value);
11157
- text = fs6.readFileSync(file.value, "utf8");
11211
+ stat = fs7.statSync(file.value);
11212
+ text = fs7.readFileSync(file.value, "utf8");
11158
11213
  } catch (error) {
11159
11214
  if (error.code === "ENOENT")
11160
11215
  return {
@@ -11289,7 +11344,7 @@ function ledgerTampering(cwd) {
11289
11344
  if (!file.ok)
11290
11345
  return [];
11291
11346
  try {
11292
- const stat = fs6.statSync(file.value);
11347
+ const stat = fs7.statSync(file.value);
11293
11348
  const cached = tamperCache.get(file.value);
11294
11349
  if (cached && cached.size === stat.size && cached.stamp === fileStamp(stat))
11295
11350
  return cached.breaks;
@@ -11620,6 +11675,28 @@ function checkVerdicts(cwd, branch, ledgerRows) {
11620
11675
  warnings
11621
11676
  };
11622
11677
  }
11678
+ var fromLead = (row, leads) => leads === null || row.actor.session !== null && leads.includes(row.actor.session);
11679
+ function activeStanding(rows, fanout, leads = null) {
11680
+ const active = [];
11681
+ for (const row of rows) {
11682
+ if (row.fanout !== fanout || !fromLead(row, leads))
11683
+ continue;
11684
+ if (row.type === "standing" && typeof row.what === "string" && row.what.trim()) {
11685
+ if (!row.superseded)
11686
+ active.push(row);
11687
+ } else if (row.type === "standing.cleared") {
11688
+ const target = str(row.target);
11689
+ if (target === null)
11690
+ active.length = 0;
11691
+ else {
11692
+ const index = active.findIndex((order) => order.id === target);
11693
+ if (index >= 0)
11694
+ active.splice(index, 1);
11695
+ }
11696
+ }
11697
+ }
11698
+ return active;
11699
+ }
11623
11700
  var OBSERVED_ONLY = new Set([
11624
11701
  "check",
11625
11702
  "merge.unverified",
@@ -11768,7 +11845,7 @@ var productDecision = (task, ledger) => {
11768
11845
  };
11769
11846
  };
11770
11847
  var planRecorded = (task, root) => {
11771
- const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync2(path9.resolve(root, ref.path)));
11848
+ const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync2(path10.resolve(root, ref.path)));
11772
11849
  if (cited)
11773
11850
  return {
11774
11851
  met: true,
@@ -12384,7 +12461,7 @@ var judgeInputSummary = (raw) => {
12384
12461
 
12385
12462
  // packages/workit-core/src/autonomy.ts
12386
12463
  import os4 from "node:os";
12387
- import path10 from "node:path";
12464
+ import path11 from "node:path";
12388
12465
  var accountHome = () => {
12389
12466
  try {
12390
12467
  return os4.userInfo().homedir;
@@ -12393,10 +12470,10 @@ var accountHome = () => {
12393
12470
  }
12394
12471
  };
12395
12472
  var grantsHome = { resolve: accountHome };
12396
- var grantsDir = () => path10.join(grantsHome.resolve(), ".config", "workit");
12473
+ var grantsDir = () => path11.join(grantsHome.resolve(), ".config", "workit");
12397
12474
  var grantsOverride = () => {
12398
- const configured = path10.resolve(resolveConfigDir());
12399
- 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`;
12475
+ const configured = path11.resolve(resolveConfigDir());
12476
+ 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`;
12400
12477
  };
12401
12478
  var GRANT_KINDS = ["push", "pr", "merge", "release", "rerun"];
12402
12479
  var DEFAULT_GRANTS = Object.freeze({
@@ -12520,9 +12597,9 @@ var suggested = (kind) => kind === "merge" ? "verified" : "true";
12520
12597
  var grantHint = (workspace, kind) => `ask the user to run, in their own terminal: workit grant set ${workspace ?? "<workspace>"} ${kind}=${suggested(kind)}`;
12521
12598
 
12522
12599
  // packages/workit-core/src/core/task-store.ts
12523
- import { createHash as createHash10, randomUUID as randomUUID3 } from "node:crypto";
12524
- import * as fs11 from "node:fs";
12525
- import path15 from "node:path";
12600
+ import { createHash as createHash11, randomUUID as randomUUID3 } from "node:crypto";
12601
+ import * as fs12 from "node:fs";
12602
+ import path16 from "node:path";
12526
12603
 
12527
12604
  // node_modules/@openclaw/fs-safe/dist/errors.js
12528
12605
  var OPERATIONAL_CODES = new Set([
@@ -12573,10 +12650,10 @@ function sameFileIdentity(left, right, platform = process.platform) {
12573
12650
  // node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.js
12574
12651
  import { randomBytes as randomBytes3 } from "node:crypto";
12575
12652
  import fsSync from "node:fs";
12576
- import path11 from "node:path";
12653
+ import path12 from "node:path";
12577
12654
 
12578
12655
  // node_modules/@openclaw/fs-safe/dist/bounded-read.js
12579
- import fs7 from "node:fs";
12656
+ import fs8 from "node:fs";
12580
12657
 
12581
12658
  // node_modules/@openclaw/fs-safe/dist/byte-budget.js
12582
12659
  function normalizeMaxBytes(value, options = {}) {
@@ -12613,7 +12690,7 @@ function readFileDescriptorBoundedSync(fd, maxBytes) {
12613
12690
  let total = 0;
12614
12691
  while (true) {
12615
12692
  const length = nextReadLength(total, maxBytes, scratch.length);
12616
- const bytesRead = fs7.readSync(fd, scratch, 0, length, null);
12693
+ const bytesRead = fs8.readSync(fd, scratch, 0, length, null);
12617
12694
  if (bytesRead === 0) {
12618
12695
  return Buffer.concat(chunks, total);
12619
12696
  }
@@ -12622,9 +12699,9 @@ function readFileDescriptorBoundedSync(fd, maxBytes) {
12622
12699
  }
12623
12700
 
12624
12701
  // node_modules/@openclaw/fs-safe/dist/read-open-flags.js
12625
- import fs8 from "node:fs";
12702
+ import fs9 from "node:fs";
12626
12703
  function resolveReadOpenFlags(options) {
12627
- const constants = options?.constants ?? fs8.constants;
12704
+ const constants = options?.constants ?? fs9.constants;
12628
12705
  const noFollow = process.platform !== "win32" && options?.followSymlinks !== true && typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
12629
12706
  const nonBlocking = process.platform !== "win32" && typeof constants.O_NONBLOCK === "number" ? constants.O_NONBLOCK : 0;
12630
12707
  return constants.O_RDONLY | noFollow | nonBlocking;
@@ -12663,13 +12740,13 @@ ${ownershipToken}
12663
12740
  return { raw, ownershipToken };
12664
12741
  }
12665
12742
  function relativeSidecarLockPath(lockRoot, lockPath) {
12666
- const resolved = path11.resolve(lockPath);
12667
- const lexicalRelative = path11.relative(lockRoot.rootDir, resolved);
12668
- const relative = lexicalRelative !== ".." && !lexicalRelative.startsWith(`..${path11.sep}`) && !path11.isAbsolute(lexicalRelative) ? lexicalRelative : path11.relative(lockRoot.rootReal, resolved);
12669
- if (!relative || relative === ".." || relative.startsWith(`..${path11.sep}`) || path11.isAbsolute(relative)) {
12743
+ const resolved = path12.resolve(lockPath);
12744
+ const lexicalRelative = path12.relative(lockRoot.rootDir, resolved);
12745
+ const relative = lexicalRelative !== ".." && !lexicalRelative.startsWith(`..${path12.sep}`) && !path12.isAbsolute(lexicalRelative) ? lexicalRelative : path12.relative(lockRoot.rootReal, resolved);
12746
+ if (!relative || relative === ".." || relative.startsWith(`..${path12.sep}`) || path12.isAbsolute(relative)) {
12670
12747
  throw new FsSafeError("outside-workspace", "sidecar lock path is outside lockRoot");
12671
12748
  }
12672
- return relative.split(path11.sep).join(path11.posix.sep);
12749
+ return relative.split(path12.sep).join(path12.posix.sep);
12673
12750
  }
12674
12751
  function parseSidecarLockPayload(raw, parser) {
12675
12752
  if (parser) {
@@ -12815,8 +12892,8 @@ function getFsSafeLockConfig() {
12815
12892
  }
12816
12893
 
12817
12894
  // node_modules/@openclaw/fs-safe/dist/file-lock-sync.js
12818
- import fs9 from "node:fs";
12819
- import path12 from "node:path";
12895
+ import fs10 from "node:fs";
12896
+ import path13 from "node:path";
12820
12897
 
12821
12898
  // node_modules/@openclaw/fs-safe/dist/timing.js
12822
12899
  function sleepSync(ms) {
@@ -12846,7 +12923,7 @@ function releaseAllSyncHeldLocks() {
12846
12923
  }
12847
12924
  try {
12848
12925
  if (held.fd !== undefined)
12849
- fs9.closeSync(held.fd);
12926
+ fs10.closeSync(held.fd);
12850
12927
  } catch {}
12851
12928
  try {
12852
12929
  removeSidecarLockIfUnchangedSync(held.lockPath, held.snapshot);
@@ -12881,7 +12958,7 @@ function releaseSyncHeldLock(held) {
12881
12958
  if (held.fd !== undefined) {
12882
12959
  const fd = held.fd;
12883
12960
  held.fd = undefined;
12884
- fs9.closeSync(fd);
12961
+ fs10.closeSync(fd);
12885
12962
  }
12886
12963
  removeSidecarLockIfUnchangedSync(held.lockPath, held.snapshot);
12887
12964
  heldLocks.delete(held.normalizedTargetPath);
@@ -12904,29 +12981,29 @@ function createSyncHeldLockHandle(held) {
12904
12981
  };
12905
12982
  }
12906
12983
  function canonicalLockParentSync(parent) {
12907
- return process.platform === "win32" ? fs9.realpathSync.native(parent) : fs9.realpathSync(parent);
12984
+ return process.platform === "win32" ? fs10.realpathSync.native(parent) : fs10.realpathSync(parent);
12908
12985
  }
12909
12986
  function normalizeTargetPath(targetPath) {
12910
- const resolved = path12.resolve(targetPath);
12911
- fs9.mkdirSync(path12.dirname(resolved), { recursive: true });
12987
+ const resolved = path13.resolve(targetPath);
12988
+ fs10.mkdirSync(path13.dirname(resolved), { recursive: true });
12912
12989
  try {
12913
- return path12.join(canonicalLockParentSync(path12.dirname(resolved)), path12.basename(resolved));
12990
+ return path13.join(canonicalLockParentSync(path13.dirname(resolved)), path13.basename(resolved));
12914
12991
  } catch {
12915
12992
  return resolved;
12916
12993
  }
12917
12994
  }
12918
12995
  function boundedLockPath(lockPath, lockRoot) {
12919
- const resolved = path12.resolve(lockPath);
12996
+ const resolved = path13.resolve(lockPath);
12920
12997
  if (!lockRoot)
12921
12998
  return resolved;
12922
12999
  relativeSidecarLockPath(lockRoot, resolved);
12923
- const parent = path12.dirname(resolved);
13000
+ const parent = path13.dirname(resolved);
12924
13001
  const parentReal = canonicalLockParentSync(parent);
12925
- const parentRelative = path12.relative(lockRoot.rootReal, parentReal);
12926
- if (parentRelative === ".." || parentRelative.startsWith(`..${path12.sep}`) || path12.isAbsolute(parentRelative)) {
13002
+ const parentRelative = path13.relative(lockRoot.rootReal, parentReal);
13003
+ if (parentRelative === ".." || parentRelative.startsWith(`..${path13.sep}`) || path13.isAbsolute(parentRelative)) {
12927
13004
  throw new FsSafeError("outside-workspace", "sidecar lock parent is outside lockRoot");
12928
13005
  }
12929
- return path12.join(parentReal, path12.basename(resolved));
13006
+ return path13.join(parentReal, path13.basename(resolved));
12930
13007
  }
12931
13008
  function defaultShouldReclaim(snapshot, staleMs, nowMs) {
12932
13009
  const createdAtMs = sidecarLockPayloadCreatedAtMs(snapshot.payload);
@@ -12936,7 +13013,7 @@ function defaultShouldReclaim(snapshot, staleMs, nowMs) {
12936
13013
  }
12937
13014
  function reclaimGuardExists(reclaimGuardPath) {
12938
13015
  try {
12939
- fs9.lstatSync(reclaimGuardPath);
13016
+ fs10.lstatSync(reclaimGuardPath);
12940
13017
  return true;
12941
13018
  } catch (error) {
12942
13019
  if (error.code === "ENOENT")
@@ -13000,19 +13077,19 @@ function acquireFileLockSync(targetPath, options) {
13000
13077
  const { raw, ownershipToken } = serializeSidecarLockPayload(payload);
13001
13078
  let lockFileCreateDenied = false;
13002
13079
  try {
13003
- const noFollow = process.platform !== "win32" && typeof fs9.constants.O_NOFOLLOW === "number" ? fs9.constants.O_NOFOLLOW : 0;
13080
+ const noFollow = process.platform !== "win32" && typeof fs10.constants.O_NOFOLLOW === "number" ? fs10.constants.O_NOFOLLOW : 0;
13004
13081
  try {
13005
- fd = fs9.openSync(lockPath, fs9.constants.O_WRONLY | fs9.constants.O_CREAT | fs9.constants.O_EXCL | noFollow, 384);
13082
+ fd = fs10.openSync(lockPath, fs10.constants.O_WRONLY | fs10.constants.O_CREAT | fs10.constants.O_EXCL | noFollow, 384);
13006
13083
  } catch (error) {
13007
13084
  lockFileCreateDenied = isTransientLockFileDenial(error, lockPath);
13008
13085
  throw error;
13009
13086
  }
13010
- fs9.writeFileSync(fd, raw, "utf8");
13011
- fs9.fsyncSync(fd);
13087
+ fs10.writeFileSync(fd, raw, "utf8");
13088
+ fs10.fsyncSync(fd);
13012
13089
  const snapshot = {
13013
13090
  raw,
13014
13091
  payload,
13015
- stat: fs9.fstatSync(fd),
13092
+ stat: fs10.fstatSync(fd),
13016
13093
  ownershipToken
13017
13094
  };
13018
13095
  const createdHeld = {
@@ -13047,8 +13124,8 @@ function acquireFileLockSync(targetPath, options) {
13047
13124
  return returnedHandle;
13048
13125
  } catch (error) {
13049
13126
  if (fd !== undefined) {
13050
- const failed = { payload: null, stat: fs9.fstatSync(fd) };
13051
- fs9.closeSync(fd);
13127
+ const failed = { payload: null, stat: fs10.fstatSync(fd) };
13128
+ fs10.closeSync(fd);
13052
13129
  fd = undefined;
13053
13130
  removeSidecarLockIfUnchangedSync(lockPath, failed);
13054
13131
  }
@@ -13097,7 +13174,7 @@ function acquireFileLockSync(targetPath, options) {
13097
13174
  })) {
13098
13175
  let ownsReclaimGuard = false;
13099
13176
  try {
13100
- fs9.mkdirSync(reclaimGuardPath);
13177
+ fs10.mkdirSync(reclaimGuardPath);
13101
13178
  ownsReclaimGuard = true;
13102
13179
  if (removeSidecarLockIfUnchangedSync(lockPath, snapshot))
13103
13180
  continue;
@@ -13110,7 +13187,7 @@ function acquireFileLockSync(targetPath, options) {
13110
13187
  } finally {
13111
13188
  if (ownsReclaimGuard) {
13112
13189
  try {
13113
- fs9.rmdirSync(reclaimGuardPath);
13190
+ fs10.rmdirSync(reclaimGuardPath);
13114
13191
  } catch {}
13115
13192
  }
13116
13193
  }
@@ -13127,13 +13204,13 @@ function acquireFileLockSync(targetPath, options) {
13127
13204
  }
13128
13205
  // packages/workit-core/src/core/package-root.ts
13129
13206
  import { existsSync as existsSync3 } from "node:fs";
13130
- import path13 from "node:path";
13207
+ import path14 from "node:path";
13131
13208
  import { fileURLToPath } from "node:url";
13132
13209
  var packageRoot = () => {
13133
- let dir = path13.dirname(fileURLToPath(import.meta.url));
13210
+ let dir = path14.dirname(fileURLToPath(import.meta.url));
13134
13211
  while (true) {
13135
- const parent = path13.dirname(dir);
13136
- if (existsSync3(path13.join(dir, "package.json")) || parent === dir)
13212
+ const parent = path14.dirname(dir);
13213
+ if (existsSync3(path14.join(dir, "package.json")) || parent === dir)
13137
13214
  return dir;
13138
13215
  dir = parent;
13139
13216
  }
@@ -13141,8 +13218,8 @@ var packageRoot = () => {
13141
13218
 
13142
13219
  // packages/workit-core/src/store/event-log.ts
13143
13220
  import { randomUUID as randomUUID2 } from "node:crypto";
13144
- import fs10 from "node:fs";
13145
- import path14 from "node:path";
13221
+ import fs11 from "node:fs";
13222
+ import path15 from "node:path";
13146
13223
  var EVENT_VERSION = 1;
13147
13224
 
13148
13225
  class LogDamage extends Error {
@@ -13171,7 +13248,7 @@ var parseEvent = (line, file, offset) => {
13171
13248
  function readLog(file, from = 0, expectSeq = null) {
13172
13249
  let fd;
13173
13250
  try {
13174
- fd = fs10.openSync(file, "r");
13251
+ fd = fs11.openSync(file, "r");
13175
13252
  } catch (error) {
13176
13253
  if (error.code === "ENOENT")
13177
13254
  return null;
@@ -13180,13 +13257,13 @@ function readLog(file, from = 0, expectSeq = null) {
13180
13257
  let bytes;
13181
13258
  let size;
13182
13259
  try {
13183
- size = fs10.fstatSync(fd).size;
13260
+ size = fs11.fstatSync(fd).size;
13184
13261
  if (from > size)
13185
13262
  throw new LogDamage(`${file}: shorter than its snapshot`);
13186
13263
  bytes = Buffer.alloc(size - from);
13187
13264
  let read = 0;
13188
13265
  while (read < bytes.length) {
13189
- const got = fs10.readSync(fd, bytes, read, bytes.length - read, from + read);
13266
+ const got = fs11.readSync(fd, bytes, read, bytes.length - read, from + read);
13190
13267
  if (got === 0)
13191
13268
  break;
13192
13269
  read += got;
@@ -13194,7 +13271,7 @@ function readLog(file, from = 0, expectSeq = null) {
13194
13271
  bytes = bytes.subarray(0, read);
13195
13272
  size = from + read;
13196
13273
  } finally {
13197
- fs10.closeSync(fd);
13274
+ fs11.closeSync(fd);
13198
13275
  }
13199
13276
  const events = [];
13200
13277
  let start = 0;
@@ -13219,11 +13296,11 @@ function readLog(file, from = 0, expectSeq = null) {
13219
13296
  }
13220
13297
  var fsyncDirectory = (dir) => {
13221
13298
  try {
13222
- const fd = fs10.openSync(dir, "r");
13299
+ const fd = fs11.openSync(dir, "r");
13223
13300
  try {
13224
- fs10.fsyncSync(fd);
13301
+ fs11.fsyncSync(fd);
13225
13302
  } finally {
13226
- fs10.closeSync(fd);
13303
+ fs11.closeSync(fd);
13227
13304
  }
13228
13305
  } catch (error) {
13229
13306
  if (process.platform !== "win32")
@@ -13233,46 +13310,46 @@ var fsyncDirectory = (dir) => {
13233
13310
  function appendEvent(file, event, validEnd) {
13234
13311
  const line = Buffer.from(`${JSON.stringify(event)}
13235
13312
  `, "utf8");
13236
- const created = !fs10.existsSync(file);
13237
- if (!created && fs10.statSync(file).size !== validEnd) {
13238
- const cut = fs10.openSync(file, "r+");
13313
+ const created = !fs11.existsSync(file);
13314
+ if (!created && fs11.statSync(file).size !== validEnd) {
13315
+ const cut = fs11.openSync(file, "r+");
13239
13316
  try {
13240
- fs10.ftruncateSync(cut, validEnd);
13241
- fs10.fsyncSync(cut);
13317
+ fs11.ftruncateSync(cut, validEnd);
13318
+ fs11.fsyncSync(cut);
13242
13319
  } finally {
13243
- fs10.closeSync(cut);
13320
+ fs11.closeSync(cut);
13244
13321
  }
13245
13322
  }
13246
- const fd = fs10.openSync(file, "a", 384);
13323
+ const fd = fs11.openSync(file, "a", 384);
13247
13324
  try {
13248
13325
  let written = 0;
13249
13326
  while (written < line.length)
13250
- written += fs10.writeSync(fd, line, written, line.length - written);
13251
- fs10.fsyncSync(fd);
13327
+ written += fs11.writeSync(fd, line, written, line.length - written);
13328
+ fs11.fsyncSync(fd);
13252
13329
  } finally {
13253
- fs10.closeSync(fd);
13330
+ fs11.closeSync(fd);
13254
13331
  }
13255
13332
  if (created)
13256
- fsyncDirectory(path14.dirname(file));
13333
+ fsyncDirectory(path15.dirname(file));
13257
13334
  return validEnd;
13258
13335
  }
13259
13336
  function replaceFile(file, bytes, durable) {
13260
13337
  const temporary = `${file}.${process.pid}.${randomUUID2()}.tmp`;
13261
13338
  try {
13262
- const fd = fs10.openSync(temporary, "wx", 384);
13339
+ const fd = fs11.openSync(temporary, "wx", 384);
13263
13340
  try {
13264
- fs10.writeSync(fd, bytes);
13341
+ fs11.writeSync(fd, bytes);
13265
13342
  if (durable)
13266
- fs10.fsyncSync(fd);
13343
+ fs11.fsyncSync(fd);
13267
13344
  } finally {
13268
- fs10.closeSync(fd);
13345
+ fs11.closeSync(fd);
13269
13346
  }
13270
13347
  renameWithRetry(temporary, file);
13271
13348
  if (durable)
13272
- fsyncDirectory(path14.dirname(file));
13349
+ fsyncDirectory(path15.dirname(file));
13273
13350
  } catch (error) {
13274
13351
  try {
13275
- fs10.unlinkSync(temporary);
13352
+ fs11.unlinkSync(temporary);
13276
13353
  } catch {}
13277
13354
  throw error;
13278
13355
  }
@@ -13297,7 +13374,7 @@ var retryTransient = (run) => {
13297
13374
  }
13298
13375
  }
13299
13376
  };
13300
- var renameWithRetry = (from, to) => retryTransient(() => fs10.renameSync(from, to));
13377
+ var renameWithRetry = (from, to) => retryTransient(() => fs11.renameSync(from, to));
13301
13378
 
13302
13379
  // packages/workit-core/src/store/patch.ts
13303
13380
  var isPlainObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -13410,7 +13487,7 @@ var isPatch = (value) => Array.isArray(value) && value.every((op) => {
13410
13487
  });
13411
13488
 
13412
13489
  // packages/workit-core/src/store/reduce.ts
13413
- import { createHash as createHash9 } from "node:crypto";
13490
+ import { createHash as createHash10 } from "node:crypto";
13414
13491
  var OPENING_TYPES = new Set([
13415
13492
  "task.opened",
13416
13493
  "task.imported",
@@ -13439,7 +13516,7 @@ var isObject5 = (value) => typeof value === "object" && value !== null && !Array
13439
13516
  var isKey = (value) => isObject5(value) && typeof value.key === "string" && (value.kind === "branch" || value.kind === "detached" || value.kind === "dir") && (value.branch === null || typeof value.branch === "string");
13440
13517
  var BLOB_REF = "$blob";
13441
13518
  var 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;
13442
- var blobDigest = (value) => createHash9("sha256").update(JSON.stringify(value)).digest("hex");
13519
+ var blobDigest = (value) => createHash10("sha256").update(JSON.stringify(value)).digest("hex");
13443
13520
  var toBlob = (value, blobs) => {
13444
13521
  if (!isObject5(value))
13445
13522
  return value;
@@ -13594,7 +13671,7 @@ var indexEntry = (task, key, legacy, file) => {
13594
13671
  };
13595
13672
  var fileSignature = (file) => {
13596
13673
  try {
13597
- const stat = fs11.statSync(file, { bigint: true });
13674
+ const stat = fs12.statSync(file, { bigint: true });
13598
13675
  return `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}`;
13599
13676
  } catch {
13600
13677
  return null;
@@ -13612,7 +13689,7 @@ var cachedRuntimeVersion = null;
13612
13689
  var runtimeVersion = () => {
13613
13690
  if (cachedRuntimeVersion === null) {
13614
13691
  try {
13615
- const pkg = JSON.parse(fs11.readFileSync(path15.join(packageRoot(), "package.json"), "utf8"));
13692
+ const pkg = JSON.parse(fs12.readFileSync(path16.join(packageRoot(), "package.json"), "utf8"));
13616
13693
  cachedRuntimeVersion = typeof pkg.version === "string" && pkg.version ? pkg.version : "0.0.0";
13617
13694
  } catch {
13618
13695
  cachedRuntimeVersion = "0.0.0";
@@ -13638,14 +13715,14 @@ var isNewerVersion = (candidate, current) => {
13638
13715
  var 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);
13639
13716
  var readText = (file) => {
13640
13717
  try {
13641
- return fs11.readFileSync(file, "utf8");
13718
+ return fs12.readFileSync(file, "utf8");
13642
13719
  } catch {
13643
13720
  return "";
13644
13721
  }
13645
13722
  };
13646
13723
  var REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
13647
13724
  var branchStart = (location, branch, aliases) => {
13648
- const first = readText(path15.join(path15.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
13725
+ const first = readText(path16.join(path16.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
13649
13726
  `, 1)[0];
13650
13727
  const created = REFLOG_LINE.exec(first);
13651
13728
  const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
@@ -13655,7 +13732,7 @@ var branchStart = (location, branch, aliases) => {
13655
13732
  return start;
13656
13733
  if (!location.git)
13657
13734
  return null;
13658
- for (const line of readText(path15.join(location.git.gitDir, "logs", "HEAD")).split(`
13735
+ for (const line of readText(path16.join(location.git.gitDir, "logs", "HEAD")).split(`
13659
13736
  `)) {
13660
13737
  const entry = REFLOG_LINE.exec(line);
13661
13738
  const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
@@ -13665,23 +13742,23 @@ var branchStart = (location, branch, aliases) => {
13665
13742
  }
13666
13743
  return null;
13667
13744
  };
13668
- var refExists = (common, ref) => fs11.existsSync(path15.join(common, ref)) || readText(path15.join(common, "packed-refs")).includes(` ${ref}
13745
+ var refExists = (common, ref) => fs12.existsSync(path16.join(common, ref)) || readText(path16.join(common, "packed-refs")).includes(` ${ref}
13669
13746
  `);
13670
13747
  var origins = new Map;
13671
13748
  var sameDirectoryIdentity = (left, right) => {
13672
- if (!path15.isAbsolute(left) || !path15.isAbsolute(right))
13749
+ if (!path16.isAbsolute(left) || !path16.isAbsolute(right))
13673
13750
  return false;
13674
- const normalizedLeft = path15.resolve(left);
13675
- const normalizedRight = path15.resolve(right);
13751
+ const normalizedLeft = path16.resolve(left);
13752
+ const normalizedRight = path16.resolve(right);
13676
13753
  try {
13677
- const a = fs11.statSync(normalizedLeft, { bigint: true });
13678
- const b = fs11.statSync(normalizedRight, { bigint: true });
13754
+ const a = fs12.statSync(normalizedLeft, { bigint: true });
13755
+ const b = fs12.statSync(normalizedRight, { bigint: true });
13679
13756
  if (!a.isDirectory() || !b.isDirectory())
13680
13757
  return false;
13681
13758
  if (process.platform === "win32" ? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase() : normalizedLeft === normalizedRight)
13682
13759
  return true;
13683
- const canonicalLeft = fs11.realpathSync(normalizedLeft);
13684
- const canonicalRight = fs11.realpathSync(normalizedRight);
13760
+ const canonicalLeft = fs12.realpathSync(normalizedLeft);
13761
+ const canonicalRight = fs12.realpathSync(normalizedRight);
13685
13762
  if (process.platform === "win32" ? canonicalLeft.toLowerCase() === canonicalRight.toLowerCase() : canonicalLeft === canonicalRight)
13686
13763
  return true;
13687
13764
  return a.dev === b.dev && a.ino !== 0n && a.ino === b.ino;
@@ -13718,8 +13795,8 @@ class TaskStore {
13718
13795
  migrationChecked = false;
13719
13796
  compactDue = new Set;
13720
13797
  constructor(root, options = {}) {
13721
- const resolved = path15.resolve(root);
13722
- this.origin = fs11.existsSync(resolved) ? fs11.realpathSync(resolved) : resolved;
13798
+ const resolved = path16.resolve(root);
13799
+ this.origin = fs12.existsSync(resolved) ? fs12.realpathSync(resolved) : resolved;
13723
13800
  this.located = resolveStore(this.origin);
13724
13801
  this.root = checkoutRootOf(this.origin, this.located);
13725
13802
  this.lockTimeoutMs = options.lockTimeoutMs ?? defaultLockTimeout();
@@ -13727,7 +13804,7 @@ class TaskStore {
13727
13804
  this.migrateOnRead = options.migrateOnRead;
13728
13805
  }
13729
13806
  location() {
13730
- if (this.located !== undefined && !(this.located instanceof Error) && !this.located.shared && fs11.existsSync(path15.join(this.root, ".git"))) {
13807
+ if (this.located !== undefined && !(this.located instanceof Error) && !this.located.shared && fs12.existsSync(path16.join(this.root, ".git"))) {
13731
13808
  this.located = undefined;
13732
13809
  this.migrationChecked = false;
13733
13810
  }
@@ -13791,7 +13868,7 @@ class TaskStore {
13791
13868
  const tasksDir = this.paths().tasks;
13792
13869
  let names;
13793
13870
  try {
13794
- names = fs11.existsSync(tasksDir) ? fs11.readdirSync(tasksDir).filter((name) => validId(name)) : [];
13871
+ names = fs12.existsSync(tasksDir) ? fs12.readdirSync(tasksDir).filter((name) => validId(name)) : [];
13795
13872
  } catch (error) {
13796
13873
  return failure2("storage_error", `unable to list tasks: ${String(error)}`, {
13797
13874
  path: tasksDir
@@ -13832,7 +13909,7 @@ class TaskStore {
13832
13909
  const file = this.paths().workspace;
13833
13910
  let bytes;
13834
13911
  try {
13835
- bytes = retryTransient(() => fs11.readFileSync(file, "utf8"));
13912
+ bytes = retryTransient(() => fs12.readFileSync(file, "utf8"));
13836
13913
  } catch (error) {
13837
13914
  if (error.code === "ENOENT")
13838
13915
  return success(null, null, null);
@@ -13883,7 +13960,7 @@ class TaskStore {
13883
13960
  const moved = this.bindLocked(again.data.id, key, input.now);
13884
13961
  return moved.ok ? success(moved.data.revision, null, { task: moved.data, created: false, key }) : moved;
13885
13962
  }
13886
- const label = key.kind === "branch" ? `branch ${key.branch}` : key.kind === "detached" ? "a detached HEAD" : path15.basename(this.root) || this.root;
13963
+ const label = key.kind === "branch" ? `branch ${key.branch}` : key.kind === "detached" ? "a detached HEAD" : path16.basename(this.root) || this.root;
13887
13964
  const intent = {
13888
13965
  objective: input.objective?.trim() || `Work on ${label}`,
13889
13966
  scope: { description: `the checkout (${label})`, paths: ["."], exclusions: [] },
@@ -13949,14 +14026,14 @@ class TaskStore {
13949
14026
  const branch = key.ok ? key.data.branch : null;
13950
14027
  if (!branch || !location.ok)
13951
14028
  return success(null, null, null);
13952
- const common = path15.dirname(location.data.dir);
13953
- const heads = path15.join(common, "logs", "refs", "heads");
13954
- const headLog = location.data.git ? path15.join(location.data.git.gitDir, "logs", "HEAD") : "";
14029
+ const common = path16.dirname(location.data.dir);
14030
+ const heads = path16.join(common, "logs", "refs", "heads");
14031
+ const headLog = location.data.git ? path16.join(location.data.git.gitDir, "logs", "HEAD") : "";
13955
14032
  const signatures = [
13956
- path15.join(heads, branch),
14033
+ path16.join(heads, branch),
13957
14034
  headLog,
13958
14035
  heads,
13959
- path15.join(common, "packed-refs")
14036
+ path16.join(common, "packed-refs")
13960
14037
  ].map((file) => fileSignature(file) ?? "-");
13961
14038
  const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
13962
14039
  let resolved = origins.get(slot);
@@ -13968,7 +14045,7 @@ class TaskStore {
13968
14045
  aliases.push(rename.from);
13969
14046
  const start = branchStart(location.data, branch, aliases);
13970
14047
  const slash = start?.indexOf("/") ?? -1;
13971
- 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)}"]`));
14048
+ 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)}"]`));
13972
14049
  const name = start && (remote ? start.slice(slash + 1) : start);
13973
14050
  resolved = {
13974
14051
  signature: signatures.join("|"),
@@ -14206,13 +14283,13 @@ class TaskStore {
14206
14283
  if (!ready.ok)
14207
14284
  return ready;
14208
14285
  const dirs = this.paths();
14209
- const recovery = path15.join(this.root, ".workit", "recovery");
14210
- if (fs11.existsSync(recovery)) {
14286
+ const recovery = path16.join(this.root, ".workit", "recovery");
14287
+ if (fs12.existsSync(recovery)) {
14211
14288
  let files = 0;
14212
14289
  let bytes = 0;
14213
14290
  try {
14214
- for (const name of fs11.readdirSync(recovery)) {
14215
- const stat = fs11.lstatSync(path15.join(recovery, name));
14291
+ for (const name of fs12.readdirSync(recovery)) {
14292
+ const stat = fs12.lstatSync(path16.join(recovery, name));
14216
14293
  if (!stat.isFile())
14217
14294
  continue;
14218
14295
  files += 1;
@@ -14221,17 +14298,17 @@ class TaskStore {
14221
14298
  } catch {}
14222
14299
  const remove = options.pruneRecovery === true && !dryRun;
14223
14300
  if (remove)
14224
- fs11.rmSync(recovery, { recursive: true, force: true });
14301
+ fs12.rmSync(recovery, { recursive: true, force: true });
14225
14302
  report.legacyRecovery = { path: recovery, files, bytes, removed: remove };
14226
14303
  }
14227
- if (!fs11.existsSync(dirs.tasks))
14304
+ if (!fs12.existsSync(dirs.tasks))
14228
14305
  return success(null, null, report);
14229
- const names = fs11.readdirSync(dirs.tasks).filter((name) => validId(name));
14306
+ const names = fs12.readdirSync(dirs.tasks).filter((name) => validId(name));
14230
14307
  for (const name of names) {
14231
14308
  const file = this.eventsPath(name);
14232
14309
  let size = 0;
14233
14310
  try {
14234
- size = fs11.statSync(file).size;
14311
+ size = fs12.statSync(file).size;
14235
14312
  } catch {
14236
14313
  continue;
14237
14314
  }
@@ -14259,16 +14336,16 @@ class TaskStore {
14259
14336
  const references = new Set;
14260
14337
  for (const name of names)
14261
14338
  try {
14262
- for (const match of fs11.readFileSync(this.eventsPath(name), "utf8").matchAll(/"\$blob":"([0-9a-f]{64})"/g))
14339
+ for (const match of fs12.readFileSync(this.eventsPath(name), "utf8").matchAll(/"\$blob":"([0-9a-f]{64})"/g))
14263
14340
  references.add(match[1]);
14264
14341
  } catch {}
14265
- if (fs11.existsSync(dirs.blobs))
14266
- for (const name of fs11.readdirSync(dirs.blobs)) {
14342
+ if (fs12.existsSync(dirs.blobs))
14343
+ for (const name of fs12.readdirSync(dirs.blobs)) {
14267
14344
  const digest = name.replace(/\.json$/, "");
14268
- const file = path15.join(dirs.blobs, name);
14345
+ const file = path16.join(dirs.blobs, name);
14269
14346
  let stat;
14270
14347
  try {
14271
- stat = fs11.lstatSync(file);
14348
+ stat = fs12.lstatSync(file);
14272
14349
  } catch {
14273
14350
  continue;
14274
14351
  }
@@ -14279,11 +14356,11 @@ class TaskStore {
14279
14356
  report.blobs.removed += 1;
14280
14357
  report.blobs.removedBytes += stat.size;
14281
14358
  if (!dryRun)
14282
- fs11.rmSync(file, { force: true });
14359
+ fs12.rmSync(file, { force: true });
14283
14360
  }
14284
14361
  return success(null, null, null);
14285
14362
  };
14286
- const swept = dryRun ? sweep() : this.withLock(path15.join(dirs.dir, "gc.lock"), sweep);
14363
+ const swept = dryRun ? sweep() : this.withLock(path16.join(dirs.dir, "gc.lock"), sweep);
14287
14364
  if (!swept.ok)
14288
14365
  return swept;
14289
14366
  const temporaryDirs = [
@@ -14291,17 +14368,17 @@ class TaskStore {
14291
14368
  dirs.tasks,
14292
14369
  dirs.blobs,
14293
14370
  dirs.checkout,
14294
- ...names.map((name) => path15.join(dirs.tasks, name))
14371
+ ...names.map((name) => path16.join(dirs.tasks, name))
14295
14372
  ];
14296
14373
  for (const directory of temporaryDirs) {
14297
- if (!fs11.existsSync(directory))
14374
+ if (!fs12.existsSync(directory))
14298
14375
  continue;
14299
- for (const name of fs11.readdirSync(directory)) {
14376
+ for (const name of fs12.readdirSync(directory)) {
14300
14377
  if (!name.endsWith(".tmp") && !name.endsWith(".probe"))
14301
14378
  continue;
14302
- const file = path15.join(directory, name);
14379
+ const file = path16.join(directory, name);
14303
14380
  try {
14304
- const stat = fs11.lstatSync(file);
14381
+ const stat = fs12.lstatSync(file);
14305
14382
  if (!stat.isFile() || nowMs - stat.mtimeMs <= STALE_TEMPORARY_MS)
14306
14383
  continue;
14307
14384
  } catch {
@@ -14309,37 +14386,37 @@ class TaskStore {
14309
14386
  }
14310
14387
  report.temporary.removed += 1;
14311
14388
  if (!dryRun)
14312
- fs11.rmSync(file, { force: true });
14389
+ fs12.rmSync(file, { force: true });
14313
14390
  }
14314
14391
  }
14315
14392
  return success(null, null, report);
14316
14393
  }
14317
14394
  paths() {
14318
14395
  const location = this.location();
14319
- const dir = location.ok ? location.data.dir : path15.join(this.root, ".workit");
14320
- const checkout = path15.join(dir, "checkouts", checkoutSlug(this.root));
14396
+ const dir = location.ok ? location.data.dir : path16.join(this.root, ".workit");
14397
+ const checkout = path16.join(dir, "checkouts", checkoutSlug(this.root));
14321
14398
  return {
14322
14399
  dir,
14323
14400
  shared: location.ok ? location.data.shared : false,
14324
- marker: path15.join(dir, "store.json"),
14401
+ marker: path16.join(dir, "store.json"),
14325
14402
  checkout,
14326
- workspace: path15.join(checkout, "workspace.json"),
14327
- checkoutLock: path15.join(checkout, "metadata.lock"),
14328
- tasks: path15.join(dir, "tasks"),
14329
- index: path15.join(dir, "task-index.json"),
14330
- blobs: path15.join(dir, "blobs", "candidates"),
14331
- legacy: path15.join(dir, "legacy", checkoutSlug(this.root), "v2"),
14332
- v2: path15.join(this.root, ".workit")
14403
+ workspace: path16.join(checkout, "workspace.json"),
14404
+ checkoutLock: path16.join(checkout, "metadata.lock"),
14405
+ tasks: path16.join(dir, "tasks"),
14406
+ index: path16.join(dir, "task-index.json"),
14407
+ blobs: path16.join(dir, "blobs", "candidates"),
14408
+ legacy: path16.join(dir, "legacy", checkoutSlug(this.root), "v2"),
14409
+ v2: path16.join(this.root, ".workit")
14333
14410
  };
14334
14411
  }
14335
14412
  eventsPath(taskId) {
14336
- return path15.join(this.paths().tasks, taskId, "events.jsonl");
14413
+ return path16.join(this.paths().tasks, taskId, "events.jsonl");
14337
14414
  }
14338
14415
  snapshotPath(taskId) {
14339
- return path15.join(this.paths().tasks, taskId, "snapshot.json");
14416
+ return path16.join(this.paths().tasks, taskId, "snapshot.json");
14340
14417
  }
14341
14418
  taskLockPath(taskId) {
14342
- return path15.join(this.paths().tasks, taskId, "lock");
14419
+ return path16.join(this.paths().tasks, taskId, "lock");
14343
14420
  }
14344
14421
  ready(write = false) {
14345
14422
  const location = this.location();
@@ -14349,7 +14426,7 @@ class TaskStore {
14349
14426
  return success(null, null, null);
14350
14427
  const dirs = this.paths();
14351
14428
  try {
14352
- const marker = JSON.parse(fs11.readFileSync(dirs.marker, "utf8"));
14429
+ const marker = JSON.parse(fs12.readFileSync(dirs.marker, "utf8"));
14353
14430
  if (typeof marker.version === "number" && marker.version > STORE_FORMAT)
14354
14431
  return failure2("recovery_required", `the workit store at ${dirs.dir} has format ${marker.version}; upgrade Workit to use it`, { path: dirs.marker });
14355
14432
  } catch {}
@@ -14378,21 +14455,21 @@ class TaskStore {
14378
14455
  return {
14379
14456
  read: (digest) => {
14380
14457
  try {
14381
- return JSON.parse(fs11.readFileSync(path15.join(dir, `${digest}.json`), "utf8"));
14458
+ return JSON.parse(fs12.readFileSync(path16.join(dir, `${digest}.json`), "utf8"));
14382
14459
  } catch (error) {
14383
14460
  throw new LogDamage(`stored candidate ${digest} is missing or unreadable: ${String(error)}`);
14384
14461
  }
14385
14462
  },
14386
14463
  write: (digest, value) => {
14387
- const file = path15.join(dir, `${digest}.json`);
14388
- if (fs11.existsSync(file)) {
14464
+ const file = path16.join(dir, `${digest}.json`);
14465
+ if (fs12.existsSync(file)) {
14389
14466
  const stamp = new Date;
14390
14467
  try {
14391
- fs11.utimesSync(file, stamp, stamp);
14468
+ fs12.utimesSync(file, stamp, stamp);
14392
14469
  return;
14393
14470
  } catch {}
14394
14471
  }
14395
- fs11.mkdirSync(dir, { recursive: true });
14472
+ fs12.mkdirSync(dir, { recursive: true });
14396
14473
  replaceFile(file, JSON.stringify(value), true);
14397
14474
  }
14398
14475
  };
@@ -14474,7 +14551,7 @@ class TaskStore {
14474
14551
  }
14475
14552
  readSnapshot(taskId) {
14476
14553
  try {
14477
- const value = JSON.parse(fs11.readFileSync(this.snapshotPath(taskId), "utf8"));
14554
+ const value = JSON.parse(fs12.readFileSync(this.snapshotPath(taskId), "utf8"));
14478
14555
  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))
14479
14556
  return null;
14480
14557
  return value;
@@ -14576,8 +14653,8 @@ class TaskStore {
14576
14653
  }
14577
14654
  }
14578
14655
  openTask(record, type, key, legacy = null) {
14579
- const dir = path15.join(this.paths().tasks, record.id);
14580
- fs11.mkdirSync(dir, { recursive: true });
14656
+ const dir = path16.join(this.paths().tasks, record.id);
14657
+ fs12.mkdirSync(dir, { recursive: true });
14581
14658
  const blobs = this.blobStore();
14582
14659
  const bound = key ? { ...key, boundAt: key.boundAt ?? new Date().toISOString() } : null;
14583
14660
  const event = this.event(record.id, 1, type, {
@@ -14629,11 +14706,11 @@ class TaskStore {
14629
14706
  } catch {}
14630
14707
  if (!latest || latest.events[0]?.id !== last.id)
14631
14708
  return failure2("busy", "the task log changed during compaction; retry", { taskId });
14632
- const appended = fs11.readFileSync(file).subarray(log.end, latest.end);
14709
+ const appended = fs12.readFileSync(file).subarray(log.end, latest.end);
14633
14710
  const bytes = Buffer.concat([Buffer.from(prefix, "utf8"), appended]);
14634
14711
  replaceFile(file, bytes.toString("utf8"), true);
14635
14712
  try {
14636
- fs11.rmSync(this.snapshotPath(taskId), { force: true });
14713
+ fs12.rmSync(this.snapshotPath(taskId), { force: true });
14637
14714
  } catch {}
14638
14715
  const reloaded = this.load(taskId);
14639
14716
  if (reloaded.ok && reloaded.data)
@@ -14646,7 +14723,7 @@ class TaskStore {
14646
14723
  }
14647
14724
  countEvents(file) {
14648
14725
  try {
14649
- const bytes = fs11.readFileSync(file);
14726
+ const bytes = fs12.readFileSync(file);
14650
14727
  let count = 0;
14651
14728
  for (let index = bytes.indexOf(10);index >= 0; index = bytes.indexOf(10, index + 1))
14652
14729
  count += 1;
@@ -14668,8 +14745,8 @@ class TaskStore {
14668
14745
  return bound.ok ? success(null, null, bound.data[0] ?? null) : bound;
14669
14746
  }
14670
14747
  withKeyLock(key, operation) {
14671
- const digest = createHash10("sha256").update(key).digest("hex").slice(0, 32);
14672
- return this.withLock(path15.join(this.paths().dir, "keys", `${digest}.lock`), operation);
14748
+ const digest = createHash11("sha256").update(key).digest("hex").slice(0, 32);
14749
+ return this.withLock(path16.join(this.paths().dir, "keys", `${digest}.lock`), operation);
14673
14750
  }
14674
14751
  bindLocked(taskId, key, timestamp) {
14675
14752
  const current = this.readWorkspace();
@@ -14810,7 +14887,7 @@ class TaskStore {
14810
14887
  writeWorkspace(record) {
14811
14888
  const file = this.paths().workspace;
14812
14889
  try {
14813
- fs11.mkdirSync(path15.dirname(file), { recursive: true });
14890
+ fs12.mkdirSync(path16.dirname(file), { recursive: true });
14814
14891
  replaceFile(file, `${canonicalJson(record)}
14815
14892
  `, true);
14816
14893
  return success(null, null, null);
@@ -14820,7 +14897,7 @@ class TaskStore {
14820
14897
  }
14821
14898
  readIndex() {
14822
14899
  try {
14823
- const value = JSON.parse(fs11.readFileSync(this.paths().index, "utf8"));
14900
+ const value = JSON.parse(fs12.readFileSync(this.paths().index, "utf8"));
14824
14901
  if (!isObject6(value) || value.version !== INDEX_VERSION || !isObject6(value.tasks))
14825
14902
  return {};
14826
14903
  const tasks = {};
@@ -14834,7 +14911,7 @@ class TaskStore {
14834
14911
  }
14835
14912
  writeIndex(entries) {
14836
14913
  try {
14837
- fs11.mkdirSync(this.paths().tasks, { recursive: true });
14914
+ fs12.mkdirSync(this.paths().tasks, { recursive: true });
14838
14915
  replaceFile(this.paths().index, JSON.stringify({
14839
14916
  version: INDEX_VERSION,
14840
14917
  tasks: Object.fromEntries(entries.map((entry) => [entry.id, entry]))
@@ -14888,23 +14965,23 @@ class TaskStore {
14888
14965
  return failure2("revision_conflict", "workspace revision does not match; omit expectedWorkspaceRevision to use the current record", { expectedWorkspaceRevision: expected, actualWorkspaceRevision: actual });
14889
14966
  }
14890
14967
  v2Dirs() {
14891
- return [...new Set([this.root, this.origin])].map((dir) => path15.join(dir, ".workit"));
14968
+ return [...new Set([this.root, this.origin])].map((dir) => path16.join(dir, ".workit"));
14892
14969
  }
14893
14970
  pendingMigrations() {
14894
14971
  return this.v2Dirs().filter((dir) => {
14895
- const raw = this.readV2Workspace(path15.join(dir, "workspace.json"));
14972
+ const raw = this.readV2Workspace(path16.join(dir, "workspace.json"));
14896
14973
  return raw !== null && raw !== TOMBSTONE;
14897
14974
  });
14898
14975
  }
14899
14976
  migrateV2(v2) {
14900
14977
  const dirs = this.paths();
14901
- const v2Workspace = path15.join(v2, "workspace.json");
14902
- const v2Tasks = path15.join(v2, "tasks");
14903
- const legacy = path15.join(dirs.dir, "legacy", checkoutSlug(path15.dirname(v2)), "v2");
14978
+ const v2Workspace = path16.join(v2, "workspace.json");
14979
+ const v2Tasks = path16.join(v2, "tasks");
14980
+ const legacy = path16.join(dirs.dir, "legacy", checkoutSlug(path16.dirname(v2)), "v2");
14904
14981
  const raw = this.readV2Workspace(v2Workspace);
14905
14982
  if (raw === null || raw === TOMBSTONE)
14906
14983
  return success(null, null, null);
14907
- return this.withLock(dirs.checkoutLock, () => this.withLock(path15.join(v2, "metadata.lock"), () => {
14984
+ return this.withLock(dirs.checkoutLock, () => this.withLock(path16.join(v2, "metadata.lock"), () => {
14908
14985
  const workspace = this.readV2Workspace(v2Workspace);
14909
14986
  if (workspace === null || workspace === TOMBSTONE)
14910
14987
  return success(null, null, null);
@@ -14913,7 +14990,7 @@ class TaskStore {
14913
14990
  return failure2("recovery_required", `cannot migrate the 2.x store at ${v2}: ${parsedWorkspace.error}; move it aside to start fresh`, { path: v2Workspace });
14914
14991
  let files = [];
14915
14992
  try {
14916
- files = fs11.readdirSync(v2Tasks).filter((name) => name.endsWith(".json") && validId(name.slice(0, -5))).filter((name) => !this.isStub(path15.join(v2Tasks, name)));
14993
+ files = fs12.readdirSync(v2Tasks).filter((name) => name.endsWith(".json") && validId(name.slice(0, -5))).filter((name) => !this.isStub(path16.join(v2Tasks, name)));
14917
14994
  } catch {}
14918
14995
  const current = this.readWorkspace();
14919
14996
  if (!current.ok)
@@ -14931,22 +15008,22 @@ class TaskStore {
14931
15008
  let skipped = 0;
14932
15009
  const done = new Map;
14933
15010
  try {
14934
- fs11.mkdirSync(path15.join(legacy, "tasks"), { recursive: true });
15011
+ fs12.mkdirSync(path16.join(legacy, "tasks"), { recursive: true });
14935
15012
  for (const name of ["workspace.json", "index.json"])
14936
- if (fs11.existsSync(path15.join(v2, name)))
14937
- fs11.copyFileSync(path15.join(v2, name), path15.join(legacy, name));
15013
+ if (fs12.existsSync(path16.join(v2, name)))
15014
+ fs12.copyFileSync(path16.join(v2, name), path16.join(legacy, name));
14938
15015
  for (const name of files) {
14939
15016
  const id = name.slice(0, -5);
14940
- const file = path15.join(v2Tasks, name);
14941
- const bytes = fs11.readFileSync(file, "utf8");
15017
+ const file = path16.join(v2Tasks, name);
15018
+ const bytes = fs12.readFileSync(file, "utf8");
14942
15019
  const digest = sha256(bytes);
14943
- fs11.writeFileSync(path15.join(legacy, "tasks", name), bytes);
15020
+ fs12.writeFileSync(path16.join(legacy, "tasks", name), bytes);
14944
15021
  const parsed = this.parseRecord(bytes, taskRecordSchema, "2.x task");
14945
15022
  if (!parsed.ok || parsed.data.id !== id)
14946
15023
  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 });
14947
15024
  const record = { ...parsed.data, workspaceId: target.id };
14948
- const origin = { path: path15.join(legacy, "tasks", name), digest };
14949
- if (!fs11.existsSync(this.eventsPath(id))) {
15025
+ const origin = { path: path16.join(legacy, "tasks", name), digest };
15026
+ if (!fs12.existsSync(this.eventsPath(id))) {
14950
15027
  this.openTask(record, "migrated.from_v2", null, origin);
14951
15028
  migrated += 1;
14952
15029
  } else {
@@ -14981,8 +15058,8 @@ class TaskStore {
14981
15058
  try {
14982
15059
  let complete = true;
14983
15060
  for (const [name, digest] of done) {
14984
- const file = path15.join(v2Tasks, name);
14985
- if (sha256(fs11.readFileSync(file, "utf8")) !== digest) {
15061
+ const file = path16.join(v2Tasks, name);
15062
+ if (sha256(fs12.readFileSync(file, "utf8")) !== digest) {
14986
15063
  complete = false;
14987
15064
  continue;
14988
15065
  }
@@ -14992,7 +15069,7 @@ class TaskStore {
14992
15069
  return failure2("busy", `the 2.x store at ${v2} changed during migration; retry`, {
14993
15070
  path: v2
14994
15071
  });
14995
- fs11.rmSync(path15.join(v2, "index.json"), { force: true });
15072
+ fs12.rmSync(path16.join(v2, "index.json"), { force: true });
14996
15073
  this.writeTombstone(v2, target.id);
14997
15074
  } catch (error) {
14998
15075
  return failure2("storage_error", `cannot finish the 2.x migration: ${String(error)}`, {
@@ -15012,45 +15089,45 @@ class TaskStore {
15012
15089
  }
15013
15090
  adoptLocalStore() {
15014
15091
  const dirs = this.paths();
15015
- const marker = path15.join(dirs.v2, "store.json");
15016
- if (!dirs.shared || !fs11.existsSync(marker))
15092
+ const marker = path16.join(dirs.v2, "store.json");
15093
+ if (!dirs.shared || !fs12.existsSync(marker))
15017
15094
  return success(null, null, null);
15018
15095
  return this.withLock(dirs.checkoutLock, () => {
15019
- if (!fs11.existsSync(marker))
15096
+ if (!fs12.existsSync(marker))
15020
15097
  return success(null, null, null);
15021
15098
  let tasks = 0;
15022
15099
  try {
15023
15100
  const merge = (from, to) => {
15024
- if (!fs11.existsSync(to)) {
15025
- fs11.mkdirSync(path15.dirname(to), { recursive: true });
15101
+ if (!fs12.existsSync(to)) {
15102
+ fs12.mkdirSync(path16.dirname(to), { recursive: true });
15026
15103
  try {
15027
- fs11.renameSync(from, to);
15104
+ fs12.renameSync(from, to);
15028
15105
  } catch {
15029
- fs11.cpSync(from, to, { recursive: true, errorOnExist: true, force: false });
15030
- fs11.rmSync(from, { recursive: true, force: true });
15106
+ fs12.cpSync(from, to, { recursive: true, errorOnExist: true, force: false });
15107
+ fs12.rmSync(from, { recursive: true, force: true });
15031
15108
  }
15032
15109
  return;
15033
15110
  }
15034
- if (fs11.lstatSync(from).isDirectory() && fs11.lstatSync(to).isDirectory())
15035
- for (const name of fs11.readdirSync(from))
15036
- merge(path15.join(from, name), path15.join(to, name));
15111
+ if (fs12.lstatSync(from).isDirectory() && fs12.lstatSync(to).isDirectory())
15112
+ for (const name of fs12.readdirSync(from))
15113
+ merge(path16.join(from, name), path16.join(to, name));
15037
15114
  };
15038
15115
  for (const sub of ["tasks", "checkouts", "blobs", "legacy"]) {
15039
- const from = path15.join(dirs.v2, sub);
15040
- if (!fs11.existsSync(from))
15116
+ const from = path16.join(dirs.v2, sub);
15117
+ if (!fs12.existsSync(from))
15041
15118
  continue;
15042
15119
  if (sub === "tasks") {
15043
- for (const name of fs11.readdirSync(from))
15044
- if (validId(name) && !fs11.existsSync(path15.join(dirs.dir, sub, name)))
15120
+ for (const name of fs12.readdirSync(from))
15121
+ if (validId(name) && !fs12.existsSync(path16.join(dirs.dir, sub, name)))
15045
15122
  tasks += 1;
15046
15123
  }
15047
- merge(from, path15.join(dirs.dir, sub));
15124
+ merge(from, path16.join(dirs.dir, sub));
15048
15125
  }
15049
- const ledger = path15.join(dirs.v2, "ledger");
15050
- if (fs11.existsSync(ledger) && !fs11.existsSync(path15.join(dirs.dir, "ledger")))
15051
- merge(ledger, path15.join(dirs.dir, "ledger"));
15052
- fs11.rmSync(path15.join(dirs.v2, "task-index.json"), { force: true });
15053
- fs11.renameSync(marker, path15.join(dirs.v2, "store.moved.json"));
15126
+ const ledger = path16.join(dirs.v2, "ledger");
15127
+ if (fs12.existsSync(ledger) && !fs12.existsSync(path16.join(dirs.dir, "ledger")))
15128
+ merge(ledger, path16.join(dirs.dir, "ledger"));
15129
+ fs12.rmSync(path16.join(dirs.v2, "task-index.json"), { force: true });
15130
+ fs12.renameSync(marker, path16.join(dirs.v2, "store.moved.json"));
15054
15131
  } catch (error) {
15055
15132
  return failure2("storage_error", `cannot move ${dirs.v2} into ${dirs.dir}: ${String(error)}`, {
15056
15133
  path: dirs.v2
@@ -15070,7 +15147,7 @@ class TaskStore {
15070
15147
  readV2Workspace(file) {
15071
15148
  let bytes;
15072
15149
  try {
15073
- bytes = fs11.readFileSync(file, "utf8");
15150
+ bytes = fs12.readFileSync(file, "utf8");
15074
15151
  } catch {
15075
15152
  return null;
15076
15153
  }
@@ -15088,7 +15165,7 @@ class TaskStore {
15088
15165
  schemaVersion: SCHEMA_VERSION,
15089
15166
  id: workspaceId ?? newId(),
15090
15167
  revision: newRevision(),
15091
- root: path15.dirname(v2),
15168
+ root: path16.dirname(v2),
15092
15169
  runtime: { createdWith: version, updatedWith: version },
15093
15170
  writer: null,
15094
15171
  store: {
@@ -15099,12 +15176,12 @@ class TaskStore {
15099
15176
  },
15100
15177
  critical: ["store"]
15101
15178
  };
15102
- fs11.mkdirSync(v2, { recursive: true });
15103
- const ignore = path15.join(v2, ".gitignore");
15104
- if (!fs11.existsSync(ignore))
15105
- fs11.writeFileSync(ignore, `*
15179
+ fs12.mkdirSync(v2, { recursive: true });
15180
+ const ignore = path16.join(v2, ".gitignore");
15181
+ if (!fs12.existsSync(ignore))
15182
+ fs12.writeFileSync(ignore, `*
15106
15183
  `);
15107
- replaceFile(path15.join(v2, "workspace.json"), `${JSON.stringify(marker, null, 2)}
15184
+ replaceFile(path16.join(v2, "workspace.json"), `${JSON.stringify(marker, null, 2)}
15108
15185
  `, true);
15109
15186
  }
15110
15187
  stubFor(taskId) {
@@ -15120,7 +15197,7 @@ class TaskStore {
15120
15197
  }
15121
15198
  isStub(file) {
15122
15199
  try {
15123
- const value = JSON.parse(fs11.readFileSync(file, "utf8"));
15200
+ const value = JSON.parse(fs12.readFileSync(file, "utf8"));
15124
15201
  return isObject6(value) && isObject6(value.store) && value.store.format === "workit-store";
15125
15202
  } catch {
15126
15203
  return false;
@@ -15128,32 +15205,32 @@ class TaskStore {
15128
15205
  }
15129
15206
  writeTombstoneIfMissing() {
15130
15207
  try {
15131
- const v2 = path15.join(this.root, ".workit");
15132
- if (fs11.existsSync(path15.join(v2, "workspace.json")))
15208
+ const v2 = path16.join(this.root, ".workit");
15209
+ if (fs12.existsSync(path16.join(v2, "workspace.json")))
15133
15210
  return;
15134
15211
  let id = null;
15135
15212
  try {
15136
- id = JSON.parse(fs11.readFileSync(this.paths().workspace, "utf8")).id ?? null;
15213
+ id = JSON.parse(fs12.readFileSync(this.paths().workspace, "utf8")).id ?? null;
15137
15214
  } catch {}
15138
15215
  this.writeTombstone(v2, id);
15139
15216
  } catch {}
15140
15217
  }
15141
15218
  initializeStorage() {
15142
15219
  const dirs = this.paths();
15143
- retryTransient(() => fs11.mkdirSync(dirs.checkout, { recursive: true }));
15144
- retryTransient(() => fs11.mkdirSync(dirs.tasks, { recursive: true }));
15145
- if (!fs11.existsSync(dirs.marker))
15220
+ retryTransient(() => fs12.mkdirSync(dirs.checkout, { recursive: true }));
15221
+ retryTransient(() => fs12.mkdirSync(dirs.tasks, { recursive: true }));
15222
+ if (!fs12.existsSync(dirs.marker))
15146
15223
  replaceFile(dirs.marker, `${JSON.stringify({ format: "workit-store", version: STORE_FORMAT, createdWith: runtimeVersion() })}
15147
15224
  `, false);
15148
15225
  if (!dirs.shared) {
15149
- const ignore = path15.join(dirs.dir, ".gitignore");
15226
+ const ignore = path16.join(dirs.dir, ".gitignore");
15150
15227
  let current = null;
15151
15228
  try {
15152
- current = fs11.readFileSync(ignore, "utf8");
15229
+ current = fs12.readFileSync(ignore, "utf8");
15153
15230
  } catch {}
15154
15231
  if (current !== `*
15155
15232
  `)
15156
- retryTransient(() => fs11.writeFileSync(ignore, `*
15233
+ retryTransient(() => fs12.writeFileSync(ignore, `*
15157
15234
  `));
15158
15235
  }
15159
15236
  this.writeTombstoneIfMissing();
@@ -15169,7 +15246,7 @@ class TaskStore {
15169
15246
  shouldReclaim: ({ payload, nowMs }) => {
15170
15247
  let ageMs = null;
15171
15248
  try {
15172
- ageMs = nowMs - fs11.lstatSync(lockPath).mtimeMs;
15249
+ ageMs = nowMs - fs12.lstatSync(lockPath).mtimeMs;
15173
15250
  } catch {}
15174
15251
  return classifyLockOwner(payload, ageMs, localLockHost(), TASK_STORE_LOCK).state === "stale";
15175
15252
  },
@@ -15206,7 +15283,7 @@ class TaskStore {
15206
15283
  withLock(lockPath, operation) {
15207
15284
  try {
15208
15285
  this.initializeStorage();
15209
- fs11.mkdirSync(path15.dirname(lockPath), { recursive: true });
15286
+ fs12.mkdirSync(path16.dirname(lockPath), { recursive: true });
15210
15287
  } catch (error) {
15211
15288
  return failure2("storage_error", `unable to initialize store: ${String(error)}`, {
15212
15289
  path: this.paths().dir
@@ -15246,18 +15323,18 @@ class TaskStore {
15246
15323
  lockDirWritable(lockPath) {
15247
15324
  const probe = `${lockPath}.${process.pid}.${randomUUID3()}.probe`;
15248
15325
  try {
15249
- fs11.closeSync(fs11.openSync(probe, "wx", 384));
15326
+ fs12.closeSync(fs12.openSync(probe, "wx", 384));
15250
15327
  } catch {
15251
15328
  return false;
15252
15329
  }
15253
15330
  try {
15254
- fs11.rmSync(probe, { force: true });
15331
+ fs12.rmSync(probe, { force: true });
15255
15332
  } catch {}
15256
15333
  return true;
15257
15334
  }
15258
15335
  lockHolderPresent(lockPath) {
15259
15336
  try {
15260
- fs11.lstatSync(lockPath);
15337
+ fs12.lstatSync(lockPath);
15261
15338
  return true;
15262
15339
  } catch (error) {
15263
15340
  return error?.code !== "ENOENT";
@@ -15269,12 +15346,12 @@ class TaskStore {
15269
15346
  if (isTransientWindowsError(error) && !this.lockHolderPresent(lockPath) && !this.lockDirWritable(lockPath))
15270
15347
  return failure2("storage_error", `cannot create the workit lock (${code}); no other Workit call holds it`, {
15271
15348
  path: lockPath,
15272
- guidance: `Check permissions and the read-only attribute on ${path15.dirname(lockPath)}.`
15349
+ guidance: `Check permissions and the read-only attribute on ${path16.dirname(lockPath)}.`
15273
15350
  });
15274
15351
  if (code === "EEXIST" || code === "file_lock_timeout" || code === "file_lock_stale" || isTransientWindowsError(error)) {
15275
15352
  let lock = null;
15276
15353
  try {
15277
- lock = parseMetadataLockOrNull(fs11.readFileSync(lockPath, "utf8"));
15354
+ lock = parseMetadataLockOrNull(fs12.readFileSync(lockPath, "utf8"));
15278
15355
  } catch {}
15279
15356
  return failure2("busy", `workit lock is held by another Workit call${lock ? ` (pid ${lock.pid} on ${lock.host})` : ""}; retry shortly`, {
15280
15357
  outcome: "not_started",
@@ -15293,26 +15370,26 @@ var isUncertainWorker = (state) => UNCERTAIN_WORKER_STATES.includes(state);
15293
15370
  var workerBlocksTransition = (transition, state) => transition === "pause" ? false : isUncertainWorker(state);
15294
15371
 
15295
15372
  // packages/workit-core/src/core/task-evaluation.ts
15296
- import { createHash as createHash11 } from "node:crypto";
15297
- import * as fs13 from "node:fs";
15373
+ import { createHash as createHash12 } from "node:crypto";
15374
+ import * as fs14 from "node:fs";
15298
15375
  import { spawnSync as spawnSync10 } from "node:child_process";
15299
- import path17 from "node:path";
15376
+ import path18 from "node:path";
15300
15377
 
15301
15378
  // packages/workit-core/src/check-config.ts
15302
15379
  import { spawnSync as spawnSync9 } from "node:child_process";
15303
- import fs12 from "node:fs";
15304
- import path16 from "node:path";
15380
+ import fs13 from "node:fs";
15381
+ import path17 from "node:path";
15305
15382
  var SCRIPT_CHECKS = ["test", "lint", "typecheck", "check"];
15306
15383
  var CHECKS_FILE = ".workit/checks.json";
15307
15384
  var LEGACY_CHECKS_FILE = "workit.checks.json";
15308
15385
  function checksConfigFile(root) {
15309
- const current = path16.join(root, CHECKS_FILE);
15310
- const legacy = path16.join(root, LEGACY_CHECKS_FILE);
15311
- return !fs12.existsSync(current) && fs12.existsSync(legacy) ? legacy : current;
15386
+ const current = path17.join(root, CHECKS_FILE);
15387
+ const legacy = path17.join(root, LEGACY_CHECKS_FILE);
15388
+ return !fs13.existsSync(current) && fs13.existsSync(legacy) ? legacy : current;
15312
15389
  }
15313
15390
  function repoHeavyCommands(root) {
15314
15391
  try {
15315
- const value = JSON.parse(fs12.readFileSync(checksConfigFile(root), "utf8"));
15392
+ const value = JSON.parse(fs13.readFileSync(checksConfigFile(root), "utf8"));
15316
15393
  const resources = isRecord3(value) ? value.resources : undefined;
15317
15394
  const list = isRecord3(resources) ? resources.heavyCommands : undefined;
15318
15395
  return Array.isArray(list) ? list.filter((item) => typeof item === "string") : [];
@@ -15370,10 +15447,10 @@ var git4 = (cwd, args) => {
15370
15447
  return value || null;
15371
15448
  };
15372
15449
  function checkRoot(cwd) {
15373
- return path16.resolve(git4(cwd, ["rev-parse", "--show-toplevel"]) ?? cwd);
15450
+ return path17.resolve(git4(cwd, ["rev-parse", "--show-toplevel"]) ?? cwd);
15374
15451
  }
15375
15452
  var packageManager = (root) => {
15376
- const has = (file) => fs12.existsSync(path16.join(root, file));
15453
+ const has = (file) => fs13.existsSync(path17.join(root, file));
15377
15454
  if (has("bun.lock") || has("bun.lockb"))
15378
15455
  return "bun";
15379
15456
  if (has("pnpm-lock.yaml"))
@@ -15393,7 +15470,7 @@ var CHECK_NAME = /^[a-z0-9][a-z0-9:._-]{0,63}$/u;
15393
15470
  function detectedChecks(root) {
15394
15471
  const read = (file) => {
15395
15472
  try {
15396
- return fs12.readFileSync(path16.join(root, file), "utf8");
15473
+ return fs13.readFileSync(path17.join(root, file), "utf8");
15397
15474
  } catch {
15398
15475
  return null;
15399
15476
  }
@@ -15433,7 +15510,7 @@ var GATES = ["testing", "verification"];
15433
15510
  function loadCheckConfig(cwd) {
15434
15511
  const root = checkRoot(cwd);
15435
15512
  const file = checksConfigFile(root);
15436
- const legacy = path16.basename(file) === LEGACY_CHECKS_FILE;
15513
+ const legacy = path17.basename(file) === LEGACY_CHECKS_FILE;
15437
15514
  const label = legacy ? LEGACY_CHECKS_FILE : CHECKS_FILE;
15438
15515
  const note = legacy ? {
15439
15516
  note: `${LEGACY_CHECKS_FILE} is deprecated; move it to ${CHECKS_FILE} (workit doctor --fix)`
@@ -15448,7 +15525,7 @@ function loadCheckConfig(cwd) {
15448
15525
  });
15449
15526
  let text = null;
15450
15527
  try {
15451
- text = fs12.readFileSync(file, "utf8");
15528
+ text = fs13.readFileSync(file, "utf8");
15452
15529
  } catch (error) {
15453
15530
  if (error.code !== "ENOENT")
15454
15531
  return none(`cannot read ${label}: ${error.message}`);
@@ -15511,10 +15588,10 @@ function workitAvailable(env = process.env) {
15511
15588
  return workitOnPath;
15512
15589
  const windows = process.platform === "win32";
15513
15590
  const exts = windows ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
15514
- const dirs = (env.PATH ?? env.Path ?? "").split(path16.delimiter).filter(Boolean);
15591
+ const dirs = (env.PATH ?? env.Path ?? "").split(path17.delimiter).filter(Boolean);
15515
15592
  workitOnPath = dirs.some((dir) => exts.some((ext) => {
15516
15593
  try {
15517
- return fs12.statSync(path16.join(dir, `workit${ext}`)).isFile();
15594
+ return fs13.statSync(path17.join(dir, `workit${ext}`)).isFile();
15518
15595
  } catch {
15519
15596
  return false;
15520
15597
  }
@@ -15526,15 +15603,15 @@ function checkCommand(args, version, onPath = workitAvailable()) {
15526
15603
  }
15527
15604
 
15528
15605
  // packages/workit-core/src/core/task-evaluation.ts
15529
- var digestBytes = (value) => createHash11("sha256").update(value).digest("hex");
15530
- var inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path17.sep}`);
15531
- var relative = (root, candidate) => path17.relative(root, candidate).split(path17.sep).join("/") || ".";
15606
+ var digestBytes = (value) => createHash12("sha256").update(value).digest("hex");
15607
+ var inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path18.sep}`);
15608
+ var relative = (root, candidate) => path18.relative(root, candidate).split(path18.sep).join("/") || ".";
15532
15609
  var canonicalPath = (value) => {
15533
15610
  if (typeof value !== "string" || !value)
15534
15611
  return null;
15535
15612
  if (value.includes("\\") || value.split("/").includes(".."))
15536
15613
  return null;
15537
- const normalized = path17.posix.normalize(value);
15614
+ const normalized = path18.posix.normalize(value);
15538
15615
  if (normalized === ".." || normalized.startsWith("../") || normalized.startsWith("/"))
15539
15616
  return null;
15540
15617
  return normalized === "." ? "." : normalized.replace(/\/$/, "");
@@ -15582,21 +15659,21 @@ var gitPaths = (root) => {
15582
15659
  git: !/not a git repository/i.test(stderr)
15583
15660
  };
15584
15661
  }
15585
- const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path17.sep).join("/")) : [];
15662
+ const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path18.sep).join("/")) : [];
15586
15663
  const stagedDeleted = spawnSync10("git", ["diff", "--cached", "--name-only", "--diff-filter=D", "-z"], { cwd: root, encoding: "buffer" });
15587
15664
  if (stagedDeleted.status !== 0) {
15588
15665
  const stderr = stagedDeleted.stderr?.toString("utf8") ?? "";
15589
15666
  if (!/not a git repository/i.test(stderr))
15590
15667
  return { paths, uncertain: true, git: true };
15591
15668
  } else if (stagedDeleted.stdout) {
15592
- paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path17.sep).join("/")));
15669
+ paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path18.sep).join("/")));
15593
15670
  }
15594
15671
  return { paths: [...new Set(paths)], uncertain: false, git: true };
15595
15672
  };
15596
15673
  var walk = (root, directory, output) => {
15597
15674
  let names;
15598
15675
  try {
15599
- names = fs13.readdirSync(directory);
15676
+ names = fs14.readdirSync(directory);
15600
15677
  } catch {
15601
15678
  return true;
15602
15679
  }
@@ -15604,10 +15681,10 @@ var walk = (root, directory, output) => {
15604
15681
  for (const name of names) {
15605
15682
  if (name === ".git" || name === ".workit")
15606
15683
  continue;
15607
- const target = path17.join(directory, name);
15684
+ const target = path18.join(directory, name);
15608
15685
  let stat;
15609
15686
  try {
15610
- stat = fs13.lstatSync(target);
15687
+ stat = fs14.lstatSync(target);
15611
15688
  } catch {
15612
15689
  uncertain = true;
15613
15690
  continue;
@@ -15622,14 +15699,14 @@ var walk = (root, directory, output) => {
15622
15699
  var scopeRoots = (root, scope) => {
15623
15700
  const roots = [];
15624
15701
  for (const item of scope.paths.length ? scope.paths : ["."]) {
15625
- const target = path17.resolve(root, item);
15702
+ const target = path18.resolve(root, item);
15626
15703
  if (!inside(root, target))
15627
15704
  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` }] });
15628
15705
  let ancestor = target;
15629
- while (!fs13.existsSync(ancestor) && ancestor !== root)
15630
- ancestor = path17.dirname(ancestor);
15706
+ while (!fs14.existsSync(ancestor) && ancestor !== root)
15707
+ ancestor = path18.dirname(ancestor);
15631
15708
  try {
15632
- if (!inside(root, fs13.realpathSync(ancestor)))
15709
+ if (!inside(root, fs14.realpathSync(ancestor)))
15633
15710
  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` }] });
15634
15711
  } catch {
15635
15712
  return failure2("invalid_input", `candidate scope cannot be inspected: ${item}`);
@@ -15641,7 +15718,7 @@ var scopeRoots = (root, scope) => {
15641
15718
  function captureCandidate(root, scope, environment = []) {
15642
15719
  let checkout;
15643
15720
  try {
15644
- checkout = fs13.realpathSync(root);
15721
+ checkout = fs14.realpathSync(root);
15645
15722
  } catch {
15646
15723
  return failure2("invalid_input", "candidate root does not exist");
15647
15724
  }
@@ -15659,11 +15736,11 @@ function captureCandidate(root, scope, environment = []) {
15659
15736
  if (item === ".git" || item === ".workit")
15660
15737
  continue;
15661
15738
  names.add(item);
15662
- if (!fs13.existsSync(target))
15739
+ if (!fs14.existsSync(target))
15663
15740
  continue;
15664
15741
  let stat;
15665
15742
  try {
15666
- stat = fs13.lstatSync(target);
15743
+ stat = fs14.lstatSync(target);
15667
15744
  } catch {
15668
15745
  uncertain = true;
15669
15746
  continue;
@@ -15679,17 +15756,17 @@ function captureCandidate(root, scope, environment = []) {
15679
15756
  for (const item of [...names].toSorted()) {
15680
15757
  if (!scopeMatches(item, normalizedScope))
15681
15758
  continue;
15682
- const target = path17.join(checkout, item);
15759
+ const target = path18.join(checkout, item);
15683
15760
  try {
15684
- const stat = fs13.lstatSync(target);
15761
+ const stat = fs14.lstatSync(target);
15685
15762
  if (stat.isSymbolicLink()) {
15686
- const link = fs13.readlinkSync(target);
15763
+ const link = fs14.readlinkSync(target);
15687
15764
  files.push({ path: item, kind: "symlink", digest: digestBytes(link), executable: null });
15688
15765
  } else if (stat.isFile()) {
15689
15766
  files.push({
15690
15767
  path: item,
15691
15768
  kind: "file",
15692
- digest: digestBytes(fs13.readFileSync(target)),
15769
+ digest: digestBytes(fs14.readFileSync(target)),
15693
15770
  executable: (stat.mode & 73) !== 0
15694
15771
  });
15695
15772
  } else if (!stat.isDirectory()) {
@@ -15854,7 +15931,7 @@ var findingVerificationPasses = (findingCandidateId, evidence) => evidence.statu
15854
15931
  var verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
15855
15932
  let root;
15856
15933
  try {
15857
- root = fs13.realpathSync(checkoutRoot);
15934
+ root = fs14.realpathSync(checkoutRoot);
15858
15935
  } catch {
15859
15936
  return failure2("permission_denied", "checkout root is unavailable");
15860
15937
  }
@@ -15863,23 +15940,23 @@ var verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
15863
15940
  continue;
15864
15941
  if (!reference.digest)
15865
15942
  return failure2("invalid_input", "document references require a byte digest");
15866
- const target = path17.resolve(root, reference.path);
15867
- if (target !== root && !target.startsWith(`${root}${path17.sep}`))
15943
+ const target = path18.resolve(root, reference.path);
15944
+ if (target !== root && !target.startsWith(`${root}${path18.sep}`))
15868
15945
  return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
15869
15946
  fields: [
15870
15947
  { path: "contentRefs.path", reason: `${reference.path} is outside the checkout` }
15871
15948
  ]
15872
15949
  });
15873
15950
  try {
15874
- const below = path17.relative(root, target);
15951
+ const below = path18.relative(root, target);
15875
15952
  let current = root;
15876
- for (const segment of below.split(path17.sep)) {
15953
+ for (const segment of below.split(path18.sep)) {
15877
15954
  if (!segment)
15878
15955
  continue;
15879
- current = path17.join(current, segment);
15880
- const stat = fs13.lstatSync(current);
15881
- const real = fs13.realpathSync(current);
15882
- if (real !== root && !real.startsWith(`${root}${path17.sep}`))
15956
+ current = path18.join(current, segment);
15957
+ const stat = fs14.lstatSync(current);
15958
+ const real = fs14.realpathSync(current);
15959
+ if (real !== root && !real.startsWith(`${root}${path18.sep}`))
15883
15960
  return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
15884
15961
  fields: [
15885
15962
  {
@@ -15895,7 +15972,7 @@ var verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
15895
15972
  if (current !== target && !stat.isDirectory())
15896
15973
  return failure2("invalid_input", "document reference ancestor is not a directory");
15897
15974
  }
15898
- if (digestBytes(fs13.readFileSync(target)) !== reference.digest)
15975
+ if (digestBytes(fs14.readFileSync(target)) !== reference.digest)
15899
15976
  return failure2("permission_denied", "decision document bytes have changed");
15900
15977
  } catch {
15901
15978
  return failure2("invalid_input", "decision document is unavailable");
@@ -18175,9 +18252,9 @@ var capabilitiesFor = (descriptor, observed = {}) => descriptor.capabilities.map
18175
18252
  };
18176
18253
  });
18177
18254
  // packages/workit-core/src/hooks/context.ts
18178
- import { createHash as createHash12 } from "node:crypto";
18179
- import fs14 from "node:fs";
18180
- import path18 from "node:path";
18255
+ import { createHash as createHash13 } from "node:crypto";
18256
+ import fs15 from "node:fs";
18257
+ import path19 from "node:path";
18181
18258
  var MIGRATION_PENDING_NOTE = "workit migration pending — run `workit task status`";
18182
18259
  var migrationPending = (result) => !result.ok && result.code === "needs_input" && (result.error ?? "").startsWith(MIGRATION_PENDING);
18183
18260
  var boundTo = (entry, session) => entry.sessions.some((item) => item.host === session.host && item.handle === session.handle);
@@ -18262,7 +18339,7 @@ function entryCompactContext(store, entry, session, context) {
18262
18339
  return null;
18263
18340
  const freshness = { mode: "signal", current: () => recentSignal(store.root) };
18264
18341
  const observed = task?.data.evidence.some(isObservedCheck) ?? false;
18265
- const files = (task?.data.decisions ?? []).flatMap((decision) => decision.data.binding.contentRefs.flatMap((ref) => ref.kind === "file" ? [path18.resolve(store.root, ref.path)] : []));
18342
+ const files = (task?.data.decisions ?? []).flatMap((decision) => decision.data.binding.contentRefs.flatMap((ref) => ref.kind === "file" ? [path19.resolve(store.root, ref.path)] : []));
18266
18343
  const observedFiles = filesKey(files);
18267
18344
  const compact = new WorkitCore(store, context).compactContext(entry?.id ?? null, freshness, origin && { origin: origin.origin, taskId: origin.entry.id });
18268
18345
  if (!compact.ok || !compact.data)
@@ -18331,7 +18408,7 @@ var turnContextText = (input, descriptor) => {
18331
18408
  }
18332
18409
  };
18333
18410
  var TURN_TTL_MS = 7 * 24 * 60 * 60 * 1000;
18334
- var digestOf = (text) => createHash12("sha256").update(text).digest("hex");
18411
+ var digestOf = (text) => createHash13("sha256").update(text).digest("hex");
18335
18412
  var turnMarker = (input) => {
18336
18413
  if (!input.session.id)
18337
18414
  return null;
@@ -18340,32 +18417,32 @@ var turnMarker = (input) => {
18340
18417
  if (location instanceof Error)
18341
18418
  return null;
18342
18419
  const session = [input.host, input.session.id, input.session.agentId ?? ""].join("\x00");
18343
- return path18.join(location.dir, "hooks", `turn-${digestOf(session).slice(0, 32)}.json`);
18420
+ return path19.join(location.dir, "hooks", `turn-${digestOf(session).slice(0, 32)}.json`);
18344
18421
  } catch {
18345
18422
  return null;
18346
18423
  }
18347
18424
  };
18348
18425
  var writeTurnDigest = (file, digest) => {
18349
18426
  try {
18350
- fs14.mkdirSync(path18.dirname(file), { recursive: true });
18351
- fs14.writeFileSync(file, `${JSON.stringify({ digest })}
18427
+ fs15.mkdirSync(path19.dirname(file), { recursive: true });
18428
+ fs15.writeFileSync(file, `${JSON.stringify({ digest })}
18352
18429
  `);
18353
18430
  } catch {}
18354
18431
  };
18355
18432
  var clearTurnDigest = (file) => {
18356
18433
  try {
18357
- fs14.rmSync(file, { force: true });
18434
+ fs15.rmSync(file, { force: true });
18358
18435
  } catch {}
18359
18436
  };
18360
18437
  var pruneTurnDigests = (dir, now) => {
18361
18438
  try {
18362
- for (const name of fs14.readdirSync(dir)) {
18439
+ for (const name of fs15.readdirSync(dir)) {
18363
18440
  if (!name.startsWith("turn-"))
18364
18441
  continue;
18365
- const file = path18.join(dir, name);
18442
+ const file = path19.join(dir, name);
18366
18443
  try {
18367
- if (now - fs14.statSync(file).mtimeMs > TURN_TTL_MS)
18368
- fs14.rmSync(file, { force: true });
18444
+ if (now - fs15.statSync(file).mtimeMs > TURN_TTL_MS)
18445
+ fs15.rmSync(file, { force: true });
18369
18446
  } catch {}
18370
18447
  }
18371
18448
  } catch {}
@@ -18381,7 +18458,7 @@ var changedTurnContext = (input, text) => {
18381
18458
  return text;
18382
18459
  const digest = digestOf(text);
18383
18460
  try {
18384
- const previous = JSON.parse(fs14.readFileSync(file, "utf8"));
18461
+ const previous = JSON.parse(fs15.readFileSync(file, "utf8"));
18385
18462
  if (previous.digest === digest)
18386
18463
  return null;
18387
18464
  } catch {}
@@ -18392,7 +18469,7 @@ var seedTurnContext = (input, descriptor, text = turnContextText(input, descript
18392
18469
  const file = turnMarker(input);
18393
18470
  if (!file)
18394
18471
  return;
18395
- pruneTurnDigests(path18.dirname(file), Date.now());
18472
+ pruneTurnDigests(path19.dirname(file), Date.now());
18396
18473
  if (text)
18397
18474
  writeTurnDigest(file, digestOf(text));
18398
18475
  else
@@ -18401,19 +18478,19 @@ var seedTurnContext = (input, descriptor, text = turnContextText(input, descript
18401
18478
  // packages/workit-core/src/core/route-intent.ts
18402
18479
  import { spawnSync as spawnSync12 } from "node:child_process";
18403
18480
  import { existsSync as existsSync6 } from "node:fs";
18404
- import path21 from "node:path";
18481
+ import path22 from "node:path";
18405
18482
 
18406
18483
  // packages/workit-core/src/hooks/raw-git.ts
18407
18484
  import { spawnSync as spawnSync11 } from "node:child_process";
18408
- import { createHash as createHash14 } from "node:crypto";
18409
- import fs16 from "node:fs";
18485
+ import { createHash as createHash15 } from "node:crypto";
18486
+ import fs17 from "node:fs";
18410
18487
  import os5 from "node:os";
18411
- import path20 from "node:path";
18488
+ import path21 from "node:path";
18412
18489
 
18413
18490
  // packages/workit-core/src/hooks/session-marker.ts
18414
- import { createHash as createHash13 } from "node:crypto";
18415
- import fs15 from "node:fs";
18416
- import path19 from "node:path";
18491
+ import { createHash as createHash14 } from "node:crypto";
18492
+ import fs16 from "node:fs";
18493
+ import path20 from "node:path";
18417
18494
  var sessionMarkerFile = (input, session, store) => {
18418
18495
  let dir = store;
18419
18496
  if (dir === undefined) {
@@ -18422,13 +18499,13 @@ var sessionMarkerFile = (input, session, store) => {
18422
18499
  return null;
18423
18500
  dir = location.dir;
18424
18501
  }
18425
- const name = createHash13("sha256").update(`${input.host}\x00${session}`).digest("hex").slice(0, 32);
18426
- return path19.join(dir, "hooks", `skills-${name}.json`);
18502
+ const name = createHash14("sha256").update(`${input.host}\x00${session}`).digest("hex").slice(0, 32);
18503
+ return path20.join(dir, "hooks", `skills-${name}.json`);
18427
18504
  };
18428
18505
  var list2 = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
18429
18506
  var readSessionMarker = (file) => {
18430
18507
  try {
18431
- const value = JSON.parse(fs15.readFileSync(file, "utf8"));
18508
+ const value = JSON.parse(fs16.readFileSync(file, "utf8"));
18432
18509
  return { nudged: list2(value.nudged), loaded: list2(value.loaded), raw: list2(value.raw) };
18433
18510
  } catch {
18434
18511
  return { nudged: [], loaded: [], raw: [] };
@@ -18436,8 +18513,8 @@ var readSessionMarker = (file) => {
18436
18513
  };
18437
18514
  var writeSessionMarker = (file, marker) => {
18438
18515
  try {
18439
- fs15.mkdirSync(path19.dirname(file), { recursive: true });
18440
- fs15.writeFileSync(file, JSON.stringify(marker));
18516
+ fs16.mkdirSync(path20.dirname(file), { recursive: true });
18517
+ fs16.writeFileSync(file, JSON.stringify(marker));
18441
18518
  } catch {}
18442
18519
  };
18443
18520
 
@@ -18934,14 +19011,14 @@ var GIT_CONFIG_ENV = /^GIT_(?:CONFIG\w*|DIR|COMMON_DIR|WORK_TREE)$/;
18934
19011
  var ASSIGNMENT = /^([A-Za-z_]\w*)=([\s\S]*)$/;
18935
19012
  var MAX_DEPTH = 4;
18936
19013
  var MAX_EXPANSIONS = 16;
18937
- var isAbsolute = (value) => path20.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\");
19014
+ var isAbsolute = (value) => path21.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\");
18938
19015
  var HERE = /^(?:\$PWD|\$\{PWD\}|\$\(\s*pwd\s*\)|`pwd`|\$\(\s*git\s+rev-parse\s+--show-toplevel\s*\))(?=$|[\\/])/;
18939
19016
  var joinDir = (base, raw) => {
18940
19017
  const next = raw.replace(HERE, ".");
18941
19018
  if (base === undefined || /[$`*?]/.test(next) || next === "-")
18942
19019
  return;
18943
- const expanded = next === "~" || next.startsWith("~/") ? path20.join(os5.homedir(), next.slice(1)) : next;
18944
- return base === null || isAbsolute(expanded) ? expanded : path20.join(base, expanded);
19020
+ const expanded = next === "~" || next.startsWith("~/") ? path21.join(os5.homedir(), next.slice(1)) : next;
19021
+ return base === null || isAbsolute(expanded) ? expanded : path21.join(base, expanded);
18945
19022
  };
18946
19023
  var rebase = (base, inner) => inner === null ? base : inner === undefined ? undefined : joinDir(base, inner);
18947
19024
  var cdTarget = (words) => {
@@ -19753,7 +19830,7 @@ var repoAt = (dir) => {
19753
19830
  return { location, dir, branch: resolveTaskKey(dir, location).branch };
19754
19831
  };
19755
19832
  var isWorkitWorkspace = (repo) => {
19756
- if (fs16.existsSync(repo.location.dir))
19833
+ if (fs17.existsSync(repo.location.dir))
19757
19834
  return true;
19758
19835
  try {
19759
19836
  return resolveRuntimeWorkspaceVcs(repo.location.top ?? repo.dir) !== null;
@@ -19774,17 +19851,17 @@ var headSha2 = (repo) => {
19774
19851
  if (!git || git.reftable)
19775
19852
  return null;
19776
19853
  try {
19777
- const head = fs16.readFileSync(path20.join(git.gitDir, "HEAD"), "utf8").trim();
19854
+ const head = fs17.readFileSync(path21.join(git.gitDir, "HEAD"), "utf8").trim();
19778
19855
  if (/^[0-9a-f]{40,64}$/.test(head))
19779
19856
  return head;
19780
19857
  const ref = /^ref: (refs\/.+)$/.exec(head)?.[1];
19781
19858
  if (!ref)
19782
19859
  return null;
19783
- const common = path20.dirname(repo.location.dir);
19860
+ const common = path21.dirname(repo.location.dir);
19784
19861
  try {
19785
- return fs16.readFileSync(path20.join(common, ref), "utf8").trim() || null;
19862
+ return fs17.readFileSync(path21.join(common, ref), "utf8").trim() || null;
19786
19863
  } catch {}
19787
- const packed = fs16.readFileSync(path20.join(common, "packed-refs"), "utf8");
19864
+ const packed = fs17.readFileSync(path21.join(common, "packed-refs"), "utf8");
19788
19865
  return new RegExp(`^([0-9a-f]{40,64}) ${ref.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`, "m").exec(packed)?.[1] ?? null;
19789
19866
  } catch {
19790
19867
  return null;
@@ -19872,8 +19949,8 @@ var expandGitAliases = (root, invocation, cache = new Map, depth = 0) => {
19872
19949
  const sub = invocation.args[0];
19873
19950
  if (invocation.tool !== "git" || invocation.dir === undefined || !sub || sub.startsWith("-") || GIT_COMMANDS.has(sub) || depth >= MAX_DEPTH)
19874
19951
  return [invocation];
19875
- const dir = path20.resolve(root, invocation.dir ?? ".");
19876
- if (!fs16.existsSync(dir))
19952
+ const dir = path21.resolve(root, invocation.dir ?? ".");
19953
+ if (!fs17.existsSync(dir))
19877
19954
  return [invocation];
19878
19955
  const config = gitConfig(dir, invocation, cache);
19879
19956
  const alias = configValue(config, `alias.${sub.toLowerCase()}`);
@@ -19895,11 +19972,11 @@ var expandGitAliases = (root, invocation, cache = new Map, depth = 0) => {
19895
19972
  var normalizedUrl = (url, dir) => {
19896
19973
  const trimmed = url.trim();
19897
19974
  if (/^file:\/\//i.test(trimmed))
19898
- return path20.resolve(dir, trimmed.slice(7)).replace(/\/+$/, "").replace(/\.git$/, "");
19975
+ return path21.resolve(dir, trimmed.slice(7)).replace(/\/+$/, "").replace(/\.git$/, "");
19899
19976
  const scheme = /^[a-z][a-z0-9+.-]*:\/\//i.exec(trimmed);
19900
19977
  const scp = !scheme && /^(?:[^@/\\]+@)?[^/\\:]{2,}:/.test(trimmed);
19901
19978
  if (!scheme && !scp)
19902
- return path20.resolve(dir, trimmed).replace(/\/+$/, "").replace(/\.git$/, "");
19979
+ return path21.resolve(dir, trimmed).replace(/\/+$/, "").replace(/\.git$/, "");
19903
19980
  const value = scheme ? trimmed.slice(scheme[0].length).replace(/^[^@/]*@/, "").replace(/^([^/:]+):\d+(?=\/)/, "$1") : trimmed.replace(/^[^@/]*@/, "").replace(":", "/");
19904
19981
  return value.toLowerCase().replace(/\/{2,}/g, "/").replace(/^www\./, "").replace(/\/+$/, "").replace(/\.git$/, "");
19905
19982
  };
@@ -20123,7 +20200,7 @@ var actionsIn = (cwd, command, dialect, cache = new Map) => {
20123
20200
  const out = [];
20124
20201
  const repos = new Map;
20125
20202
  const repoFor = (relative) => {
20126
- const dir = path20.resolve(cwd, relative ?? ".");
20203
+ const dir = path21.resolve(cwd, relative ?? ".");
20127
20204
  if (!repos.has(dir)) {
20128
20205
  const repo = repoAt(dir);
20129
20206
  repos.set(dir, repo && isWorkitWorkspace(repo) ? repo : null);
@@ -20209,8 +20286,8 @@ var analysisDenial = (error) => ({
20209
20286
  });
20210
20287
  var NEXT_COMMAND = "next";
20211
20288
  var MARKER_TTL_SECONDS = 3600;
20212
- var markerFile = (repo, session, key) => path20.join(repo.location.dir, "hooks", `commit-${createHash14("sha256").update(`${session}\x00${key}`).digest("hex").slice(0, 32)}.json`);
20213
- var callKey = (toolUseId, command) => toolUseId ?? `cmd:${createHash14("sha256").update(command).digest("hex")}`;
20289
+ var markerFile = (repo, session, key) => path21.join(repo.location.dir, "hooks", `commit-${createHash15("sha256").update(`${session}\x00${key}`).digest("hex").slice(0, 32)}.json`);
20290
+ var callKey = (toolUseId, command) => toolUseId ?? `cmd:${createHash15("sha256").update(command).digest("hex")}`;
20214
20291
  function noteRawCommit(input, command, key) {
20215
20292
  try {
20216
20293
  if (!input.session.id || !/\bcommit\b/.test(command))
@@ -20220,8 +20297,8 @@ function noteRawCommit(input, command, key) {
20220
20297
  if (action.kind !== "commit")
20221
20298
  continue;
20222
20299
  const file = markerFile(repo, input.session.id, key);
20223
- fs16.mkdirSync(path20.dirname(file), { recursive: true });
20224
- fs16.writeFileSync(file, `${JSON.stringify({ head: headSha2(repo), at })}
20300
+ fs17.mkdirSync(path21.dirname(file), { recursive: true });
20301
+ fs17.writeFileSync(file, `${JSON.stringify({ head: headSha2(repo), at })}
20225
20302
  `);
20226
20303
  }
20227
20304
  } catch {}
@@ -20244,11 +20321,11 @@ var headCommit = (dir) => {
20244
20321
  var settle2 = (input, repo, file) => {
20245
20322
  let marker;
20246
20323
  try {
20247
- marker = JSON.parse(fs16.readFileSync(file, "utf8"));
20324
+ marker = JSON.parse(fs17.readFileSync(file, "utf8"));
20248
20325
  } catch {
20249
20326
  return;
20250
20327
  }
20251
- fs16.rmSync(file, { force: true });
20328
+ fs17.rmSync(file, { force: true });
20252
20329
  const session = input.session.id;
20253
20330
  const now = Date.now() / 1000;
20254
20331
  if (typeof marker.at !== "number" || now - marker.at > MARKER_TTL_SECONDS)
@@ -20297,7 +20374,7 @@ function settlePendingCommit(input) {
20297
20374
  if (!repo)
20298
20375
  return;
20299
20376
  const file = markerFile(repo, input.session.id, NEXT_COMMAND);
20300
- if (fs16.existsSync(file))
20377
+ if (fs17.existsSync(file))
20301
20378
  settle2(input, repo, file);
20302
20379
  } catch {}
20303
20380
  }
@@ -20451,7 +20528,7 @@ var judgedDir = (root, dir) => {
20451
20528
  return null;
20452
20529
  if (dir === null)
20453
20530
  return root;
20454
- const resolved = path21.resolve(root, dir);
20531
+ const resolved = path22.resolve(root, dir);
20455
20532
  return existsSync6(resolved) && inWorkitWorkspace(resolved) ? resolved : null;
20456
20533
  };
20457
20534
  var shellBranchPolicyViolation = (root, command, dialect = "posix") => {
@@ -20486,13 +20563,13 @@ var shellPolicy = (cwd, command, dialect = "posix") => {
20486
20563
  return policy && !policy.ok ? { kind: "deny", reason: `branch_policy_denied: ${policy.error}`, unblock: null } : { kind: "none" };
20487
20564
  };
20488
20565
  // packages/workit-core/src/core/heavy-rules.ts
20489
- import fs17 from "node:fs";
20566
+ import fs18 from "node:fs";
20490
20567
  import os6 from "node:os";
20491
- import path22 from "node:path";
20568
+ import path23 from "node:path";
20492
20569
  var EMPTY = () => ({ deny: [], allow: [] });
20493
20570
  var readText2 = (file) => {
20494
20571
  try {
20495
- return fs17.readFileSync(file, "utf8");
20572
+ return fs18.readFileSync(file, "utf8");
20496
20573
  } catch (error) {
20497
20574
  if (error.code === "ENOENT")
20498
20575
  return null;
@@ -20529,19 +20606,19 @@ function parseJsonc(text) {
20529
20606
  return JSON.parse(out.replace(/,(\s*[}\]])/gu, "$1"));
20530
20607
  }
20531
20608
  function gitTop(cwd) {
20532
- for (let dir = path22.resolve(cwd);; dir = path22.dirname(dir)) {
20533
- if (fs17.existsSync(path22.join(dir, ".git")))
20609
+ for (let dir = path23.resolve(cwd);; dir = path23.dirname(dir)) {
20610
+ if (fs18.existsSync(path23.join(dir, ".git")))
20534
20611
  return dir;
20535
- if (path22.dirname(dir) === dir)
20612
+ if (path23.dirname(dir) === dir)
20536
20613
  return null;
20537
20614
  }
20538
20615
  }
20539
20616
  var projectDirs = (cwd) => {
20540
20617
  const top = gitTop(cwd);
20541
20618
  const dirs = [];
20542
- for (let dir = path22.resolve(cwd);; dir = path22.dirname(dir)) {
20619
+ for (let dir = path23.resolve(cwd);; dir = path23.dirname(dir)) {
20543
20620
  dirs.push(dir);
20544
- if (!top || dir === top || path22.dirname(dir) === dir)
20621
+ if (!top || dir === top || path23.dirname(dir) === dir)
20545
20622
  return dirs;
20546
20623
  }
20547
20624
  };
@@ -20553,12 +20630,12 @@ var CLAUDE_MANAGED = {
20553
20630
  };
20554
20631
  function claudeSettingsFiles(cwd, env, platform = process.platform) {
20555
20632
  const project = env.CLAUDE_PROJECT_DIR || gitTop(cwd) || cwd;
20556
- const user = env.CLAUDE_CONFIG_DIR || path22.join(homeOf(env), ".claude");
20633
+ const user = env.CLAUDE_CONFIG_DIR || path23.join(homeOf(env), ".claude");
20557
20634
  return [
20558
20635
  ...CLAUDE_MANAGED[platform] ? [CLAUDE_MANAGED[platform]] : [],
20559
- path22.join(user, "settings.json"),
20560
- path22.join(project, ".claude", "settings.json"),
20561
- path22.join(project, ".claude", "settings.local.json")
20636
+ path23.join(user, "settings.json"),
20637
+ path23.join(project, ".claude", "settings.json"),
20638
+ path23.join(project, ".claude", "settings.local.json")
20562
20639
  ];
20563
20640
  }
20564
20641
  var bashPattern = (entry) => {
@@ -20648,10 +20725,10 @@ var opencodeConfig = (value, rules) => {
20648
20725
  function opencodeRules(cwd, env = process.env) {
20649
20726
  const rules = EMPTY();
20650
20727
  try {
20651
- const config = env.XDG_CONFIG_HOME || path22.join(homeOf(env), ".config");
20728
+ const config = env.XDG_CONFIG_HOME || path23.join(homeOf(env), ".config");
20652
20729
  const files = [
20653
- ...OPENCODE_NAMES.map((name) => path22.join(config, "opencode", name)),
20654
- ...projectDirs(cwd).flatMap((dir) => OPENCODE_NAMES.flatMap((name) => [path22.join(dir, name), path22.join(dir, ".opencode", name)])),
20730
+ ...OPENCODE_NAMES.map((name) => path23.join(config, "opencode", name)),
20731
+ ...projectDirs(cwd).flatMap((dir) => OPENCODE_NAMES.flatMap((name) => [path23.join(dir, name), path23.join(dir, ".opencode", name)])),
20655
20732
  ...env.OPENCODE_CONFIG ? [env.OPENCODE_CONFIG] : []
20656
20733
  ];
20657
20734
  for (const file of files) {
@@ -20695,19 +20772,19 @@ var codexRule = (body) => {
20695
20772
  function codexRules(cwd, env = process.env) {
20696
20773
  const rules = EMPTY();
20697
20774
  try {
20698
- const home = env.CODEX_HOME || path22.join(homeOf(env), ".codex");
20775
+ const home = env.CODEX_HOME || path23.join(homeOf(env), ".codex");
20699
20776
  const top = gitTop(cwd) ?? cwd;
20700
- for (const dir of [path22.join(home, "rules"), path22.join(top, ".codex", "rules")]) {
20777
+ for (const dir of [path23.join(home, "rules"), path23.join(top, ".codex", "rules")]) {
20701
20778
  let files;
20702
20779
  try {
20703
- files = fs17.readdirSync(dir).filter((name) => name.endsWith(".rules"));
20780
+ files = fs18.readdirSync(dir).filter((name) => name.endsWith(".rules"));
20704
20781
  } catch (error) {
20705
20782
  if (error.code === "ENOENT")
20706
20783
  continue;
20707
20784
  return "unreadable";
20708
20785
  }
20709
20786
  for (const name of files) {
20710
- const text = readText2(path22.join(dir, name)) ?? "";
20787
+ const text = readText2(path23.join(dir, name)) ?? "";
20711
20788
  for (const part of text.split(/\bprefix_rule\s*\(/u).slice(1)) {
20712
20789
  const rule = codexRule(part);
20713
20790
  if (!rule)
@@ -20726,8 +20803,8 @@ function cursorRules(cwd, env = process.env) {
20726
20803
  try {
20727
20804
  const top = gitTop(cwd) ?? cwd;
20728
20805
  for (const file of [
20729
- path22.join(homeOf(env), ".cursor", "cli-config.json"),
20730
- path22.join(top, ".cursor", "cli.json")
20806
+ path23.join(homeOf(env), ".cursor", "cli-config.json"),
20807
+ path23.join(top, ".cursor", "cli.json")
20731
20808
  ]) {
20732
20809
  const text = readText2(file);
20733
20810
  if (text === null)
@@ -20801,23 +20878,23 @@ function wrapAllowed(read, words, command, options = {}) {
20801
20878
  }
20802
20879
 
20803
20880
  // packages/workit-core/src/core/heavy.ts
20804
- import fs18 from "node:fs";
20881
+ import fs19 from "node:fs";
20805
20882
  import os7 from "node:os";
20806
- import path23 from "node:path";
20883
+ import path24 from "node:path";
20807
20884
  function stateDir(env, platform = process.platform) {
20808
20885
  if (env.WORKFLOW_TOOLKIT_STATE)
20809
20886
  return env.WORKFLOW_TOOLKIT_STATE;
20810
20887
  if (env.XDG_STATE_HOME)
20811
- return path23.join(env.XDG_STATE_HOME, "workit");
20888
+ return path24.join(env.XDG_STATE_HOME, "workit");
20812
20889
  const home = env.HOME || os7.homedir();
20813
20890
  if (platform === "darwin")
20814
- return path23.join(home, "Library", "Application Support", "workit");
20891
+ return path24.join(home, "Library", "Application Support", "workit");
20815
20892
  if (platform === "win32")
20816
- return path23.join(env.LOCALAPPDATA ?? path23.join(home, "AppData", "Local"), "workit");
20817
- return path23.join(home, ".local", "state", "workit");
20893
+ return path24.join(env.LOCALAPPDATA ?? path24.join(home, "AppData", "Local"), "workit");
20894
+ return path24.join(home, ".local", "state", "workit");
20818
20895
  }
20819
20896
  var HEAVY_COMMANDS_FILE = "heavy-commands.json";
20820
- var heavyCommandsFile = (env) => path23.join(stateDir(env), HEAVY_COMMANDS_FILE);
20897
+ var heavyCommandsFile = (env) => path24.join(stateDir(env), HEAVY_COMMANDS_FILE);
20821
20898
  var HEAVY_SCRIPT = /^(?:test|tests|t|tst|unit|integration|e2e|coverage|cov|lint|eslint|typecheck|type-check|types|tsc|check|verify|validate|build|compile|bundle|ci|sonar|cypress|playwright|jest|vitest|mocha|bench|benchmark|all)(?:$|[:_.-])/iu;
20822
20899
  var INFO_FLAGS = new Set(["--version", "-v", "-V", "--help", "-h", "help", "version"]);
20823
20900
  var WATCH_FLAG = /^(?:--watch(?:All)?(?:=.*)?|-w|--serve)$/u;
@@ -21080,7 +21157,7 @@ function parsePattern(pattern) {
21080
21157
  var 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]));
21081
21158
  var readJson = (file) => {
21082
21159
  try {
21083
- return JSON.parse(fs18.readFileSync(file, "utf8"));
21160
+ return JSON.parse(fs19.readFileSync(file, "utf8"));
21084
21161
  } catch {
21085
21162
  return;
21086
21163
  }
@@ -21092,7 +21169,7 @@ function machinePatterns(env) {
21092
21169
  return isRecord5(value) ? stringList(value.patterns) : [];
21093
21170
  }
21094
21171
  function repoPatterns(cwd) {
21095
- return repoHeavyCommands(gitTop(cwd) ?? path23.resolve(cwd));
21172
+ return repoHeavyCommands(gitTop(cwd) ?? path24.resolve(cwd));
21096
21173
  }
21097
21174
  function heavyLines(lines, options) {
21098
21175
  const found = [];
@@ -21170,12 +21247,12 @@ function heavyPlan(command, options) {
21170
21247
  }
21171
21248
  function workitOnPath2(env = process.env) {
21172
21249
  const names = process.platform === "win32" ? ["workit.exe", "workit.cmd", "workit"] : ["workit"];
21173
- for (const dir of (env.PATH ?? "").split(path23.delimiter))
21250
+ for (const dir of (env.PATH ?? "").split(path24.delimiter))
21174
21251
  for (const name of names) {
21175
21252
  if (!dir)
21176
21253
  continue;
21177
21254
  try {
21178
- fs18.accessSync(path23.join(dir, name), fs18.constants.X_OK);
21255
+ fs19.accessSync(path24.join(dir, name), fs19.constants.X_OK);
21179
21256
  return true;
21180
21257
  } catch {}
21181
21258
  }
@@ -21192,41 +21269,41 @@ function leaseRewrite(command) {
21192
21269
  }
21193
21270
 
21194
21271
  // packages/workit-core/src/core/heavy-words.ts
21195
- import fs19 from "node:fs";
21272
+ import fs20 from "node:fs";
21196
21273
  import os8 from "node:os";
21197
- import path24 from "node:path";
21274
+ import path25 from "node:path";
21198
21275
  var HEAVY_WORDS = new Set(("npm npx pnpm pnpx yarn bun bunx deno corepack make gmake docker podman nerdctl " + "python python3 py uv poetry pdm pipenv hatch rye bundle rake nx " + "jest vitest mocha ava tap karma jasmine nyc c8 tsc vue-tsc svelte-check eslint stylelint " + "tslint webpack webpack-cli rollup parcel tsup vite next nuxt nuxi astro ng react-scripts " + "playwright cypress wdio testcafe turbo lerna sonar-scanner sonarless sonarless-mcp go " + "golangci-lint gotestsum staticcheck cargo mvn mvnw gradle gradlew ant sbt bazel bazelisk " + "buck2 dotnet msbuild pytest py.test tox nox mypy pyright pylint coverage maturin pip pip3 " + "rspec rails phpunit pest phpstan psalm composer mix swift xcodebuild flutter dart pod cmake " + "ninja meson ctest scons docker-compose buildah earthly").split(" "));
21199
21276
  var wordsOf = (command) => command.split(/[\s;&|()<>`'"]+/u).map((word) => (word.split(/[\\/]/u).at(-1) ?? "").toLowerCase().replace(/\.(?:exe|cmd|bat)$/u, "")).filter(Boolean);
21200
21277
  var stateDir2 = (env) => {
21201
21278
  if (env.WORKFLOW_TOOLKIT_STATE)
21202
21279
  return env.WORKFLOW_TOOLKIT_STATE;
21203
21280
  if (env.XDG_STATE_HOME)
21204
- return path24.join(env.XDG_STATE_HOME, "workit");
21281
+ return path25.join(env.XDG_STATE_HOME, "workit");
21205
21282
  const home = env.HOME || os8.homedir();
21206
21283
  if (process.platform === "darwin")
21207
- return path24.join(home, "Library", "Application Support", "workit");
21284
+ return path25.join(home, "Library", "Application Support", "workit");
21208
21285
  if (process.platform === "win32")
21209
- return path24.join(env.LOCALAPPDATA ?? path24.join(home, "AppData", "Local"), "workit");
21210
- return path24.join(home, ".local", "state", "workit");
21286
+ return path25.join(env.LOCALAPPDATA ?? path25.join(home, "AppData", "Local"), "workit");
21287
+ return path25.join(home, ".local", "state", "workit");
21211
21288
  };
21212
21289
  var readJson2 = (file) => {
21213
21290
  try {
21214
- return JSON.parse(fs19.readFileSync(file, "utf8"));
21291
+ return JSON.parse(fs20.readFileSync(file, "utf8"));
21215
21292
  } catch {
21216
21293
  return;
21217
21294
  }
21218
21295
  };
21219
21296
  var patternWords = (cwd, env) => {
21220
21297
  const patterns = [];
21221
- const machine = readJson2(path24.join(stateDir2(env), "heavy-commands.json"));
21298
+ const machine = readJson2(path25.join(stateDir2(env), "heavy-commands.json"));
21222
21299
  if (Array.isArray(machine?.patterns))
21223
21300
  patterns.push(...machine.patterns);
21224
- for (let dir = path24.resolve(cwd);; dir = path24.dirname(dir)) {
21225
- if (fs19.existsSync(path24.join(dir, ".git"))) {
21301
+ for (let dir = path25.resolve(cwd);; dir = path25.dirname(dir)) {
21302
+ if (fs20.existsSync(path25.join(dir, ".git"))) {
21226
21303
  patterns.push(...repoHeavyCommands(dir));
21227
21304
  break;
21228
21305
  }
21229
- if (path24.dirname(dir) === dir)
21306
+ if (path25.dirname(dir) === dir)
21230
21307
  break;
21231
21308
  }
21232
21309
  const words = new Set;
@@ -21298,14 +21375,14 @@ var splitDenial = (plan) => ({
21298
21375
  // packages/workit-core/src/hooks/write-gate.ts
21299
21376
  import { realpathSync as realpathSync5 } from "node:fs";
21300
21377
  import os10 from "node:os";
21301
- import path26 from "node:path";
21378
+ import path27 from "node:path";
21302
21379
 
21303
21380
  // packages/workit-core/src/core/live-session.ts
21304
21381
  import { spawnSync as spawnSync13 } from "node:child_process";
21305
- import { createHash as createHash15 } from "node:crypto";
21306
- import fs20 from "node:fs";
21382
+ import { createHash as createHash16 } from "node:crypto";
21383
+ import fs21 from "node:fs";
21307
21384
  import os9 from "node:os";
21308
- import path25 from "node:path";
21385
+ import path26 from "node:path";
21309
21386
  var LIVE_SESSION_TTL_MS = 15 * 60000;
21310
21387
  var HEARTBEAT_EVERY_MS = 30000;
21311
21388
  var liveProbe = {
@@ -21326,9 +21403,9 @@ var processAlive = (pid) => {
21326
21403
  var processInfo = (pid) => {
21327
21404
  try {
21328
21405
  if (liveProbe.platform === "linux") {
21329
- const stat = fs20.readFileSync(`/proc/${pid}/stat`, "utf8");
21406
+ const stat = fs21.readFileSync(`/proc/${pid}/stat`, "utf8");
21330
21407
  const ppid = Number(stat.slice(stat.lastIndexOf(")") + 2).split(" ")[1]);
21331
- const command = fs20.readFileSync(`/proc/${pid}/cmdline`, "utf8").replaceAll("\x00", " ");
21408
+ const command = fs21.readFileSync(`/proc/${pid}/cmdline`, "utf8").replaceAll("\x00", " ");
21332
21409
  return Number.isInteger(ppid) ? { ppid, command: command.trim() } : null;
21333
21410
  }
21334
21411
  if (liveProbe.platform === "win32")
@@ -21379,35 +21456,35 @@ var liveOwner = (input, transport, env = process.env) => {
21379
21456
  };
21380
21457
  };
21381
21458
  var checkoutOf = (target) => {
21382
- let dir = path25.resolve(target);
21383
- while (!fs20.existsSync(dir) && path25.dirname(dir) !== dir)
21384
- dir = path25.dirname(dir);
21385
- if (fs20.existsSync(dir) && !fs20.statSync(dir).isDirectory())
21386
- dir = path25.dirname(dir);
21387
- const parts = dir.split(path25.sep);
21459
+ let dir = path26.resolve(target);
21460
+ while (!fs21.existsSync(dir) && path26.dirname(dir) !== dir)
21461
+ dir = path26.dirname(dir);
21462
+ if (fs21.existsSync(dir) && !fs21.statSync(dir).isDirectory())
21463
+ dir = path26.dirname(dir);
21464
+ const parts = dir.split(path26.sep);
21388
21465
  const dotGit = parts.lastIndexOf(".git");
21389
21466
  if (dotGit > 0)
21390
- dir = parts.slice(0, dotGit).join(path25.sep) || path25.sep;
21467
+ dir = parts.slice(0, dotGit).join(path26.sep) || path26.sep;
21391
21468
  const location = resolveStore(dir);
21392
21469
  if (location instanceof Error || !location.shared || !location.top)
21393
21470
  return null;
21394
21471
  let top = location.top;
21395
21472
  try {
21396
- top = fs20.realpathSync.native(top);
21473
+ top = fs21.realpathSync.native(top);
21397
21474
  } catch {}
21398
21475
  return top;
21399
21476
  };
21400
- var markerFile2 = (top) => path25.join(resolveStateDir(), "live-sessions", `${createHash15("sha256").update(checkoutKey(top)).digest("hex").slice(0, 32)}.json`);
21477
+ var markerFile2 = (top) => path26.join(resolveStateDir(), "live-sessions", `${createHash16("sha256").update(checkoutKey(top)).digest("hex").slice(0, 32)}.json`);
21401
21478
  var checkoutKey = (top, platform = process.platform) => {
21402
- let key = path25.resolve(top);
21479
+ let key = path26.resolve(top);
21403
21480
  try {
21404
- key = fs20.realpathSync.native(key);
21481
+ key = fs21.realpathSync.native(key);
21405
21482
  } catch {}
21406
21483
  return platform === "win32" ? key.replaceAll("/", "\\").toLowerCase() : key;
21407
21484
  };
21408
21485
  var readMarker = (file) => {
21409
21486
  try {
21410
- const value = JSON.parse(fs20.readFileSync(file, "utf8"));
21487
+ const value = JSON.parse(fs21.readFileSync(file, "utf8"));
21411
21488
  if (value?.version !== 1 || typeof value.session !== "string" || typeof value.host !== "string" || typeof value.heartbeatAt !== "string" || Number.isNaN(Date.parse(value.heartbeatAt)))
21412
21489
  return null;
21413
21490
  return {
@@ -21494,10 +21571,10 @@ var claimLiveSession = (target, owner, deps = {}) => {
21494
21571
  checkout,
21495
21572
  heartbeatAt: now.toISOString()
21496
21573
  };
21497
- fs20.mkdirSync(path25.dirname(file), { recursive: true });
21574
+ fs21.mkdirSync(path26.dirname(file), { recursive: true });
21498
21575
  const temp = `${file}.${process.pid}.tmp`;
21499
- fs20.writeFileSync(temp, JSON.stringify(marker));
21500
- fs20.renameSync(temp, file);
21576
+ fs21.writeFileSync(temp, JSON.stringify(marker));
21577
+ fs21.renameSync(temp, file);
21501
21578
  } catch {}
21502
21579
  };
21503
21580
 
@@ -21506,22 +21583,22 @@ var NONE3 = { kind: "none" };
21506
21583
  var CASE_INSENSITIVE = process.platform === "darwin" || process.platform === "win32";
21507
21584
  var canonical2 = (file) => {
21508
21585
  let rest = "";
21509
- for (let dir = path26.resolve(file);; dir = path26.dirname(dir)) {
21586
+ for (let dir = path27.resolve(file);; dir = path27.dirname(dir)) {
21510
21587
  try {
21511
- return path26.join(realpathSync5.native(dir), rest);
21588
+ return path27.join(realpathSync5.native(dir), rest);
21512
21589
  } catch {
21513
- if (path26.dirname(dir) === dir)
21514
- return path26.resolve(file);
21515
- rest = rest ? path26.join(path26.basename(dir), rest) : path26.basename(dir);
21590
+ if (path27.dirname(dir) === dir)
21591
+ return path27.resolve(file);
21592
+ rest = rest ? path27.join(path27.basename(dir), rest) : path27.basename(dir);
21516
21593
  }
21517
21594
  }
21518
21595
  };
21519
21596
  var exempt = (cwd, root, file, plans) => {
21520
21597
  const fold = (value) => CASE_INSENSITIVE ? value.toLowerCase() : value;
21521
- const relative = path26.relative(fold(canonical2(root)), fold(canonical2(path26.resolve(cwd, file))));
21522
- if (relative.startsWith("..") || path26.isAbsolute(relative))
21598
+ const relative = path27.relative(fold(canonical2(root)), fold(canonical2(path27.resolve(cwd, file))));
21599
+ if (relative.startsWith("..") || path27.isAbsolute(relative))
21523
21600
  return true;
21524
- const posix = relative.split(path26.sep).join("/");
21601
+ const posix = relative.split(path27.sep).join("/");
21525
21602
  const segments = posix.split("/");
21526
21603
  return /\.mdx?$/i.test(posix) || segments[0] === "docs" || segments.includes("plans") || [...plans].some((plan) => fold(plan) === posix);
21527
21604
  };
@@ -21642,7 +21719,7 @@ var shellWrites = (command, depth = 0) => {
21642
21719
  return { writes: true, targets: unknown ? null : targets };
21643
21720
  };
21644
21721
  var cache2 = new Map;
21645
- var planKeyOf = (root, plans) => [...plans].map((file) => fileSignature(path26.resolve(root, file)) ?? "-").join("\x00");
21722
+ var planKeyOf = (root, plans) => [...plans].map((file) => fileSignature(path27.resolve(root, file)) ?? "-").join("\x00");
21646
21723
  var gateFor = (cwd) => {
21647
21724
  const store = new TaskStore(cwd);
21648
21725
  const listed = store.listTaskIndex();
@@ -21721,7 +21798,7 @@ var gitMutationDirs = (cwd, command, dialect) => {
21721
21798
  return [];
21722
21799
  if (sub === "stash" && ["list", "show"].includes(rest[0] ?? ""))
21723
21800
  return [];
21724
- return [path26.resolve(cwd, invocation.dir ?? ".")];
21801
+ return [path27.resolve(cwd, invocation.dir ?? ".")];
21725
21802
  });
21726
21803
  };
21727
21804
  var CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
@@ -21732,7 +21809,7 @@ var cdInto = (dir, words) => {
21732
21809
  const target = named === undefined ? undefined : homeExpanded(named);
21733
21810
  if (dir === undefined || target === "-" || target && /^~|[$`*?]/.test(target))
21734
21811
  return;
21735
- return target === undefined ? os10.homedir() : path26.resolve(dir, target);
21812
+ return target === undefined ? os10.homedir() : path27.resolve(dir, target);
21736
21813
  };
21737
21814
  var quoteWord2 = (word) => /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replaceAll("'", "'\\''")}'`;
21738
21815
  var homeExpanded = (file) => {
@@ -21746,7 +21823,7 @@ var segmentTargets = (cwd, command, dialect, depth = 0) => {
21746
21823
  const groups = [];
21747
21824
  const at = (file) => {
21748
21825
  const home = homeExpanded(file);
21749
- return path26.isAbsolute(home) ? home : dir === undefined ? null : path26.resolve(dir, home);
21826
+ return path27.isAbsolute(home) ? home : dir === undefined ? null : path27.resolve(dir, home);
21750
21827
  };
21751
21828
  for (const segment of segmentsOf(command, dialect)) {
21752
21829
  if (segment.group === "open") {
@@ -21787,7 +21864,7 @@ var segmentTargets = (cwd, command, dialect, depth = 0) => {
21787
21864
  const edits = editsOf(segment.words);
21788
21865
  if (edits === null) {
21789
21866
  if (dir !== undefined)
21790
- targets.push(path26.join(dir, DIR_TARGET));
21867
+ targets.push(path27.join(dir, DIR_TARGET));
21791
21868
  } else
21792
21869
  for (const file of edits) {
21793
21870
  const resolved = at(file);
@@ -21795,7 +21872,7 @@ var segmentTargets = (cwd, command, dialect, depth = 0) => {
21795
21872
  targets.push(resolved);
21796
21873
  }
21797
21874
  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), "")))
21798
- targets.push(path26.join(dir, DIR_TARGET));
21875
+ targets.push(path27.join(dir, DIR_TARGET));
21799
21876
  }
21800
21877
  return targets;
21801
21878
  };
@@ -21830,7 +21907,7 @@ var liveDeny = ({ marker, checkout, ageMs, file }) => {
21830
21907
  var guarded = (targets) => {
21831
21908
  const seen = new Set;
21832
21909
  return targets.filter((target) => {
21833
- const dir = path26.dirname(target);
21910
+ const dir = path27.dirname(target);
21834
21911
  if (seen.has(dir))
21835
21912
  return false;
21836
21913
  seen.add(dir);
@@ -21851,7 +21928,7 @@ var claimAll = (owner, targets, deps) => {
21851
21928
  for (const target of guarded(targets))
21852
21929
  claimLiveSession(target, owner, deps);
21853
21930
  };
21854
- var liveTargets = (cwd, paths) => paths?.length ? paths.map((file) => path26.resolve(cwd, file)) : [path26.join(cwd, DIR_TARGET)];
21931
+ var liveTargets = (cwd, paths) => paths?.length ? paths.map((file) => path27.resolve(cwd, file)) : [path27.join(cwd, DIR_TARGET)];
21855
21932
  var issuedTarget = (cwd, targets) => {
21856
21933
  const state = resolveStateDir();
21857
21934
  const found = targets.find((target) => underIssued(state, cwd, homeExpanded(target), process.platform, canonical2));
@@ -21859,7 +21936,7 @@ var issuedTarget = (cwd, targets) => {
21859
21936
  };
21860
21937
  var underIssued = (state, cwd, target, platform = process.platform, real = (file) => file) => {
21861
21938
  const win = platform === "win32";
21862
- const p = win ? path26.win32 : path26.posix;
21939
+ const p = win ? path27.win32 : path27.posix;
21863
21940
  const fold = (value) => win || platform === "darwin" ? value.toLowerCase() : value;
21864
21941
  const named = win ? target.replace(/^\/([a-zA-Z])(?=\/|$)/, "$1:") : target;
21865
21942
  const relative = p.relative(fold(real(p.resolve(state))), fold(real(p.resolve(cwd, named))));
@@ -21908,7 +21985,7 @@ function shellGate(cwd, command, owner, dialect = "posix", deps) {
21908
21985
  try {
21909
21986
  targets = [
21910
21987
  ...segmentTargets(cwd, command, dialect),
21911
- ...gitMutationDirs(cwd, command, dialect).map((dir) => path26.join(dir, DIR_TARGET))
21988
+ ...gitMutationDirs(cwd, command, dialect).map((dir) => path27.join(dir, DIR_TARGET))
21912
21989
  ];
21913
21990
  } catch {
21914
21991
  targets = [];
@@ -22342,12 +22419,12 @@ ${line}` };
22342
22419
  };
22343
22420
  // packages/workit-core/src/hooks/hosts/fields.ts
22344
22421
  import { existsSync as existsSync7, realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
22345
- import path27 from "node:path";
22422
+ import path28 from "node:path";
22346
22423
  var isRecord6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
22347
22424
  var nonEmpty2 = (value) => typeof value === "string" && value.trim() !== "";
22348
22425
  var optionalText = (value) => typeof value === "string" ? value : null;
22349
22426
  var existingDirectory = (value) => {
22350
- if (!nonEmpty2(value) || !path27.isAbsolute(value) || !existsSync7(value))
22427
+ if (!nonEmpty2(value) || !path28.isAbsolute(value) || !existsSync7(value))
22351
22428
  return null;
22352
22429
  try {
22353
22430
  return statSync2(value).isDirectory() ? realpathSync6(value) : null;
@@ -22413,6 +22490,109 @@ var writeTargets = (input) => {
22413
22490
  const paths = writePaths(input);
22414
22491
  return paths.length > 0 ? paths : null;
22415
22492
  };
22493
+ // packages/workit-core/src/hooks/standing.ts
22494
+ import fs22 from "node:fs";
22495
+ import path29 from "node:path";
22496
+ var readPlans = (store) => {
22497
+ const dir = path29.join(store, "fanouts");
22498
+ let names;
22499
+ try {
22500
+ names = fs22.readdirSync(dir).filter((name) => name.endsWith(".json"));
22501
+ } catch {
22502
+ return [];
22503
+ }
22504
+ const plans = [];
22505
+ for (const name of names) {
22506
+ try {
22507
+ const raw = JSON.parse(fs22.readFileSync(path29.join(dir, name), "utf8"));
22508
+ if (typeof raw.name !== "string" || !Array.isArray(raw.slices))
22509
+ continue;
22510
+ const texts = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string" && item !== "") : [];
22511
+ plans.push({
22512
+ name: raw.name,
22513
+ leads: texts([raw.leadSession, ...texts(raw.formerLeads)]),
22514
+ branches: texts(raw.slices.map((slice) => slice && typeof slice === "object" ? slice.branch : null))
22515
+ });
22516
+ } catch {}
22517
+ }
22518
+ return plans;
22519
+ };
22520
+ var leadOf2 = (input) => input.session.parentId ?? (input.session.agentId ? input.session.id : null) ?? (input.session.id.includes(":") ? input.session.id.split(":")[0] : null);
22521
+ var worksFor = (plan, input, branch) => {
22522
+ const session = input.session.id;
22523
+ if (plan.leads.includes(session) && !input.session.agentId)
22524
+ return false;
22525
+ const lead = leadOf2(input);
22526
+ if (lead && plan.leads.includes(lead))
22527
+ return true;
22528
+ if (plan.leads.some((each) => session.startsWith(`${each}-w-`)))
22529
+ return true;
22530
+ const current = branch();
22531
+ return current !== null && plan.branches.includes(current);
22532
+ };
22533
+ var standingFor = (input, store, rev) => {
22534
+ const orders = new Map;
22535
+ const ledger = readLedger(input.cwd);
22536
+ const rows = ledger.ok ? ledger.value.rows : [];
22537
+ let branch;
22538
+ const lazyBranch = () => branch === undefined ? branch = currentBranch(input.cwd) : branch;
22539
+ for (const plan of readPlans(store))
22540
+ if (worksFor(plan, input, lazyBranch))
22541
+ for (const row of activeStanding(rows, plan.name, plan.leads.length ? plan.leads : null))
22542
+ orders.set(row.id, row);
22543
+ return { rev, orders, rows };
22544
+ };
22545
+ var located = (input) => {
22546
+ const store = input.session.id ? gitStoreDir(input.cwd) : null;
22547
+ const rev = store ? readStandingRev(store) : null;
22548
+ if (!store || rev === null)
22549
+ return null;
22550
+ return { store, rev, file: standingSeenFile(store, input.session.id, input.session.agentId) };
22551
+ };
22552
+ var seedStanding = (input) => {
22553
+ try {
22554
+ const where = located(input);
22555
+ if (!where)
22556
+ return;
22557
+ const now = standingFor(input, where.store, where.rev);
22558
+ writeStandingSeen(where.file, { rev: where.rev, ids: [...now.orders.keys()] });
22559
+ } catch {}
22560
+ };
22561
+ var fanoutOf = (row) => typeof row.fanout === "string" ? row.fanout : "?";
22562
+ var changedSince = (now, ids) => {
22563
+ const known = new Set(ids);
22564
+ const added = [...now.orders.values()].filter((row) => !known.has(row.id));
22565
+ const byId = new Map(now.rows.map((row) => [row.id, row]));
22566
+ const dropped = ids.filter((id) => !now.orders.has(id)).map((id) => byId.get(id)).filter((row) => row !== undefined);
22567
+ if (!added.length && !dropped.length)
22568
+ return null;
22569
+ const fanouts = [...new Set([...added, ...dropped].map(fanoutOf))].join(", ");
22570
+ const lines = [
22571
+ `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.`,
22572
+ ...added.map((row) => ` - new: ${String(row.what)}`),
22573
+ ...dropped.map((row) => ` - no longer in force: ${String(row.what)}${row.stop ? " (the stop is lifted: continue your brief)" : ""}`)
22574
+ ];
22575
+ if (added.some((row) => row.stop === true))
22576
+ 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.");
22577
+ return lines.join(`
22578
+ `);
22579
+ };
22580
+ var standingDelta = (input) => {
22581
+ try {
22582
+ const where = located(input);
22583
+ if (!where)
22584
+ return null;
22585
+ const seen = readStandingSeen(where.file);
22586
+ if (seen.rev === where.rev)
22587
+ return null;
22588
+ const now = standingFor(input, where.store, where.rev);
22589
+ writeStandingSeen(where.file, { rev: where.rev, ids: [...now.orders.keys()] });
22590
+ return changedSince(now, seen.ids);
22591
+ } catch {
22592
+ return null;
22593
+ }
22594
+ };
22595
+ var sinceStart = new Map;
22416
22596
  // packages/workit-core/src/hooks/handle.ts
22417
22597
  var usable2 = (value) => value === "native" || value === "partial";
22418
22598
  var NONE5 = { kind: "none" };
@@ -22457,7 +22637,18 @@ ${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
22457
22637
  const pick = judge === "verifier" ? ", --kind live when you drove the real surface" : "";
22458
22638
  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." : ""}`;
22459
22639
  };
22640
+ var PRE_TOOL = new Set(["shell.pre", "write.pre", "tool.pre"]);
22460
22641
  function handleHook(input, deps) {
22642
+ const decision = decide(input, deps);
22643
+ if (deps.descriptor.transport !== "hook-process" || !PRE_TOOL.has(input.event.kind) || decision.kind === "deny")
22644
+ return decision;
22645
+ const delta = standingDelta(input);
22646
+ if (!delta)
22647
+ return decision;
22648
+ return decision.kind === "rewrite" ? { ...decision, text: [decision.text, delta].filter(Boolean).join(`
22649
+ `) } : withContextLine(decision, delta);
22650
+ }
22651
+ function decide(input, deps) {
22461
22652
  const { descriptor } = deps;
22462
22653
  const event = input.event;
22463
22654
  switch (event.kind) {
@@ -22534,6 +22725,7 @@ function handleHook(input, deps) {
22534
22725
  case "write.pre":
22535
22726
  return usable2(descriptor.events["write.pre"].support) ? writeGate(input.cwd, event.paths, liveOwner(input, descriptor.transport)) : NONE5;
22536
22727
  case "subagent.start":
22728
+ seedStanding({ ...input, session: { ...input.session, agentId: event.agentId } });
22537
22729
  return {
22538
22730
  kind: "context",
22539
22731
  text: subagentStartText(input, descriptor, event)
@@ -22585,7 +22777,7 @@ var dispatchHook = (adapter, raw, env = process.env) => {
22585
22777
  };
22586
22778
  // packages/workit-core/src/hooks/deadline.ts
22587
22779
  import { appendFileSync, mkdirSync as mkdirSync3 } from "node:fs";
22588
- import path28 from "node:path";
22780
+ import path30 from "node:path";
22589
22781
  var HOOK_SKIP_TEXT = "workit context skipped: host under load";
22590
22782
  var HOOK_DEADLINE_MS = 8000;
22591
22783
  var HOST_DEADLINES = {
@@ -22603,7 +22795,7 @@ var hookDeadlineMs = (env, host = "", native) => {
22603
22795
  const row = HOST_DEADLINES[host];
22604
22796
  return override(env) ?? (row ? native === undefined ? Math.min(...Object.values(row)) : row[native] ?? row[""] : HOOK_DEADLINE_MS);
22605
22797
  };
22606
- var skipsFile = (stateDir) => path28.join(stateDir, HOOK_SKIPS_FILE);
22798
+ var skipsFile = (stateDir) => path30.join(stateDir, HOOK_SKIPS_FILE);
22607
22799
  var recordHookSkip = (skip, stateDir = resolveStateDir()) => {
22608
22800
  try {
22609
22801
  mkdirSync3(stateDir, { recursive: true });
@@ -23247,8 +23439,8 @@ var codexAdapter = {
23247
23439
  };
23248
23440
 
23249
23441
  // packages/workit-core/src/hooks/hosts/cursor.ts
23250
- import fs21 from "node:fs";
23251
- import path29 from "node:path";
23442
+ import fs23 from "node:fs";
23443
+ import path31 from "node:path";
23252
23444
  var undocumented = { support: "undocumented", native: null };
23253
23445
  var none = { support: "none", native: null };
23254
23446
  var CURSOR_DESCRIPTOR = {
@@ -23445,17 +23637,17 @@ var protocolEvent2 = (input) => {
23445
23637
  };
23446
23638
  var TRANSCRIPT_TAIL_BYTES = 256 * 1024;
23447
23639
  var lastAssistantText = (file) => {
23448
- if (!file || !path29.isAbsolute(file))
23640
+ if (!file || !path31.isAbsolute(file))
23449
23641
  return null;
23450
23642
  try {
23451
- const size = fs21.statSync(file).size;
23643
+ const size = fs23.statSync(file).size;
23452
23644
  const start = Math.max(0, size - TRANSCRIPT_TAIL_BYTES);
23453
23645
  const buffer = Buffer.alloc(size - start);
23454
- const fd = fs21.openSync(file, "r");
23646
+ const fd = fs23.openSync(file, "r");
23455
23647
  try {
23456
- fs21.readSync(fd, buffer, 0, buffer.length, start);
23648
+ fs23.readSync(fd, buffer, 0, buffer.length, start);
23457
23649
  } finally {
23458
- fs21.closeSync(fd);
23650
+ fs23.closeSync(fd);
23459
23651
  }
23460
23652
  const lines = buffer.toString("utf8").split(`
23461
23653
  `);
@@ -23482,7 +23674,7 @@ var lastAssistantText = (file) => {
23482
23674
  return null;
23483
23675
  }
23484
23676
  };
23485
- var within2 = (root, dir) => dir === root || dir.startsWith(root.endsWith(path29.sep) ? root : `${root}${path29.sep}`);
23677
+ var within2 = (root, dir) => dir === root || dir.startsWith(root.endsWith(path31.sep) ? root : `${root}${path31.sep}`);
23486
23678
  var hookCwd = (input) => {
23487
23679
  const cwd = existingDirectory(input.cwd);
23488
23680
  if (cwd && input.hook_event_name === "beforeShellExecution")