@brainervirus/workit-cursor 8.9.1 → 8.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8377,7 +8377,7 @@ import { realpathSync as realpathSync4 } from "node:fs";
8377
8377
 
8378
8378
  // packages/workit-core/src/core/policy/derive.ts
8379
8379
  import { existsSync as existsSync2 } from "node:fs";
8380
- import path7 from "node:path";
8380
+ import path8 from "node:path";
8381
8381
 
8382
8382
  // packages/workit-core/src/git/rev.ts
8383
8383
  import { spawnSync } from "node:child_process";
@@ -8562,9 +8562,9 @@ function pushRemoteName(cwd, branch) {
8562
8562
 
8563
8563
  // packages/workit-core/src/ledger.ts
8564
8564
  import { spawnSync as spawnSync7 } from "node:child_process";
8565
- import { createHash as createHash6, randomBytes } from "node:crypto";
8566
- import fs4 from "node:fs";
8567
- import path6 from "node:path";
8565
+ import { createHash as createHash7, randomBytes } from "node:crypto";
8566
+ import fs5 from "node:fs";
8567
+ import path7 from "node:path";
8568
8568
 
8569
8569
  // packages/workit-core/src/core/vcs-config.ts
8570
8570
  import fs2 from "node:fs";
@@ -9799,33 +9799,9 @@ function vcsConfig(mode, cwd, options = {}) {
9799
9799
  }
9800
9800
 
9801
9801
  // packages/workit-core/src/host-session.ts
9802
- var HOST_SESSION_VARS = [
9803
- ["OPENCODE_SESSION_ID", () => "opencode"],
9804
- ["PI_SESSION_ID", () => "pi"],
9805
- [
9806
- "CODEX_THREAD_ID",
9807
- (env) => env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || env.CODEX_ELECTRON_RESOURCES_PATH ? "codex_desktop" : "codex_cli"
9808
- ]
9809
- ];
9810
- var family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null;
9811
- function hostSessionFromEnv(env) {
9812
- const value = (key) => env[key]?.trim() || null;
9813
- let inner = null;
9814
- for (const [key, host] of HOST_SESSION_VARS) {
9815
- const session = value(key);
9816
- if (session) {
9817
- inner = { host: host(env), session };
9818
- break;
9819
- }
9820
- }
9821
- const declared = value("WORKIT_HOST");
9822
- if (env.WORKIT_SESSION_ID !== undefined) {
9823
- const inherited = inner !== null && declared !== null && family(declared) !== family(inner.host);
9824
- if (!inherited)
9825
- return { host: declared, session: value("WORKIT_SESSION_ID") };
9826
- }
9827
- return inner ? { host: inner.host, session: inner.session } : { host: declared, session: null };
9828
- }
9802
+ import { createHash as createHash6 } from "node:crypto";
9803
+ import fs4 from "node:fs";
9804
+ import path6 from "node:path";
9829
9805
 
9830
9806
  // packages/workit-core/src/store/paths.ts
9831
9807
  import { spawnSync as spawnSync6 } from "node:child_process";
@@ -10107,6 +10083,63 @@ var checkoutSlug = (root) => {
10107
10083
  return `${base}-${shortHash(canonical)}`;
10108
10084
  };
10109
10085
 
10086
+ // packages/workit-core/src/host-session.ts
10087
+ var HOST_SESSION_VARS = [
10088
+ ["OPENCODE_SESSION_ID", () => "opencode"],
10089
+ ["PI_SESSION_ID", () => "pi"],
10090
+ [
10091
+ "CODEX_THREAD_ID",
10092
+ (env) => env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || env.CODEX_ELECTRON_RESOURCES_PATH ? "codex_desktop" : "codex_cli"
10093
+ ]
10094
+ ];
10095
+ var family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null;
10096
+ function hostSessionFromEnv(env) {
10097
+ const value = (key) => env[key]?.trim() || null;
10098
+ let inner = null;
10099
+ for (const [key, host] of HOST_SESSION_VARS) {
10100
+ const session = value(key);
10101
+ if (session) {
10102
+ inner = { host: host(env), session };
10103
+ break;
10104
+ }
10105
+ }
10106
+ const declared = value("WORKIT_HOST");
10107
+ if (env.WORKIT_SESSION_ID !== undefined) {
10108
+ const inherited = inner !== null && declared !== null && family(declared) !== family(inner.host);
10109
+ if (!inherited)
10110
+ return { host: declared, session: value("WORKIT_SESSION_ID") };
10111
+ }
10112
+ return inner ? { host: inner.host, session: inner.session } : { host: declared, session: null };
10113
+ }
10114
+ var ISSUED_PER_LEAD = 64;
10115
+ var ISSUED_SESSIONS_MARKER = "workit-issued-sessions/1";
10116
+ var hash = (value) => createHash6("sha256").update(value).digest("hex").slice(0, 32);
10117
+ var issuedRoot = (cwd) => {
10118
+ const location = resolveStore(cwd);
10119
+ return location instanceof Error ? null : path6.join(location.dir, "hooks", "issued");
10120
+ };
10121
+ var issuedDir = (cwd, lead) => {
10122
+ const root = issuedRoot(cwd);
10123
+ return root === null ? null : path6.join(root, hash(lead));
10124
+ };
10125
+ function recordIssuedSession(cwd, lead, issued) {
10126
+ try {
10127
+ const dir = issuedDir(cwd, lead);
10128
+ if (!dir)
10129
+ return;
10130
+ fs4.mkdirSync(dir, { recursive: true });
10131
+ const own = hash(issued);
10132
+ fs4.writeFileSync(path6.join(dir, own), ISSUED_SESSIONS_MARKER);
10133
+ const entries = fs4.readdirSync(dir);
10134
+ if (entries.length <= ISSUED_PER_LEAD)
10135
+ return;
10136
+ const byAge = entries.filter((name) => name !== own).map((name) => ({ name, at: fs4.statSync(path6.join(dir, name)).mtimeMs })).toSorted((a, b) => a.at - b.at);
10137
+ for (const { name } of byAge.slice(0, entries.length - ISSUED_PER_LEAD))
10138
+ fs4.rmSync(path6.join(dir, name), { force: true });
10139
+ } catch {}
10140
+ }
10141
+ var OWN_CHILD_SHELL = new Set(["opencode", "pi"]);
10142
+
10110
10143
  // packages/workit-core/src/ledger.ts
10111
10144
  var LEDGER_VERSION = 1;
10112
10145
  var MAX_LINE_BYTES = 4096;
@@ -10212,7 +10245,7 @@ function diffHash(cwd, base, head) {
10212
10245
  ], GIT_TIMEOUTS.worktree);
10213
10246
  if (!diff.ok || !diff.stdout)
10214
10247
  return null;
10215
- const hash = createHash6("sha256");
10248
+ const hash = createHash7("sha256");
10216
10249
  for (const line of diff.stdout.split(`
10217
10250
  `)) {
10218
10251
  if (line.startsWith("index "))
@@ -10224,14 +10257,14 @@ function diffHash(cwd, base, head) {
10224
10257
  return `sha256:${hash.digest("hex")}`;
10225
10258
  }
10226
10259
  function storeRoot(cwd) {
10227
- const location = resolveStore(path6.resolve(cwd));
10260
+ const location = resolveStore(path7.resolve(cwd));
10228
10261
  if (location instanceof Error)
10229
10262
  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");
10230
10263
  return { ok: true, value: { root: location.dir, shared: location.shared } };
10231
10264
  }
10232
10265
  function ledgerPath(cwd) {
10233
10266
  const root = storeRoot(cwd);
10234
- return root.ok ? { ok: true, value: path6.join(root.value.root, "ledger", "ledger.jsonl") } : root;
10267
+ return root.ok ? { ok: true, value: path7.join(root.value.root, "ledger", "ledger.jsonl") } : root;
10235
10268
  }
10236
10269
  var newId2 = () => `${Date.now().toString(36)}-${randomBytes(6).toString("hex")}`;
10237
10270
  var NETWORK_FS_TYPES = new Set([
@@ -10251,7 +10284,7 @@ var onNetworkFs = (dir) => {
10251
10284
  if (process.platform !== "linux")
10252
10285
  return false;
10253
10286
  try {
10254
- return isNetworkFsType(fs4.statfsSync(dir).type);
10287
+ return isNetworkFsType(fs5.statfsSync(dir).type);
10255
10288
  } catch {
10256
10289
  return false;
10257
10290
  }
@@ -10261,15 +10294,15 @@ var LOCK_STALE_MS = 30000;
10261
10294
  var LOCK_OWNER = "owner";
10262
10295
  var lockToken = (lock) => {
10263
10296
  try {
10264
- return fs4.readFileSync(path6.join(lock, LOCK_OWNER), "utf8");
10297
+ return fs5.readFileSync(path7.join(lock, LOCK_OWNER), "utf8");
10265
10298
  } catch {
10266
10299
  return null;
10267
10300
  }
10268
10301
  };
10269
10302
  var lockAgeMs = (lock) => {
10270
- for (const target of [path6.join(lock, LOCK_OWNER), lock]) {
10303
+ for (const target of [path7.join(lock, LOCK_OWNER), lock]) {
10271
10304
  try {
10272
- return Date.now() - fs4.statSync(target).mtimeMs;
10305
+ return Date.now() - fs5.statSync(target).mtimeMs;
10273
10306
  } catch {}
10274
10307
  }
10275
10308
  return null;
@@ -10277,14 +10310,14 @@ var lockAgeMs = (lock) => {
10277
10310
  var ledgerLock = {
10278
10311
  acquire(lock) {
10279
10312
  try {
10280
- fs4.mkdirSync(lock);
10313
+ fs5.mkdirSync(lock);
10281
10314
  } catch (error) {
10282
10315
  if (error.code === "EEXIST")
10283
10316
  return null;
10284
10317
  throw error;
10285
10318
  }
10286
10319
  const token = `${process.pid}-${randomBytes(8).toString("hex")}`;
10287
- fs4.writeFileSync(path6.join(lock, LOCK_OWNER), token);
10320
+ fs5.writeFileSync(path7.join(lock, LOCK_OWNER), token);
10288
10321
  return token;
10289
10322
  },
10290
10323
  release(lock, token) {
@@ -10292,35 +10325,35 @@ var ledgerLock = {
10292
10325
  return false;
10293
10326
  const tomb = `${lock}.release-${randomBytes(6).toString("hex")}`;
10294
10327
  try {
10295
- fs4.renameSync(lock, tomb);
10328
+ fs5.renameSync(lock, tomb);
10296
10329
  } catch {
10297
10330
  return false;
10298
10331
  }
10299
10332
  if (lockToken(tomb) !== token) {
10300
10333
  try {
10301
- fs4.renameSync(tomb, lock);
10334
+ fs5.renameSync(tomb, lock);
10302
10335
  } catch {}
10303
10336
  return false;
10304
10337
  }
10305
- fs4.rmSync(tomb, { recursive: true, force: true });
10338
+ fs5.rmSync(tomb, { recursive: true, force: true });
10306
10339
  return true;
10307
10340
  },
10308
10341
  token: lockToken,
10309
10342
  reap(lock, observed) {
10310
10343
  const tomb = `${lock}.reap-${randomBytes(6).toString("hex")}`;
10311
10344
  try {
10312
- fs4.renameSync(lock, tomb);
10345
+ fs5.renameSync(lock, tomb);
10313
10346
  } catch {
10314
10347
  return false;
10315
10348
  }
10316
10349
  if (lockToken(tomb) === observed) {
10317
- fs4.rmSync(tomb, { recursive: true, force: true });
10350
+ fs5.rmSync(tomb, { recursive: true, force: true });
10318
10351
  return true;
10319
10352
  }
10320
10353
  try {
10321
- fs4.renameSync(tomb, lock);
10354
+ fs5.renameSync(tomb, lock);
10322
10355
  } catch {
10323
- fs4.rmSync(tomb, { recursive: true, force: true });
10356
+ fs5.rmSync(tomb, { recursive: true, force: true });
10324
10357
  }
10325
10358
  return false;
10326
10359
  }
@@ -10347,14 +10380,14 @@ function withLedgerLock(file, fn, waitMs = LOCK_WAIT_MS) {
10347
10380
  ledgerLock.release(lock, token);
10348
10381
  }
10349
10382
  }
10350
- var sha2562 = (text) => createHash6("sha256").update(text).digest("hex");
10383
+ var sha2562 = (text) => createHash7("sha256").update(text).digest("hex");
10351
10384
  var chainHash = (prevHash, body) => sha2562(`${prevHash ?? ""}
10352
10385
  ${body}`);
10353
10386
  var TAIL_BYTES = 64 * 1024;
10354
10387
  var lastLine = (fd, size) => {
10355
10388
  for (let span = Math.min(size, TAIL_BYTES);span > 0; span = Math.min(size, span * 2)) {
10356
10389
  const buffer = Buffer.alloc(span);
10357
- fs4.readSync(fd, buffer, 0, span, size - span);
10390
+ fs5.readSync(fd, buffer, 0, span, size - span);
10358
10391
  const end = buffer.lastIndexOf(10);
10359
10392
  if (end < 0) {
10360
10393
  if (span === size)
@@ -10385,13 +10418,13 @@ var lastLine = (fd, size) => {
10385
10418
  };
10386
10419
  function appendLine(file, build, options) {
10387
10420
  const write = () => {
10388
- const fd = fs4.openSync(file, "a+");
10421
+ const fd = fs5.openSync(file, "a+");
10389
10422
  try {
10390
- const size = fs4.fstatSync(fd).size;
10423
+ const size = fs5.fstatSync(fd).size;
10391
10424
  let fence = "";
10392
10425
  if (size > 0) {
10393
10426
  const last = Buffer.alloc(1);
10394
- fs4.readSync(fd, last, 0, 1, size - 1);
10427
+ fs5.readSync(fd, last, 0, 1, size - 1);
10395
10428
  if (last[0] !== 10)
10396
10429
  fence = `
10397
10430
  `;
@@ -10400,17 +10433,17 @@ function appendLine(file, build, options) {
10400
10433
  if (!line.ok)
10401
10434
  return line;
10402
10435
  const bytes = Buffer.from(fence + line.value);
10403
- const written = fs4.writeSync(fd, bytes);
10436
+ const written = fs5.writeSync(fd, bytes);
10404
10437
  if (written !== bytes.length)
10405
10438
  return err("unavailable", `short write to ${file}: ${written} of ${bytes.length} bytes; the row is torn and will be skipped`);
10406
10439
  return { ok: true, value: undefined };
10407
10440
  } finally {
10408
- fs4.closeSync(fd);
10441
+ fs5.closeSync(fd);
10409
10442
  }
10410
10443
  };
10411
10444
  try {
10412
- fs4.mkdirSync(path6.dirname(file), { recursive: true });
10413
- if (!options.forceLock && !onNetworkFs(path6.dirname(file)))
10445
+ fs5.mkdirSync(path7.dirname(file), { recursive: true });
10446
+ if (!options.forceLock && !onNetworkFs(path7.dirname(file)))
10414
10447
  return write();
10415
10448
  const locked = withLedgerLock(file, write);
10416
10449
  return locked ?? err("busy", `ledger lock ${file}.lock is held`, "retry; remove the .lock directory if no workit process is running");
@@ -10482,7 +10515,7 @@ function readLedger(cwd, options = {}) {
10482
10515
  return file;
10483
10516
  let text = "";
10484
10517
  try {
10485
- text = fs4.readFileSync(file.value, "utf8");
10518
+ text = fs5.readFileSync(file.value, "utf8");
10486
10519
  } catch (error) {
10487
10520
  if (error.code === "ENOENT")
10488
10521
  return {
@@ -10676,11 +10709,20 @@ function authorSessions(cwd, rows, branch, range = { base: null, head: null }, s
10676
10709
  sessions.add(session);
10677
10710
  return sessions;
10678
10711
  }
10712
+ var derivesFrom = (derived, bare) => !bare.includes(":") && derived.endsWith(`:${bare}`);
10713
+ var authoredBy = (authors, session) => {
10714
+ if (authors.has(session))
10715
+ return true;
10716
+ for (const author of authors)
10717
+ if (derivesFrom(author, session) || derivesFrom(session, author))
10718
+ return true;
10719
+ return false;
10720
+ };
10679
10721
  var independenceReasons = (row, authors) => {
10680
10722
  const reasons = [];
10681
10723
  if (!row.actor.session)
10682
10724
  reasons.push("no_session");
10683
- else if (authors.has(row.actor.session))
10725
+ else if (authoredBy(authors, row.actor.session))
10684
10726
  reasons.push("author_session");
10685
10727
  if (row.self === true && !reasons.includes("no_session"))
10686
10728
  reasons.push("self");
@@ -10964,7 +11006,7 @@ var productDecision = (task, ledger) => {
10964
11006
  };
10965
11007
  };
10966
11008
  var planRecorded = (task, root) => {
10967
- const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync2(path7.resolve(root, ref.path)));
11009
+ const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync2(path8.resolve(root, ref.path)));
10968
11010
  if (cited)
10969
11011
  return {
10970
11012
  met: true,
@@ -11580,7 +11622,7 @@ var judgeInputSummary = (raw) => {
11580
11622
 
11581
11623
  // packages/workit-core/src/autonomy.ts
11582
11624
  import os3 from "node:os";
11583
- import path8 from "node:path";
11625
+ import path9 from "node:path";
11584
11626
  var accountHome = () => {
11585
11627
  try {
11586
11628
  return os3.userInfo().homedir;
@@ -11589,10 +11631,10 @@ var accountHome = () => {
11589
11631
  }
11590
11632
  };
11591
11633
  var grantsHome = { resolve: accountHome };
11592
- var grantsDir = () => path8.join(grantsHome.resolve(), ".config", "workit");
11634
+ var grantsDir = () => path9.join(grantsHome.resolve(), ".config", "workit");
11593
11635
  var grantsOverride = () => {
11594
- const configured = path8.resolve(resolveConfigDir());
11595
- return configured === path8.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 ${path8.join(grantsDir(), "workspaces.json")}, so the D4 defaults apply`;
11636
+ const configured = path9.resolve(resolveConfigDir());
11637
+ return configured === path9.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 ${path9.join(grantsDir(), "workspaces.json")}, so the D4 defaults apply`;
11596
11638
  };
11597
11639
  var GRANT_KINDS = ["push", "pr", "merge", "release", "rerun"];
11598
11640
  var DEFAULT_GRANTS = Object.freeze({
@@ -11716,9 +11758,9 @@ var suggested = (kind) => kind === "merge" ? "verified" : "true";
11716
11758
  var grantHint = (workspace, kind) => `ask the user to run, in their own terminal: workit grant set ${workspace ?? "<workspace>"} ${kind}=${suggested(kind)}`;
11717
11759
 
11718
11760
  // packages/workit-core/src/core/task-store.ts
11719
- import { createHash as createHash8, randomUUID as randomUUID3 } from "node:crypto";
11720
- import * as fs10 from "node:fs";
11721
- import path13 from "node:path";
11761
+ import { createHash as createHash9, randomUUID as randomUUID3 } from "node:crypto";
11762
+ import * as fs11 from "node:fs";
11763
+ import path14 from "node:path";
11722
11764
 
11723
11765
  // node_modules/@openclaw/fs-safe/dist/errors.js
11724
11766
  var OPERATIONAL_CODES = new Set([
@@ -11769,10 +11811,10 @@ function sameFileIdentity(left, right, platform = process.platform) {
11769
11811
  // node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.js
11770
11812
  import { randomBytes as randomBytes2 } from "node:crypto";
11771
11813
  import fsSync from "node:fs";
11772
- import path9 from "node:path";
11814
+ import path10 from "node:path";
11773
11815
 
11774
11816
  // node_modules/@openclaw/fs-safe/dist/bounded-read.js
11775
- import fs5 from "node:fs";
11817
+ import fs6 from "node:fs";
11776
11818
 
11777
11819
  // node_modules/@openclaw/fs-safe/dist/byte-budget.js
11778
11820
  function normalizeMaxBytes(value, options = {}) {
@@ -11809,7 +11851,7 @@ function readFileDescriptorBoundedSync(fd, maxBytes) {
11809
11851
  let total = 0;
11810
11852
  while (true) {
11811
11853
  const length = nextReadLength(total, maxBytes, scratch.length);
11812
- const bytesRead = fs5.readSync(fd, scratch, 0, length, null);
11854
+ const bytesRead = fs6.readSync(fd, scratch, 0, length, null);
11813
11855
  if (bytesRead === 0) {
11814
11856
  return Buffer.concat(chunks, total);
11815
11857
  }
@@ -11818,9 +11860,9 @@ function readFileDescriptorBoundedSync(fd, maxBytes) {
11818
11860
  }
11819
11861
 
11820
11862
  // node_modules/@openclaw/fs-safe/dist/read-open-flags.js
11821
- import fs6 from "node:fs";
11863
+ import fs7 from "node:fs";
11822
11864
  function resolveReadOpenFlags(options) {
11823
- const constants = options?.constants ?? fs6.constants;
11865
+ const constants = options?.constants ?? fs7.constants;
11824
11866
  const noFollow = process.platform !== "win32" && options?.followSymlinks !== true && typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
11825
11867
  const nonBlocking = process.platform !== "win32" && typeof constants.O_NONBLOCK === "number" ? constants.O_NONBLOCK : 0;
11826
11868
  return constants.O_RDONLY | noFollow | nonBlocking;
@@ -11859,13 +11901,13 @@ ${ownershipToken}
11859
11901
  return { raw, ownershipToken };
11860
11902
  }
11861
11903
  function relativeSidecarLockPath(lockRoot, lockPath) {
11862
- const resolved = path9.resolve(lockPath);
11863
- const lexicalRelative = path9.relative(lockRoot.rootDir, resolved);
11864
- const relative = lexicalRelative !== ".." && !lexicalRelative.startsWith(`..${path9.sep}`) && !path9.isAbsolute(lexicalRelative) ? lexicalRelative : path9.relative(lockRoot.rootReal, resolved);
11865
- if (!relative || relative === ".." || relative.startsWith(`..${path9.sep}`) || path9.isAbsolute(relative)) {
11904
+ const resolved = path10.resolve(lockPath);
11905
+ const lexicalRelative = path10.relative(lockRoot.rootDir, resolved);
11906
+ const relative = lexicalRelative !== ".." && !lexicalRelative.startsWith(`..${path10.sep}`) && !path10.isAbsolute(lexicalRelative) ? lexicalRelative : path10.relative(lockRoot.rootReal, resolved);
11907
+ if (!relative || relative === ".." || relative.startsWith(`..${path10.sep}`) || path10.isAbsolute(relative)) {
11866
11908
  throw new FsSafeError("outside-workspace", "sidecar lock path is outside lockRoot");
11867
11909
  }
11868
- return relative.split(path9.sep).join(path9.posix.sep);
11910
+ return relative.split(path10.sep).join(path10.posix.sep);
11869
11911
  }
11870
11912
  function parseSidecarLockPayload(raw, parser) {
11871
11913
  if (parser) {
@@ -12011,8 +12053,8 @@ function getFsSafeLockConfig() {
12011
12053
  }
12012
12054
 
12013
12055
  // node_modules/@openclaw/fs-safe/dist/file-lock-sync.js
12014
- import fs7 from "node:fs";
12015
- import path10 from "node:path";
12056
+ import fs8 from "node:fs";
12057
+ import path11 from "node:path";
12016
12058
 
12017
12059
  // node_modules/@openclaw/fs-safe/dist/timing.js
12018
12060
  function sleepSync(ms) {
@@ -12042,7 +12084,7 @@ function releaseAllSyncHeldLocks() {
12042
12084
  }
12043
12085
  try {
12044
12086
  if (held.fd !== undefined)
12045
- fs7.closeSync(held.fd);
12087
+ fs8.closeSync(held.fd);
12046
12088
  } catch {}
12047
12089
  try {
12048
12090
  removeSidecarLockIfUnchangedSync(held.lockPath, held.snapshot);
@@ -12077,7 +12119,7 @@ function releaseSyncHeldLock(held) {
12077
12119
  if (held.fd !== undefined) {
12078
12120
  const fd = held.fd;
12079
12121
  held.fd = undefined;
12080
- fs7.closeSync(fd);
12122
+ fs8.closeSync(fd);
12081
12123
  }
12082
12124
  removeSidecarLockIfUnchangedSync(held.lockPath, held.snapshot);
12083
12125
  heldLocks.delete(held.normalizedTargetPath);
@@ -12100,29 +12142,29 @@ function createSyncHeldLockHandle(held) {
12100
12142
  };
12101
12143
  }
12102
12144
  function canonicalLockParentSync(parent) {
12103
- return process.platform === "win32" ? fs7.realpathSync.native(parent) : fs7.realpathSync(parent);
12145
+ return process.platform === "win32" ? fs8.realpathSync.native(parent) : fs8.realpathSync(parent);
12104
12146
  }
12105
12147
  function normalizeTargetPath(targetPath) {
12106
- const resolved = path10.resolve(targetPath);
12107
- fs7.mkdirSync(path10.dirname(resolved), { recursive: true });
12148
+ const resolved = path11.resolve(targetPath);
12149
+ fs8.mkdirSync(path11.dirname(resolved), { recursive: true });
12108
12150
  try {
12109
- return path10.join(canonicalLockParentSync(path10.dirname(resolved)), path10.basename(resolved));
12151
+ return path11.join(canonicalLockParentSync(path11.dirname(resolved)), path11.basename(resolved));
12110
12152
  } catch {
12111
12153
  return resolved;
12112
12154
  }
12113
12155
  }
12114
12156
  function boundedLockPath(lockPath, lockRoot) {
12115
- const resolved = path10.resolve(lockPath);
12157
+ const resolved = path11.resolve(lockPath);
12116
12158
  if (!lockRoot)
12117
12159
  return resolved;
12118
12160
  relativeSidecarLockPath(lockRoot, resolved);
12119
- const parent = path10.dirname(resolved);
12161
+ const parent = path11.dirname(resolved);
12120
12162
  const parentReal = canonicalLockParentSync(parent);
12121
- const parentRelative = path10.relative(lockRoot.rootReal, parentReal);
12122
- if (parentRelative === ".." || parentRelative.startsWith(`..${path10.sep}`) || path10.isAbsolute(parentRelative)) {
12163
+ const parentRelative = path11.relative(lockRoot.rootReal, parentReal);
12164
+ if (parentRelative === ".." || parentRelative.startsWith(`..${path11.sep}`) || path11.isAbsolute(parentRelative)) {
12123
12165
  throw new FsSafeError("outside-workspace", "sidecar lock parent is outside lockRoot");
12124
12166
  }
12125
- return path10.join(parentReal, path10.basename(resolved));
12167
+ return path11.join(parentReal, path11.basename(resolved));
12126
12168
  }
12127
12169
  function defaultShouldReclaim(snapshot, staleMs, nowMs) {
12128
12170
  const createdAtMs = sidecarLockPayloadCreatedAtMs(snapshot.payload);
@@ -12132,7 +12174,7 @@ function defaultShouldReclaim(snapshot, staleMs, nowMs) {
12132
12174
  }
12133
12175
  function reclaimGuardExists(reclaimGuardPath) {
12134
12176
  try {
12135
- fs7.lstatSync(reclaimGuardPath);
12177
+ fs8.lstatSync(reclaimGuardPath);
12136
12178
  return true;
12137
12179
  } catch (error) {
12138
12180
  if (error.code === "ENOENT")
@@ -12196,19 +12238,19 @@ function acquireFileLockSync(targetPath, options) {
12196
12238
  const { raw, ownershipToken } = serializeSidecarLockPayload(payload);
12197
12239
  let lockFileCreateDenied = false;
12198
12240
  try {
12199
- const noFollow = process.platform !== "win32" && typeof fs7.constants.O_NOFOLLOW === "number" ? fs7.constants.O_NOFOLLOW : 0;
12241
+ const noFollow = process.platform !== "win32" && typeof fs8.constants.O_NOFOLLOW === "number" ? fs8.constants.O_NOFOLLOW : 0;
12200
12242
  try {
12201
- fd = fs7.openSync(lockPath, fs7.constants.O_WRONLY | fs7.constants.O_CREAT | fs7.constants.O_EXCL | noFollow, 384);
12243
+ fd = fs8.openSync(lockPath, fs8.constants.O_WRONLY | fs8.constants.O_CREAT | fs8.constants.O_EXCL | noFollow, 384);
12202
12244
  } catch (error) {
12203
12245
  lockFileCreateDenied = isTransientLockFileDenial(error, lockPath);
12204
12246
  throw error;
12205
12247
  }
12206
- fs7.writeFileSync(fd, raw, "utf8");
12207
- fs7.fsyncSync(fd);
12248
+ fs8.writeFileSync(fd, raw, "utf8");
12249
+ fs8.fsyncSync(fd);
12208
12250
  const snapshot = {
12209
12251
  raw,
12210
12252
  payload,
12211
- stat: fs7.fstatSync(fd),
12253
+ stat: fs8.fstatSync(fd),
12212
12254
  ownershipToken
12213
12255
  };
12214
12256
  const createdHeld = {
@@ -12243,8 +12285,8 @@ function acquireFileLockSync(targetPath, options) {
12243
12285
  return returnedHandle;
12244
12286
  } catch (error) {
12245
12287
  if (fd !== undefined) {
12246
- const failed = { payload: null, stat: fs7.fstatSync(fd) };
12247
- fs7.closeSync(fd);
12288
+ const failed = { payload: null, stat: fs8.fstatSync(fd) };
12289
+ fs8.closeSync(fd);
12248
12290
  fd = undefined;
12249
12291
  removeSidecarLockIfUnchangedSync(lockPath, failed);
12250
12292
  }
@@ -12293,7 +12335,7 @@ function acquireFileLockSync(targetPath, options) {
12293
12335
  })) {
12294
12336
  let ownsReclaimGuard = false;
12295
12337
  try {
12296
- fs7.mkdirSync(reclaimGuardPath);
12338
+ fs8.mkdirSync(reclaimGuardPath);
12297
12339
  ownsReclaimGuard = true;
12298
12340
  if (removeSidecarLockIfUnchangedSync(lockPath, snapshot))
12299
12341
  continue;
@@ -12306,7 +12348,7 @@ function acquireFileLockSync(targetPath, options) {
12306
12348
  } finally {
12307
12349
  if (ownsReclaimGuard) {
12308
12350
  try {
12309
- fs7.rmdirSync(reclaimGuardPath);
12351
+ fs8.rmdirSync(reclaimGuardPath);
12310
12352
  } catch {}
12311
12353
  }
12312
12354
  }
@@ -12323,13 +12365,13 @@ function acquireFileLockSync(targetPath, options) {
12323
12365
  }
12324
12366
  // packages/workit-core/src/core/package-root.ts
12325
12367
  import { existsSync as existsSync3 } from "node:fs";
12326
- import path11 from "node:path";
12368
+ import path12 from "node:path";
12327
12369
  import { fileURLToPath } from "node:url";
12328
12370
  var packageRoot = () => {
12329
- let dir = path11.dirname(fileURLToPath(import.meta.url));
12371
+ let dir = path12.dirname(fileURLToPath(import.meta.url));
12330
12372
  while (true) {
12331
- const parent = path11.dirname(dir);
12332
- if (existsSync3(path11.join(dir, "package.json")) || parent === dir)
12373
+ const parent = path12.dirname(dir);
12374
+ if (existsSync3(path12.join(dir, "package.json")) || parent === dir)
12333
12375
  return dir;
12334
12376
  dir = parent;
12335
12377
  }
@@ -12337,7 +12379,7 @@ var packageRoot = () => {
12337
12379
 
12338
12380
  // packages/workit-core/src/core/store-lock.ts
12339
12381
  import { spawnSync as spawnSync8 } from "node:child_process";
12340
- import fs8 from "node:fs";
12382
+ import fs9 from "node:fs";
12341
12383
  import { hostname } from "node:os";
12342
12384
  var metadataLockSchema = object({
12343
12385
  pid: number2().int().nonnegative().safe(),
@@ -12379,7 +12421,7 @@ var parseProcStatStart = (stat) => {
12379
12421
  var processStartOf = (pid) => {
12380
12422
  if (process.platform === "linux") {
12381
12423
  try {
12382
- return parseProcStatStart(fs8.readFileSync(`/proc/${pid}/stat`, "utf8"));
12424
+ return parseProcStatStart(fs9.readFileSync(`/proc/${pid}/stat`, "utf8"));
12383
12425
  } catch {
12384
12426
  return null;
12385
12427
  }
@@ -12400,7 +12442,7 @@ var processStartOf = (pid) => {
12400
12442
  };
12401
12443
  var readTrimmed = (file) => {
12402
12444
  try {
12403
- return fs8.readFileSync(file, "utf8").trim() || null;
12445
+ return fs9.readFileSync(file, "utf8").trim() || null;
12404
12446
  } catch {
12405
12447
  return null;
12406
12448
  }
@@ -12411,7 +12453,7 @@ var localLockHost = () => {
12411
12453
  return cachedLockHost;
12412
12454
  let pidns = null;
12413
12455
  try {
12414
- pidns = /\[(\d+)\]/.exec(fs8.readlinkSync("/proc/self/ns/pid"))?.[1] ?? null;
12456
+ pidns = /\[(\d+)\]/.exec(fs9.readlinkSync("/proc/self/ns/pid"))?.[1] ?? null;
12415
12457
  } catch {}
12416
12458
  const boot = readTrimmed("/proc/sys/kernel/random/boot_id");
12417
12459
  cachedLockHost = pidns || boot ? `${hostname()}#${pidns ?? "?"}:${boot ?? "?"}` : hostname();
@@ -12457,7 +12499,7 @@ var classifyLockOwner = (payload, ageMs, localHost = localLockHost(), options =
12457
12499
  };
12458
12500
  var ageOf = (file, nowMs) => {
12459
12501
  try {
12460
- return nowMs - fs8.lstatSync(file).mtimeMs;
12502
+ return nowMs - fs9.lstatSync(file).mtimeMs;
12461
12503
  } catch {
12462
12504
  return null;
12463
12505
  }
@@ -12468,7 +12510,7 @@ var clearAbandonedReclaimGuard = (lockPath, nowMs = Date.now()) => {
12468
12510
  if (age === null || age <= RECLAIM_GUARD_TTL_MS)
12469
12511
  return false;
12470
12512
  try {
12471
- fs8.rmdirSync(guard);
12513
+ fs9.rmdirSync(guard);
12472
12514
  return true;
12473
12515
  } catch {
12474
12516
  return false;
@@ -12477,8 +12519,8 @@ var clearAbandonedReclaimGuard = (lockPath, nowMs = Date.now()) => {
12477
12519
 
12478
12520
  // packages/workit-core/src/store/event-log.ts
12479
12521
  import { randomUUID as randomUUID2 } from "node:crypto";
12480
- import fs9 from "node:fs";
12481
- import path12 from "node:path";
12522
+ import fs10 from "node:fs";
12523
+ import path13 from "node:path";
12482
12524
  var EVENT_VERSION = 1;
12483
12525
 
12484
12526
  class LogDamage extends Error {
@@ -12507,7 +12549,7 @@ var parseEvent = (line, file, offset) => {
12507
12549
  function readLog(file, from = 0, expectSeq = null) {
12508
12550
  let fd;
12509
12551
  try {
12510
- fd = fs9.openSync(file, "r");
12552
+ fd = fs10.openSync(file, "r");
12511
12553
  } catch (error) {
12512
12554
  if (error.code === "ENOENT")
12513
12555
  return null;
@@ -12516,13 +12558,13 @@ function readLog(file, from = 0, expectSeq = null) {
12516
12558
  let bytes;
12517
12559
  let size;
12518
12560
  try {
12519
- size = fs9.fstatSync(fd).size;
12561
+ size = fs10.fstatSync(fd).size;
12520
12562
  if (from > size)
12521
12563
  throw new LogDamage(`${file}: shorter than its snapshot`);
12522
12564
  bytes = Buffer.alloc(size - from);
12523
12565
  let read = 0;
12524
12566
  while (read < bytes.length) {
12525
- const got = fs9.readSync(fd, bytes, read, bytes.length - read, from + read);
12567
+ const got = fs10.readSync(fd, bytes, read, bytes.length - read, from + read);
12526
12568
  if (got === 0)
12527
12569
  break;
12528
12570
  read += got;
@@ -12530,7 +12572,7 @@ function readLog(file, from = 0, expectSeq = null) {
12530
12572
  bytes = bytes.subarray(0, read);
12531
12573
  size = from + read;
12532
12574
  } finally {
12533
- fs9.closeSync(fd);
12575
+ fs10.closeSync(fd);
12534
12576
  }
12535
12577
  const events = [];
12536
12578
  let start = 0;
@@ -12555,11 +12597,11 @@ function readLog(file, from = 0, expectSeq = null) {
12555
12597
  }
12556
12598
  var fsyncDirectory = (dir) => {
12557
12599
  try {
12558
- const fd = fs9.openSync(dir, "r");
12600
+ const fd = fs10.openSync(dir, "r");
12559
12601
  try {
12560
- fs9.fsyncSync(fd);
12602
+ fs10.fsyncSync(fd);
12561
12603
  } finally {
12562
- fs9.closeSync(fd);
12604
+ fs10.closeSync(fd);
12563
12605
  }
12564
12606
  } catch (error) {
12565
12607
  if (process.platform !== "win32")
@@ -12569,46 +12611,46 @@ var fsyncDirectory = (dir) => {
12569
12611
  function appendEvent(file, event, validEnd) {
12570
12612
  const line = Buffer.from(`${JSON.stringify(event)}
12571
12613
  `, "utf8");
12572
- const created = !fs9.existsSync(file);
12573
- if (!created && fs9.statSync(file).size !== validEnd) {
12574
- const cut = fs9.openSync(file, "r+");
12614
+ const created = !fs10.existsSync(file);
12615
+ if (!created && fs10.statSync(file).size !== validEnd) {
12616
+ const cut = fs10.openSync(file, "r+");
12575
12617
  try {
12576
- fs9.ftruncateSync(cut, validEnd);
12577
- fs9.fsyncSync(cut);
12618
+ fs10.ftruncateSync(cut, validEnd);
12619
+ fs10.fsyncSync(cut);
12578
12620
  } finally {
12579
- fs9.closeSync(cut);
12621
+ fs10.closeSync(cut);
12580
12622
  }
12581
12623
  }
12582
- const fd = fs9.openSync(file, "a", 384);
12624
+ const fd = fs10.openSync(file, "a", 384);
12583
12625
  try {
12584
12626
  let written = 0;
12585
12627
  while (written < line.length)
12586
- written += fs9.writeSync(fd, line, written, line.length - written);
12587
- fs9.fsyncSync(fd);
12628
+ written += fs10.writeSync(fd, line, written, line.length - written);
12629
+ fs10.fsyncSync(fd);
12588
12630
  } finally {
12589
- fs9.closeSync(fd);
12631
+ fs10.closeSync(fd);
12590
12632
  }
12591
12633
  if (created)
12592
- fsyncDirectory(path12.dirname(file));
12634
+ fsyncDirectory(path13.dirname(file));
12593
12635
  return validEnd;
12594
12636
  }
12595
12637
  function replaceFile(file, bytes, durable) {
12596
12638
  const temporary = `${file}.${process.pid}.${randomUUID2()}.tmp`;
12597
12639
  try {
12598
- const fd = fs9.openSync(temporary, "wx", 384);
12640
+ const fd = fs10.openSync(temporary, "wx", 384);
12599
12641
  try {
12600
- fs9.writeSync(fd, bytes);
12642
+ fs10.writeSync(fd, bytes);
12601
12643
  if (durable)
12602
- fs9.fsyncSync(fd);
12644
+ fs10.fsyncSync(fd);
12603
12645
  } finally {
12604
- fs9.closeSync(fd);
12646
+ fs10.closeSync(fd);
12605
12647
  }
12606
12648
  renameWithRetry(temporary, file);
12607
12649
  if (durable)
12608
- fsyncDirectory(path12.dirname(file));
12650
+ fsyncDirectory(path13.dirname(file));
12609
12651
  } catch (error) {
12610
12652
  try {
12611
- fs9.unlinkSync(temporary);
12653
+ fs10.unlinkSync(temporary);
12612
12654
  } catch {}
12613
12655
  throw error;
12614
12656
  }
@@ -12633,7 +12675,7 @@ var retryTransient = (run) => {
12633
12675
  }
12634
12676
  }
12635
12677
  };
12636
- var renameWithRetry = (from, to) => retryTransient(() => fs9.renameSync(from, to));
12678
+ var renameWithRetry = (from, to) => retryTransient(() => fs10.renameSync(from, to));
12637
12679
 
12638
12680
  // packages/workit-core/src/store/patch.ts
12639
12681
  var isPlainObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -12746,7 +12788,7 @@ var isPatch = (value) => Array.isArray(value) && value.every((op) => {
12746
12788
  });
12747
12789
 
12748
12790
  // packages/workit-core/src/store/reduce.ts
12749
- import { createHash as createHash7 } from "node:crypto";
12791
+ import { createHash as createHash8 } from "node:crypto";
12750
12792
  var OPENING_TYPES = new Set([
12751
12793
  "task.opened",
12752
12794
  "task.imported",
@@ -12775,7 +12817,7 @@ var isObject5 = (value) => typeof value === "object" && value !== null && !Array
12775
12817
  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");
12776
12818
  var BLOB_REF = "$blob";
12777
12819
  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;
12778
- var blobDigest = (value) => createHash7("sha256").update(JSON.stringify(value)).digest("hex");
12820
+ var blobDigest = (value) => createHash8("sha256").update(JSON.stringify(value)).digest("hex");
12779
12821
  var toBlob = (value, blobs) => {
12780
12822
  if (!isObject5(value))
12781
12823
  return value;
@@ -12930,7 +12972,7 @@ var indexEntry = (task, key, legacy, file) => {
12930
12972
  };
12931
12973
  var fileSignature = (file) => {
12932
12974
  try {
12933
- const stat = fs10.statSync(file, { bigint: true });
12975
+ const stat = fs11.statSync(file, { bigint: true });
12934
12976
  return `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}`;
12935
12977
  } catch {
12936
12978
  return null;
@@ -12948,7 +12990,7 @@ var cachedRuntimeVersion = null;
12948
12990
  var runtimeVersion = () => {
12949
12991
  if (cachedRuntimeVersion === null) {
12950
12992
  try {
12951
- const pkg = JSON.parse(fs10.readFileSync(path13.join(packageRoot(), "package.json"), "utf8"));
12993
+ const pkg = JSON.parse(fs11.readFileSync(path14.join(packageRoot(), "package.json"), "utf8"));
12952
12994
  cachedRuntimeVersion = typeof pkg.version === "string" && pkg.version ? pkg.version : "0.0.0";
12953
12995
  } catch {
12954
12996
  cachedRuntimeVersion = "0.0.0";
@@ -12974,14 +13016,14 @@ var isNewerVersion = (candidate, current) => {
12974
13016
  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);
12975
13017
  var readText = (file) => {
12976
13018
  try {
12977
- return fs10.readFileSync(file, "utf8");
13019
+ return fs11.readFileSync(file, "utf8");
12978
13020
  } catch {
12979
13021
  return "";
12980
13022
  }
12981
13023
  };
12982
13024
  var REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
12983
13025
  var branchStart = (location, branch, aliases) => {
12984
- const first = readText(path13.join(path13.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
13026
+ const first = readText(path14.join(path14.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
12985
13027
  `, 1)[0];
12986
13028
  const created = REFLOG_LINE.exec(first);
12987
13029
  const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
@@ -12991,7 +13033,7 @@ var branchStart = (location, branch, aliases) => {
12991
13033
  return start;
12992
13034
  if (!location.git)
12993
13035
  return null;
12994
- for (const line of readText(path13.join(location.git.gitDir, "logs", "HEAD")).split(`
13036
+ for (const line of readText(path14.join(location.git.gitDir, "logs", "HEAD")).split(`
12995
13037
  `)) {
12996
13038
  const entry = REFLOG_LINE.exec(line);
12997
13039
  const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
@@ -13001,23 +13043,23 @@ var branchStart = (location, branch, aliases) => {
13001
13043
  }
13002
13044
  return null;
13003
13045
  };
13004
- var refExists = (common, ref) => fs10.existsSync(path13.join(common, ref)) || readText(path13.join(common, "packed-refs")).includes(` ${ref}
13046
+ var refExists = (common, ref) => fs11.existsSync(path14.join(common, ref)) || readText(path14.join(common, "packed-refs")).includes(` ${ref}
13005
13047
  `);
13006
13048
  var origins = new Map;
13007
13049
  var sameDirectoryIdentity = (left, right) => {
13008
- if (!path13.isAbsolute(left) || !path13.isAbsolute(right))
13050
+ if (!path14.isAbsolute(left) || !path14.isAbsolute(right))
13009
13051
  return false;
13010
- const normalizedLeft = path13.resolve(left);
13011
- const normalizedRight = path13.resolve(right);
13052
+ const normalizedLeft = path14.resolve(left);
13053
+ const normalizedRight = path14.resolve(right);
13012
13054
  try {
13013
- const a = fs10.statSync(normalizedLeft, { bigint: true });
13014
- const b = fs10.statSync(normalizedRight, { bigint: true });
13055
+ const a = fs11.statSync(normalizedLeft, { bigint: true });
13056
+ const b = fs11.statSync(normalizedRight, { bigint: true });
13015
13057
  if (!a.isDirectory() || !b.isDirectory())
13016
13058
  return false;
13017
13059
  if (process.platform === "win32" ? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase() : normalizedLeft === normalizedRight)
13018
13060
  return true;
13019
- const canonicalLeft = fs10.realpathSync(normalizedLeft);
13020
- const canonicalRight = fs10.realpathSync(normalizedRight);
13061
+ const canonicalLeft = fs11.realpathSync(normalizedLeft);
13062
+ const canonicalRight = fs11.realpathSync(normalizedRight);
13021
13063
  if (process.platform === "win32" ? canonicalLeft.toLowerCase() === canonicalRight.toLowerCase() : canonicalLeft === canonicalRight)
13022
13064
  return true;
13023
13065
  return a.dev === b.dev && a.ino !== 0n && a.ino === b.ino;
@@ -13054,8 +13096,8 @@ class TaskStore {
13054
13096
  migrationChecked = false;
13055
13097
  compactDue = new Set;
13056
13098
  constructor(root, options = {}) {
13057
- const resolved = path13.resolve(root);
13058
- this.origin = fs10.existsSync(resolved) ? fs10.realpathSync(resolved) : resolved;
13099
+ const resolved = path14.resolve(root);
13100
+ this.origin = fs11.existsSync(resolved) ? fs11.realpathSync(resolved) : resolved;
13059
13101
  this.located = resolveStore(this.origin);
13060
13102
  this.root = checkoutRootOf(this.origin, this.located);
13061
13103
  this.lockTimeoutMs = options.lockTimeoutMs ?? defaultLockTimeout();
@@ -13063,7 +13105,7 @@ class TaskStore {
13063
13105
  this.migrateOnRead = options.migrateOnRead;
13064
13106
  }
13065
13107
  location() {
13066
- if (this.located !== undefined && !(this.located instanceof Error) && !this.located.shared && fs10.existsSync(path13.join(this.root, ".git"))) {
13108
+ if (this.located !== undefined && !(this.located instanceof Error) && !this.located.shared && fs11.existsSync(path14.join(this.root, ".git"))) {
13067
13109
  this.located = undefined;
13068
13110
  this.migrationChecked = false;
13069
13111
  }
@@ -13127,7 +13169,7 @@ class TaskStore {
13127
13169
  const tasksDir = this.paths().tasks;
13128
13170
  let names;
13129
13171
  try {
13130
- names = fs10.existsSync(tasksDir) ? fs10.readdirSync(tasksDir).filter((name) => validId(name)) : [];
13172
+ names = fs11.existsSync(tasksDir) ? fs11.readdirSync(tasksDir).filter((name) => validId(name)) : [];
13131
13173
  } catch (error) {
13132
13174
  return failure2("storage_error", `unable to list tasks: ${String(error)}`, {
13133
13175
  path: tasksDir
@@ -13168,7 +13210,7 @@ class TaskStore {
13168
13210
  const file = this.paths().workspace;
13169
13211
  let bytes;
13170
13212
  try {
13171
- bytes = retryTransient(() => fs10.readFileSync(file, "utf8"));
13213
+ bytes = retryTransient(() => fs11.readFileSync(file, "utf8"));
13172
13214
  } catch (error) {
13173
13215
  if (error.code === "ENOENT")
13174
13216
  return success(null, null, null);
@@ -13219,7 +13261,7 @@ class TaskStore {
13219
13261
  const moved = this.bindLocked(again.data.id, key, input.now);
13220
13262
  return moved.ok ? success(moved.data.revision, null, { task: moved.data, created: false, key }) : moved;
13221
13263
  }
13222
- const label = key.kind === "branch" ? `branch ${key.branch}` : key.kind === "detached" ? "a detached HEAD" : path13.basename(this.root) || this.root;
13264
+ const label = key.kind === "branch" ? `branch ${key.branch}` : key.kind === "detached" ? "a detached HEAD" : path14.basename(this.root) || this.root;
13223
13265
  const intent = {
13224
13266
  objective: input.objective?.trim() || `Work on ${label}`,
13225
13267
  scope: { description: `the checkout (${label})`, paths: ["."], exclusions: [] },
@@ -13279,14 +13321,14 @@ class TaskStore {
13279
13321
  const branch = key.ok ? key.data.branch : null;
13280
13322
  if (!branch || !location.ok)
13281
13323
  return success(null, null, null);
13282
- const common = path13.dirname(location.data.dir);
13283
- const heads = path13.join(common, "logs", "refs", "heads");
13284
- const headLog = location.data.git ? path13.join(location.data.git.gitDir, "logs", "HEAD") : "";
13324
+ const common = path14.dirname(location.data.dir);
13325
+ const heads = path14.join(common, "logs", "refs", "heads");
13326
+ const headLog = location.data.git ? path14.join(location.data.git.gitDir, "logs", "HEAD") : "";
13285
13327
  const signatures = [
13286
- path13.join(heads, branch),
13328
+ path14.join(heads, branch),
13287
13329
  headLog,
13288
13330
  heads,
13289
- path13.join(common, "packed-refs")
13331
+ path14.join(common, "packed-refs")
13290
13332
  ].map((file) => fileSignature(file) ?? "-");
13291
13333
  const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
13292
13334
  let resolved = origins.get(slot);
@@ -13298,7 +13340,7 @@ class TaskStore {
13298
13340
  aliases.push(rename.from);
13299
13341
  const start = branchStart(location.data, branch, aliases);
13300
13342
  const slash = start?.indexOf("/") ?? -1;
13301
- const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(path13.join(common, "config")).includes(`[remote "${start.slice(0, slash)}"]`));
13343
+ const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(path14.join(common, "config")).includes(`[remote "${start.slice(0, slash)}"]`));
13302
13344
  const name = start && (remote ? start.slice(slash + 1) : start);
13303
13345
  resolved = {
13304
13346
  signature: signatures.join("|"),
@@ -13536,13 +13578,13 @@ class TaskStore {
13536
13578
  if (!ready.ok)
13537
13579
  return ready;
13538
13580
  const dirs = this.paths();
13539
- const recovery = path13.join(this.root, ".workit", "recovery");
13540
- if (fs10.existsSync(recovery)) {
13581
+ const recovery = path14.join(this.root, ".workit", "recovery");
13582
+ if (fs11.existsSync(recovery)) {
13541
13583
  let files = 0;
13542
13584
  let bytes = 0;
13543
13585
  try {
13544
- for (const name of fs10.readdirSync(recovery)) {
13545
- const stat = fs10.lstatSync(path13.join(recovery, name));
13586
+ for (const name of fs11.readdirSync(recovery)) {
13587
+ const stat = fs11.lstatSync(path14.join(recovery, name));
13546
13588
  if (!stat.isFile())
13547
13589
  continue;
13548
13590
  files += 1;
@@ -13551,17 +13593,17 @@ class TaskStore {
13551
13593
  } catch {}
13552
13594
  const remove = options.pruneRecovery === true && !dryRun;
13553
13595
  if (remove)
13554
- fs10.rmSync(recovery, { recursive: true, force: true });
13596
+ fs11.rmSync(recovery, { recursive: true, force: true });
13555
13597
  report.legacyRecovery = { path: recovery, files, bytes, removed: remove };
13556
13598
  }
13557
- if (!fs10.existsSync(dirs.tasks))
13599
+ if (!fs11.existsSync(dirs.tasks))
13558
13600
  return success(null, null, report);
13559
- const names = fs10.readdirSync(dirs.tasks).filter((name) => validId(name));
13601
+ const names = fs11.readdirSync(dirs.tasks).filter((name) => validId(name));
13560
13602
  for (const name of names) {
13561
13603
  const file = this.eventsPath(name);
13562
13604
  let size = 0;
13563
13605
  try {
13564
- size = fs10.statSync(file).size;
13606
+ size = fs11.statSync(file).size;
13565
13607
  } catch {
13566
13608
  continue;
13567
13609
  }
@@ -13589,16 +13631,16 @@ class TaskStore {
13589
13631
  const references = new Set;
13590
13632
  for (const name of names)
13591
13633
  try {
13592
- for (const match of fs10.readFileSync(this.eventsPath(name), "utf8").matchAll(/"\$blob":"([0-9a-f]{64})"/g))
13634
+ for (const match of fs11.readFileSync(this.eventsPath(name), "utf8").matchAll(/"\$blob":"([0-9a-f]{64})"/g))
13593
13635
  references.add(match[1]);
13594
13636
  } catch {}
13595
- if (fs10.existsSync(dirs.blobs))
13596
- for (const name of fs10.readdirSync(dirs.blobs)) {
13637
+ if (fs11.existsSync(dirs.blobs))
13638
+ for (const name of fs11.readdirSync(dirs.blobs)) {
13597
13639
  const digest = name.replace(/\.json$/, "");
13598
- const file = path13.join(dirs.blobs, name);
13640
+ const file = path14.join(dirs.blobs, name);
13599
13641
  let stat;
13600
13642
  try {
13601
- stat = fs10.lstatSync(file);
13643
+ stat = fs11.lstatSync(file);
13602
13644
  } catch {
13603
13645
  continue;
13604
13646
  }
@@ -13609,11 +13651,11 @@ class TaskStore {
13609
13651
  report.blobs.removed += 1;
13610
13652
  report.blobs.removedBytes += stat.size;
13611
13653
  if (!dryRun)
13612
- fs10.rmSync(file, { force: true });
13654
+ fs11.rmSync(file, { force: true });
13613
13655
  }
13614
13656
  return success(null, null, null);
13615
13657
  };
13616
- const swept = dryRun ? sweep() : this.withLock(path13.join(dirs.dir, "gc.lock"), sweep);
13658
+ const swept = dryRun ? sweep() : this.withLock(path14.join(dirs.dir, "gc.lock"), sweep);
13617
13659
  if (!swept.ok)
13618
13660
  return swept;
13619
13661
  const temporaryDirs = [
@@ -13621,17 +13663,17 @@ class TaskStore {
13621
13663
  dirs.tasks,
13622
13664
  dirs.blobs,
13623
13665
  dirs.checkout,
13624
- ...names.map((name) => path13.join(dirs.tasks, name))
13666
+ ...names.map((name) => path14.join(dirs.tasks, name))
13625
13667
  ];
13626
13668
  for (const directory of temporaryDirs) {
13627
- if (!fs10.existsSync(directory))
13669
+ if (!fs11.existsSync(directory))
13628
13670
  continue;
13629
- for (const name of fs10.readdirSync(directory)) {
13671
+ for (const name of fs11.readdirSync(directory)) {
13630
13672
  if (!name.endsWith(".tmp") && !name.endsWith(".probe"))
13631
13673
  continue;
13632
- const file = path13.join(directory, name);
13674
+ const file = path14.join(directory, name);
13633
13675
  try {
13634
- const stat = fs10.lstatSync(file);
13676
+ const stat = fs11.lstatSync(file);
13635
13677
  if (!stat.isFile() || nowMs - stat.mtimeMs <= STALE_TEMPORARY_MS)
13636
13678
  continue;
13637
13679
  } catch {
@@ -13639,37 +13681,37 @@ class TaskStore {
13639
13681
  }
13640
13682
  report.temporary.removed += 1;
13641
13683
  if (!dryRun)
13642
- fs10.rmSync(file, { force: true });
13684
+ fs11.rmSync(file, { force: true });
13643
13685
  }
13644
13686
  }
13645
13687
  return success(null, null, report);
13646
13688
  }
13647
13689
  paths() {
13648
13690
  const location = this.location();
13649
- const dir = location.ok ? location.data.dir : path13.join(this.root, ".workit");
13650
- const checkout = path13.join(dir, "checkouts", checkoutSlug(this.root));
13691
+ const dir = location.ok ? location.data.dir : path14.join(this.root, ".workit");
13692
+ const checkout = path14.join(dir, "checkouts", checkoutSlug(this.root));
13651
13693
  return {
13652
13694
  dir,
13653
13695
  shared: location.ok ? location.data.shared : false,
13654
- marker: path13.join(dir, "store.json"),
13696
+ marker: path14.join(dir, "store.json"),
13655
13697
  checkout,
13656
- workspace: path13.join(checkout, "workspace.json"),
13657
- checkoutLock: path13.join(checkout, "metadata.lock"),
13658
- tasks: path13.join(dir, "tasks"),
13659
- index: path13.join(dir, "task-index.json"),
13660
- blobs: path13.join(dir, "blobs", "candidates"),
13661
- legacy: path13.join(dir, "legacy", checkoutSlug(this.root), "v2"),
13662
- v2: path13.join(this.root, ".workit")
13698
+ workspace: path14.join(checkout, "workspace.json"),
13699
+ checkoutLock: path14.join(checkout, "metadata.lock"),
13700
+ tasks: path14.join(dir, "tasks"),
13701
+ index: path14.join(dir, "task-index.json"),
13702
+ blobs: path14.join(dir, "blobs", "candidates"),
13703
+ legacy: path14.join(dir, "legacy", checkoutSlug(this.root), "v2"),
13704
+ v2: path14.join(this.root, ".workit")
13663
13705
  };
13664
13706
  }
13665
13707
  eventsPath(taskId) {
13666
- return path13.join(this.paths().tasks, taskId, "events.jsonl");
13708
+ return path14.join(this.paths().tasks, taskId, "events.jsonl");
13667
13709
  }
13668
13710
  snapshotPath(taskId) {
13669
- return path13.join(this.paths().tasks, taskId, "snapshot.json");
13711
+ return path14.join(this.paths().tasks, taskId, "snapshot.json");
13670
13712
  }
13671
13713
  taskLockPath(taskId) {
13672
- return path13.join(this.paths().tasks, taskId, "lock");
13714
+ return path14.join(this.paths().tasks, taskId, "lock");
13673
13715
  }
13674
13716
  ready(write = false) {
13675
13717
  const location = this.location();
@@ -13679,7 +13721,7 @@ class TaskStore {
13679
13721
  return success(null, null, null);
13680
13722
  const dirs = this.paths();
13681
13723
  try {
13682
- const marker = JSON.parse(fs10.readFileSync(dirs.marker, "utf8"));
13724
+ const marker = JSON.parse(fs11.readFileSync(dirs.marker, "utf8"));
13683
13725
  if (typeof marker.version === "number" && marker.version > STORE_FORMAT)
13684
13726
  return failure2("recovery_required", `the workit store at ${dirs.dir} has format ${marker.version}; upgrade Workit to use it`, { path: dirs.marker });
13685
13727
  } catch {}
@@ -13708,21 +13750,21 @@ class TaskStore {
13708
13750
  return {
13709
13751
  read: (digest) => {
13710
13752
  try {
13711
- return JSON.parse(fs10.readFileSync(path13.join(dir, `${digest}.json`), "utf8"));
13753
+ return JSON.parse(fs11.readFileSync(path14.join(dir, `${digest}.json`), "utf8"));
13712
13754
  } catch (error) {
13713
13755
  throw new LogDamage(`stored candidate ${digest} is missing or unreadable: ${String(error)}`);
13714
13756
  }
13715
13757
  },
13716
13758
  write: (digest, value) => {
13717
- const file = path13.join(dir, `${digest}.json`);
13718
- if (fs10.existsSync(file)) {
13759
+ const file = path14.join(dir, `${digest}.json`);
13760
+ if (fs11.existsSync(file)) {
13719
13761
  const stamp = new Date;
13720
13762
  try {
13721
- fs10.utimesSync(file, stamp, stamp);
13763
+ fs11.utimesSync(file, stamp, stamp);
13722
13764
  return;
13723
13765
  } catch {}
13724
13766
  }
13725
- fs10.mkdirSync(dir, { recursive: true });
13767
+ fs11.mkdirSync(dir, { recursive: true });
13726
13768
  replaceFile(file, JSON.stringify(value), true);
13727
13769
  }
13728
13770
  };
@@ -13804,7 +13846,7 @@ class TaskStore {
13804
13846
  }
13805
13847
  readSnapshot(taskId) {
13806
13848
  try {
13807
- const value = JSON.parse(fs10.readFileSync(this.snapshotPath(taskId), "utf8"));
13849
+ const value = JSON.parse(fs11.readFileSync(this.snapshotPath(taskId), "utf8"));
13808
13850
  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))
13809
13851
  return null;
13810
13852
  return value;
@@ -13906,8 +13948,8 @@ class TaskStore {
13906
13948
  }
13907
13949
  }
13908
13950
  openTask(record, type, key, legacy = null) {
13909
- const dir = path13.join(this.paths().tasks, record.id);
13910
- fs10.mkdirSync(dir, { recursive: true });
13951
+ const dir = path14.join(this.paths().tasks, record.id);
13952
+ fs11.mkdirSync(dir, { recursive: true });
13911
13953
  const blobs = this.blobStore();
13912
13954
  const bound = key ? { ...key, boundAt: key.boundAt ?? new Date().toISOString() } : null;
13913
13955
  const event = this.event(record.id, 1, type, {
@@ -13959,11 +14001,11 @@ class TaskStore {
13959
14001
  } catch {}
13960
14002
  if (!latest || latest.events[0]?.id !== last.id)
13961
14003
  return failure2("busy", "the task log changed during compaction; retry", { taskId });
13962
- const appended = fs10.readFileSync(file).subarray(log.end, latest.end);
14004
+ const appended = fs11.readFileSync(file).subarray(log.end, latest.end);
13963
14005
  const bytes = Buffer.concat([Buffer.from(prefix, "utf8"), appended]);
13964
14006
  replaceFile(file, bytes.toString("utf8"), true);
13965
14007
  try {
13966
- fs10.rmSync(this.snapshotPath(taskId), { force: true });
14008
+ fs11.rmSync(this.snapshotPath(taskId), { force: true });
13967
14009
  } catch {}
13968
14010
  const reloaded = this.load(taskId);
13969
14011
  if (reloaded.ok && reloaded.data)
@@ -13976,7 +14018,7 @@ class TaskStore {
13976
14018
  }
13977
14019
  countEvents(file) {
13978
14020
  try {
13979
- const bytes = fs10.readFileSync(file);
14021
+ const bytes = fs11.readFileSync(file);
13980
14022
  let count = 0;
13981
14023
  for (let index = bytes.indexOf(10);index >= 0; index = bytes.indexOf(10, index + 1))
13982
14024
  count += 1;
@@ -13998,8 +14040,8 @@ class TaskStore {
13998
14040
  return bound.ok ? success(null, null, bound.data[0] ?? null) : bound;
13999
14041
  }
14000
14042
  withKeyLock(key, operation) {
14001
- const digest = createHash8("sha256").update(key).digest("hex").slice(0, 32);
14002
- return this.withLock(path13.join(this.paths().dir, "keys", `${digest}.lock`), operation);
14043
+ const digest = createHash9("sha256").update(key).digest("hex").slice(0, 32);
14044
+ return this.withLock(path14.join(this.paths().dir, "keys", `${digest}.lock`), operation);
14003
14045
  }
14004
14046
  bindLocked(taskId, key, timestamp) {
14005
14047
  const current = this.readWorkspace();
@@ -14140,7 +14182,7 @@ class TaskStore {
14140
14182
  writeWorkspace(record) {
14141
14183
  const file = this.paths().workspace;
14142
14184
  try {
14143
- fs10.mkdirSync(path13.dirname(file), { recursive: true });
14185
+ fs11.mkdirSync(path14.dirname(file), { recursive: true });
14144
14186
  replaceFile(file, `${canonicalJson(record)}
14145
14187
  `, true);
14146
14188
  return success(null, null, null);
@@ -14150,7 +14192,7 @@ class TaskStore {
14150
14192
  }
14151
14193
  readIndex() {
14152
14194
  try {
14153
- const value = JSON.parse(fs10.readFileSync(this.paths().index, "utf8"));
14195
+ const value = JSON.parse(fs11.readFileSync(this.paths().index, "utf8"));
14154
14196
  if (!isObject6(value) || value.version !== INDEX_VERSION || !isObject6(value.tasks))
14155
14197
  return {};
14156
14198
  const tasks = {};
@@ -14164,7 +14206,7 @@ class TaskStore {
14164
14206
  }
14165
14207
  writeIndex(entries) {
14166
14208
  try {
14167
- fs10.mkdirSync(this.paths().tasks, { recursive: true });
14209
+ fs11.mkdirSync(this.paths().tasks, { recursive: true });
14168
14210
  replaceFile(this.paths().index, JSON.stringify({
14169
14211
  version: INDEX_VERSION,
14170
14212
  tasks: Object.fromEntries(entries.map((entry) => [entry.id, entry]))
@@ -14218,23 +14260,23 @@ class TaskStore {
14218
14260
  return failure2("revision_conflict", "workspace revision does not match; omit expectedWorkspaceRevision to use the current record", { expectedWorkspaceRevision: expected, actualWorkspaceRevision: actual });
14219
14261
  }
14220
14262
  v2Dirs() {
14221
- return [...new Set([this.root, this.origin])].map((dir) => path13.join(dir, ".workit"));
14263
+ return [...new Set([this.root, this.origin])].map((dir) => path14.join(dir, ".workit"));
14222
14264
  }
14223
14265
  pendingMigrations() {
14224
14266
  return this.v2Dirs().filter((dir) => {
14225
- const raw = this.readV2Workspace(path13.join(dir, "workspace.json"));
14267
+ const raw = this.readV2Workspace(path14.join(dir, "workspace.json"));
14226
14268
  return raw !== null && raw !== TOMBSTONE;
14227
14269
  });
14228
14270
  }
14229
14271
  migrateV2(v2) {
14230
14272
  const dirs = this.paths();
14231
- const v2Workspace = path13.join(v2, "workspace.json");
14232
- const v2Tasks = path13.join(v2, "tasks");
14233
- const legacy = path13.join(dirs.dir, "legacy", checkoutSlug(path13.dirname(v2)), "v2");
14273
+ const v2Workspace = path14.join(v2, "workspace.json");
14274
+ const v2Tasks = path14.join(v2, "tasks");
14275
+ const legacy = path14.join(dirs.dir, "legacy", checkoutSlug(path14.dirname(v2)), "v2");
14234
14276
  const raw = this.readV2Workspace(v2Workspace);
14235
14277
  if (raw === null || raw === TOMBSTONE)
14236
14278
  return success(null, null, null);
14237
- return this.withLock(dirs.checkoutLock, () => this.withLock(path13.join(v2, "metadata.lock"), () => {
14279
+ return this.withLock(dirs.checkoutLock, () => this.withLock(path14.join(v2, "metadata.lock"), () => {
14238
14280
  const workspace = this.readV2Workspace(v2Workspace);
14239
14281
  if (workspace === null || workspace === TOMBSTONE)
14240
14282
  return success(null, null, null);
@@ -14243,7 +14285,7 @@ class TaskStore {
14243
14285
  return failure2("recovery_required", `cannot migrate the 2.x store at ${v2}: ${parsedWorkspace.error}; move it aside to start fresh`, { path: v2Workspace });
14244
14286
  let files = [];
14245
14287
  try {
14246
- files = fs10.readdirSync(v2Tasks).filter((name) => name.endsWith(".json") && validId(name.slice(0, -5))).filter((name) => !this.isStub(path13.join(v2Tasks, name)));
14288
+ files = fs11.readdirSync(v2Tasks).filter((name) => name.endsWith(".json") && validId(name.slice(0, -5))).filter((name) => !this.isStub(path14.join(v2Tasks, name)));
14247
14289
  } catch {}
14248
14290
  const current = this.readWorkspace();
14249
14291
  if (!current.ok)
@@ -14261,22 +14303,22 @@ class TaskStore {
14261
14303
  let skipped = 0;
14262
14304
  const done = new Map;
14263
14305
  try {
14264
- fs10.mkdirSync(path13.join(legacy, "tasks"), { recursive: true });
14306
+ fs11.mkdirSync(path14.join(legacy, "tasks"), { recursive: true });
14265
14307
  for (const name of ["workspace.json", "index.json"])
14266
- if (fs10.existsSync(path13.join(v2, name)))
14267
- fs10.copyFileSync(path13.join(v2, name), path13.join(legacy, name));
14308
+ if (fs11.existsSync(path14.join(v2, name)))
14309
+ fs11.copyFileSync(path14.join(v2, name), path14.join(legacy, name));
14268
14310
  for (const name of files) {
14269
14311
  const id = name.slice(0, -5);
14270
- const file = path13.join(v2Tasks, name);
14271
- const bytes = fs10.readFileSync(file, "utf8");
14312
+ const file = path14.join(v2Tasks, name);
14313
+ const bytes = fs11.readFileSync(file, "utf8");
14272
14314
  const digest = sha256(bytes);
14273
- fs10.writeFileSync(path13.join(legacy, "tasks", name), bytes);
14315
+ fs11.writeFileSync(path14.join(legacy, "tasks", name), bytes);
14274
14316
  const parsed = this.parseRecord(bytes, taskRecordSchema, "2.x task");
14275
14317
  if (!parsed.ok || parsed.data.id !== id)
14276
14318
  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 });
14277
14319
  const record = { ...parsed.data, workspaceId: target.id };
14278
- const origin = { path: path13.join(legacy, "tasks", name), digest };
14279
- if (!fs10.existsSync(this.eventsPath(id))) {
14320
+ const origin = { path: path14.join(legacy, "tasks", name), digest };
14321
+ if (!fs11.existsSync(this.eventsPath(id))) {
14280
14322
  this.openTask(record, "migrated.from_v2", null, origin);
14281
14323
  migrated += 1;
14282
14324
  } else {
@@ -14311,8 +14353,8 @@ class TaskStore {
14311
14353
  try {
14312
14354
  let complete = true;
14313
14355
  for (const [name, digest] of done) {
14314
- const file = path13.join(v2Tasks, name);
14315
- if (sha256(fs10.readFileSync(file, "utf8")) !== digest) {
14356
+ const file = path14.join(v2Tasks, name);
14357
+ if (sha256(fs11.readFileSync(file, "utf8")) !== digest) {
14316
14358
  complete = false;
14317
14359
  continue;
14318
14360
  }
@@ -14322,7 +14364,7 @@ class TaskStore {
14322
14364
  return failure2("busy", `the 2.x store at ${v2} changed during migration; retry`, {
14323
14365
  path: v2
14324
14366
  });
14325
- fs10.rmSync(path13.join(v2, "index.json"), { force: true });
14367
+ fs11.rmSync(path14.join(v2, "index.json"), { force: true });
14326
14368
  this.writeTombstone(v2, target.id);
14327
14369
  } catch (error) {
14328
14370
  return failure2("storage_error", `cannot finish the 2.x migration: ${String(error)}`, {
@@ -14342,45 +14384,45 @@ class TaskStore {
14342
14384
  }
14343
14385
  adoptLocalStore() {
14344
14386
  const dirs = this.paths();
14345
- const marker = path13.join(dirs.v2, "store.json");
14346
- if (!dirs.shared || !fs10.existsSync(marker))
14387
+ const marker = path14.join(dirs.v2, "store.json");
14388
+ if (!dirs.shared || !fs11.existsSync(marker))
14347
14389
  return success(null, null, null);
14348
14390
  return this.withLock(dirs.checkoutLock, () => {
14349
- if (!fs10.existsSync(marker))
14391
+ if (!fs11.existsSync(marker))
14350
14392
  return success(null, null, null);
14351
14393
  let tasks = 0;
14352
14394
  try {
14353
14395
  const merge = (from, to) => {
14354
- if (!fs10.existsSync(to)) {
14355
- fs10.mkdirSync(path13.dirname(to), { recursive: true });
14396
+ if (!fs11.existsSync(to)) {
14397
+ fs11.mkdirSync(path14.dirname(to), { recursive: true });
14356
14398
  try {
14357
- fs10.renameSync(from, to);
14399
+ fs11.renameSync(from, to);
14358
14400
  } catch {
14359
- fs10.cpSync(from, to, { recursive: true, errorOnExist: true, force: false });
14360
- fs10.rmSync(from, { recursive: true, force: true });
14401
+ fs11.cpSync(from, to, { recursive: true, errorOnExist: true, force: false });
14402
+ fs11.rmSync(from, { recursive: true, force: true });
14361
14403
  }
14362
14404
  return;
14363
14405
  }
14364
- if (fs10.lstatSync(from).isDirectory() && fs10.lstatSync(to).isDirectory())
14365
- for (const name of fs10.readdirSync(from))
14366
- merge(path13.join(from, name), path13.join(to, name));
14406
+ if (fs11.lstatSync(from).isDirectory() && fs11.lstatSync(to).isDirectory())
14407
+ for (const name of fs11.readdirSync(from))
14408
+ merge(path14.join(from, name), path14.join(to, name));
14367
14409
  };
14368
14410
  for (const sub of ["tasks", "checkouts", "blobs", "legacy"]) {
14369
- const from = path13.join(dirs.v2, sub);
14370
- if (!fs10.existsSync(from))
14411
+ const from = path14.join(dirs.v2, sub);
14412
+ if (!fs11.existsSync(from))
14371
14413
  continue;
14372
14414
  if (sub === "tasks") {
14373
- for (const name of fs10.readdirSync(from))
14374
- if (validId(name) && !fs10.existsSync(path13.join(dirs.dir, sub, name)))
14415
+ for (const name of fs11.readdirSync(from))
14416
+ if (validId(name) && !fs11.existsSync(path14.join(dirs.dir, sub, name)))
14375
14417
  tasks += 1;
14376
14418
  }
14377
- merge(from, path13.join(dirs.dir, sub));
14419
+ merge(from, path14.join(dirs.dir, sub));
14378
14420
  }
14379
- const ledger = path13.join(dirs.v2, "ledger");
14380
- if (fs10.existsSync(ledger) && !fs10.existsSync(path13.join(dirs.dir, "ledger")))
14381
- merge(ledger, path13.join(dirs.dir, "ledger"));
14382
- fs10.rmSync(path13.join(dirs.v2, "task-index.json"), { force: true });
14383
- fs10.renameSync(marker, path13.join(dirs.v2, "store.moved.json"));
14421
+ const ledger = path14.join(dirs.v2, "ledger");
14422
+ if (fs11.existsSync(ledger) && !fs11.existsSync(path14.join(dirs.dir, "ledger")))
14423
+ merge(ledger, path14.join(dirs.dir, "ledger"));
14424
+ fs11.rmSync(path14.join(dirs.v2, "task-index.json"), { force: true });
14425
+ fs11.renameSync(marker, path14.join(dirs.v2, "store.moved.json"));
14384
14426
  } catch (error) {
14385
14427
  return failure2("storage_error", `cannot move ${dirs.v2} into ${dirs.dir}: ${String(error)}`, {
14386
14428
  path: dirs.v2
@@ -14400,7 +14442,7 @@ class TaskStore {
14400
14442
  readV2Workspace(file) {
14401
14443
  let bytes;
14402
14444
  try {
14403
- bytes = fs10.readFileSync(file, "utf8");
14445
+ bytes = fs11.readFileSync(file, "utf8");
14404
14446
  } catch {
14405
14447
  return null;
14406
14448
  }
@@ -14418,7 +14460,7 @@ class TaskStore {
14418
14460
  schemaVersion: SCHEMA_VERSION,
14419
14461
  id: workspaceId ?? newId(),
14420
14462
  revision: newRevision(),
14421
- root: path13.dirname(v2),
14463
+ root: path14.dirname(v2),
14422
14464
  runtime: { createdWith: version, updatedWith: version },
14423
14465
  writer: null,
14424
14466
  store: {
@@ -14429,12 +14471,12 @@ class TaskStore {
14429
14471
  },
14430
14472
  critical: ["store"]
14431
14473
  };
14432
- fs10.mkdirSync(v2, { recursive: true });
14433
- const ignore = path13.join(v2, ".gitignore");
14434
- if (!fs10.existsSync(ignore))
14435
- fs10.writeFileSync(ignore, `*
14474
+ fs11.mkdirSync(v2, { recursive: true });
14475
+ const ignore = path14.join(v2, ".gitignore");
14476
+ if (!fs11.existsSync(ignore))
14477
+ fs11.writeFileSync(ignore, `*
14436
14478
  `);
14437
- replaceFile(path13.join(v2, "workspace.json"), `${JSON.stringify(marker, null, 2)}
14479
+ replaceFile(path14.join(v2, "workspace.json"), `${JSON.stringify(marker, null, 2)}
14438
14480
  `, true);
14439
14481
  }
14440
14482
  stubFor(taskId) {
@@ -14450,7 +14492,7 @@ class TaskStore {
14450
14492
  }
14451
14493
  isStub(file) {
14452
14494
  try {
14453
- const value = JSON.parse(fs10.readFileSync(file, "utf8"));
14495
+ const value = JSON.parse(fs11.readFileSync(file, "utf8"));
14454
14496
  return isObject6(value) && isObject6(value.store) && value.store.format === "workit-store";
14455
14497
  } catch {
14456
14498
  return false;
@@ -14458,32 +14500,32 @@ class TaskStore {
14458
14500
  }
14459
14501
  writeTombstoneIfMissing() {
14460
14502
  try {
14461
- const v2 = path13.join(this.root, ".workit");
14462
- if (fs10.existsSync(path13.join(v2, "workspace.json")))
14503
+ const v2 = path14.join(this.root, ".workit");
14504
+ if (fs11.existsSync(path14.join(v2, "workspace.json")))
14463
14505
  return;
14464
14506
  let id = null;
14465
14507
  try {
14466
- id = JSON.parse(fs10.readFileSync(this.paths().workspace, "utf8")).id ?? null;
14508
+ id = JSON.parse(fs11.readFileSync(this.paths().workspace, "utf8")).id ?? null;
14467
14509
  } catch {}
14468
14510
  this.writeTombstone(v2, id);
14469
14511
  } catch {}
14470
14512
  }
14471
14513
  initializeStorage() {
14472
14514
  const dirs = this.paths();
14473
- retryTransient(() => fs10.mkdirSync(dirs.checkout, { recursive: true }));
14474
- retryTransient(() => fs10.mkdirSync(dirs.tasks, { recursive: true }));
14475
- if (!fs10.existsSync(dirs.marker))
14515
+ retryTransient(() => fs11.mkdirSync(dirs.checkout, { recursive: true }));
14516
+ retryTransient(() => fs11.mkdirSync(dirs.tasks, { recursive: true }));
14517
+ if (!fs11.existsSync(dirs.marker))
14476
14518
  replaceFile(dirs.marker, `${JSON.stringify({ format: "workit-store", version: STORE_FORMAT, createdWith: runtimeVersion() })}
14477
14519
  `, false);
14478
14520
  if (!dirs.shared) {
14479
- const ignore = path13.join(dirs.dir, ".gitignore");
14521
+ const ignore = path14.join(dirs.dir, ".gitignore");
14480
14522
  let current = null;
14481
14523
  try {
14482
- current = fs10.readFileSync(ignore, "utf8");
14524
+ current = fs11.readFileSync(ignore, "utf8");
14483
14525
  } catch {}
14484
14526
  if (current !== `*
14485
14527
  `)
14486
- retryTransient(() => fs10.writeFileSync(ignore, `*
14528
+ retryTransient(() => fs11.writeFileSync(ignore, `*
14487
14529
  `));
14488
14530
  }
14489
14531
  this.writeTombstoneIfMissing();
@@ -14499,7 +14541,7 @@ class TaskStore {
14499
14541
  shouldReclaim: ({ payload, nowMs }) => {
14500
14542
  let ageMs = null;
14501
14543
  try {
14502
- ageMs = nowMs - fs10.lstatSync(lockPath).mtimeMs;
14544
+ ageMs = nowMs - fs11.lstatSync(lockPath).mtimeMs;
14503
14545
  } catch {}
14504
14546
  return classifyLockOwner(payload, ageMs, localLockHost(), TASK_STORE_LOCK).state === "stale";
14505
14547
  },
@@ -14536,7 +14578,7 @@ class TaskStore {
14536
14578
  withLock(lockPath, operation) {
14537
14579
  try {
14538
14580
  this.initializeStorage();
14539
- fs10.mkdirSync(path13.dirname(lockPath), { recursive: true });
14581
+ fs11.mkdirSync(path14.dirname(lockPath), { recursive: true });
14540
14582
  } catch (error) {
14541
14583
  return failure2("storage_error", `unable to initialize store: ${String(error)}`, {
14542
14584
  path: this.paths().dir
@@ -14576,18 +14618,18 @@ class TaskStore {
14576
14618
  lockDirWritable(lockPath) {
14577
14619
  const probe = `${lockPath}.${process.pid}.${randomUUID3()}.probe`;
14578
14620
  try {
14579
- fs10.closeSync(fs10.openSync(probe, "wx", 384));
14621
+ fs11.closeSync(fs11.openSync(probe, "wx", 384));
14580
14622
  } catch {
14581
14623
  return false;
14582
14624
  }
14583
14625
  try {
14584
- fs10.rmSync(probe, { force: true });
14626
+ fs11.rmSync(probe, { force: true });
14585
14627
  } catch {}
14586
14628
  return true;
14587
14629
  }
14588
14630
  lockHolderPresent(lockPath) {
14589
14631
  try {
14590
- fs10.lstatSync(lockPath);
14632
+ fs11.lstatSync(lockPath);
14591
14633
  return true;
14592
14634
  } catch (error) {
14593
14635
  return error?.code !== "ENOENT";
@@ -14599,12 +14641,12 @@ class TaskStore {
14599
14641
  if (isTransientWindowsError(error) && !this.lockHolderPresent(lockPath) && !this.lockDirWritable(lockPath))
14600
14642
  return failure2("storage_error", `cannot create the workit lock (${code}); no other Workit call holds it`, {
14601
14643
  path: lockPath,
14602
- guidance: `Check permissions and the read-only attribute on ${path13.dirname(lockPath)}.`
14644
+ guidance: `Check permissions and the read-only attribute on ${path14.dirname(lockPath)}.`
14603
14645
  });
14604
14646
  if (code === "EEXIST" || code === "file_lock_timeout" || code === "file_lock_stale" || isTransientWindowsError(error)) {
14605
14647
  let lock = null;
14606
14648
  try {
14607
- lock = parseMetadataLockOrNull(fs10.readFileSync(lockPath, "utf8"));
14649
+ lock = parseMetadataLockOrNull(fs11.readFileSync(lockPath, "utf8"));
14608
14650
  } catch {}
14609
14651
  return failure2("busy", `workit lock is held by another Workit call${lock ? ` (pid ${lock.pid} on ${lock.host})` : ""}; retry shortly`, {
14610
14652
  outcome: "not_started",
@@ -14623,15 +14665,15 @@ var isUncertainWorker = (state) => UNCERTAIN_WORKER_STATES.includes(state);
14623
14665
  var workerBlocksTransition = (transition, state) => transition === "pause" ? false : isUncertainWorker(state);
14624
14666
 
14625
14667
  // packages/workit-core/src/core/task-evaluation.ts
14626
- import { createHash as createHash9 } from "node:crypto";
14627
- import * as fs12 from "node:fs";
14668
+ import { createHash as createHash10 } from "node:crypto";
14669
+ import * as fs13 from "node:fs";
14628
14670
  import { spawnSync as spawnSync10 } from "node:child_process";
14629
- import path15 from "node:path";
14671
+ import path16 from "node:path";
14630
14672
 
14631
14673
  // packages/workit-core/src/check-config.ts
14632
14674
  import { spawnSync as spawnSync9 } from "node:child_process";
14633
- import fs11 from "node:fs";
14634
- import path14 from "node:path";
14675
+ import fs12 from "node:fs";
14676
+ import path15 from "node:path";
14635
14677
  var SCRIPT_CHECKS = ["test", "lint", "typecheck", "check"];
14636
14678
  var CHECKS_FILE = "workit.checks.json";
14637
14679
  var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -14684,10 +14726,10 @@ var git4 = (cwd, args) => {
14684
14726
  return value || null;
14685
14727
  };
14686
14728
  function checkRoot(cwd) {
14687
- return path14.resolve(git4(cwd, ["rev-parse", "--show-toplevel"]) ?? cwd);
14729
+ return path15.resolve(git4(cwd, ["rev-parse", "--show-toplevel"]) ?? cwd);
14688
14730
  }
14689
14731
  var packageManager = (root) => {
14690
- const has = (file) => fs11.existsSync(path14.join(root, file));
14732
+ const has = (file) => fs12.existsSync(path15.join(root, file));
14691
14733
  if (has("bun.lock") || has("bun.lockb"))
14692
14734
  return "bun";
14693
14735
  if (has("pnpm-lock.yaml"))
@@ -14707,7 +14749,7 @@ var CHECK_NAME = /^[a-z0-9][a-z0-9:._-]{0,63}$/u;
14707
14749
  function detectedChecks(root) {
14708
14750
  const read = (file) => {
14709
14751
  try {
14710
- return fs11.readFileSync(path14.join(root, file), "utf8");
14752
+ return fs12.readFileSync(path15.join(root, file), "utf8");
14711
14753
  } catch {
14712
14754
  return null;
14713
14755
  }
@@ -14746,7 +14788,7 @@ function detectedChecks(root) {
14746
14788
  var GATES = ["testing", "verification"];
14747
14789
  function loadCheckConfig(cwd) {
14748
14790
  const root = checkRoot(cwd);
14749
- const file = path14.join(root, CHECKS_FILE);
14791
+ const file = path15.join(root, CHECKS_FILE);
14750
14792
  const none = (error = null) => ({
14751
14793
  source: error ? CHECKS_FILE : "none",
14752
14794
  root,
@@ -14756,7 +14798,7 @@ function loadCheckConfig(cwd) {
14756
14798
  });
14757
14799
  let text = null;
14758
14800
  try {
14759
- text = fs11.readFileSync(file, "utf8");
14801
+ text = fs12.readFileSync(file, "utf8");
14760
14802
  } catch (error) {
14761
14803
  if (error.code !== "ENOENT")
14762
14804
  return none(`cannot read ${CHECKS_FILE}: ${error.message}`);
@@ -14819,10 +14861,10 @@ function workitAvailable(env = process.env) {
14819
14861
  return workitOnPath;
14820
14862
  const windows = process.platform === "win32";
14821
14863
  const exts = windows ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
14822
- const dirs = (env.PATH ?? env.Path ?? "").split(path14.delimiter).filter(Boolean);
14864
+ const dirs = (env.PATH ?? env.Path ?? "").split(path15.delimiter).filter(Boolean);
14823
14865
  workitOnPath = dirs.some((dir) => exts.some((ext) => {
14824
14866
  try {
14825
- return fs11.statSync(path14.join(dir, `workit${ext}`)).isFile();
14867
+ return fs12.statSync(path15.join(dir, `workit${ext}`)).isFile();
14826
14868
  } catch {
14827
14869
  return false;
14828
14870
  }
@@ -14834,15 +14876,15 @@ function checkCommand(args, version, onPath = workitAvailable()) {
14834
14876
  }
14835
14877
 
14836
14878
  // packages/workit-core/src/core/task-evaluation.ts
14837
- var digestBytes = (value) => createHash9("sha256").update(value).digest("hex");
14838
- var inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path15.sep}`);
14839
- var relative = (root, candidate) => path15.relative(root, candidate).split(path15.sep).join("/") || ".";
14879
+ var digestBytes = (value) => createHash10("sha256").update(value).digest("hex");
14880
+ var inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path16.sep}`);
14881
+ var relative = (root, candidate) => path16.relative(root, candidate).split(path16.sep).join("/") || ".";
14840
14882
  var canonicalPath = (value) => {
14841
14883
  if (typeof value !== "string" || !value)
14842
14884
  return null;
14843
14885
  if (value.includes("\\") || value.split("/").includes(".."))
14844
14886
  return null;
14845
- const normalized = path15.posix.normalize(value);
14887
+ const normalized = path16.posix.normalize(value);
14846
14888
  if (normalized === ".." || normalized.startsWith("../") || normalized.startsWith("/"))
14847
14889
  return null;
14848
14890
  return normalized === "." ? "." : normalized.replace(/\/$/, "");
@@ -14890,21 +14932,21 @@ var gitPaths = (root) => {
14890
14932
  git: !/not a git repository/i.test(stderr)
14891
14933
  };
14892
14934
  }
14893
- const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path15.sep).join("/")) : [];
14935
+ const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path16.sep).join("/")) : [];
14894
14936
  const stagedDeleted = spawnSync10("git", ["diff", "--cached", "--name-only", "--diff-filter=D", "-z"], { cwd: root, encoding: "buffer" });
14895
14937
  if (stagedDeleted.status !== 0) {
14896
14938
  const stderr = stagedDeleted.stderr?.toString("utf8") ?? "";
14897
14939
  if (!/not a git repository/i.test(stderr))
14898
14940
  return { paths, uncertain: true, git: true };
14899
14941
  } else if (stagedDeleted.stdout) {
14900
- paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path15.sep).join("/")));
14942
+ paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path16.sep).join("/")));
14901
14943
  }
14902
14944
  return { paths: [...new Set(paths)], uncertain: false, git: true };
14903
14945
  };
14904
14946
  var walk = (root, directory, output) => {
14905
14947
  let names;
14906
14948
  try {
14907
- names = fs12.readdirSync(directory);
14949
+ names = fs13.readdirSync(directory);
14908
14950
  } catch {
14909
14951
  return true;
14910
14952
  }
@@ -14912,10 +14954,10 @@ var walk = (root, directory, output) => {
14912
14954
  for (const name of names) {
14913
14955
  if (name === ".git" || name === ".workit")
14914
14956
  continue;
14915
- const target = path15.join(directory, name);
14957
+ const target = path16.join(directory, name);
14916
14958
  let stat;
14917
14959
  try {
14918
- stat = fs12.lstatSync(target);
14960
+ stat = fs13.lstatSync(target);
14919
14961
  } catch {
14920
14962
  uncertain = true;
14921
14963
  continue;
@@ -14930,14 +14972,14 @@ var walk = (root, directory, output) => {
14930
14972
  var scopeRoots = (root, scope) => {
14931
14973
  const roots = [];
14932
14974
  for (const item of scope.paths.length ? scope.paths : ["."]) {
14933
- const target = path15.resolve(root, item);
14975
+ const target = path16.resolve(root, item);
14934
14976
  if (!inside(root, target))
14935
14977
  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` }] });
14936
14978
  let ancestor = target;
14937
- while (!fs12.existsSync(ancestor) && ancestor !== root)
14938
- ancestor = path15.dirname(ancestor);
14979
+ while (!fs13.existsSync(ancestor) && ancestor !== root)
14980
+ ancestor = path16.dirname(ancestor);
14939
14981
  try {
14940
- if (!inside(root, fs12.realpathSync(ancestor)))
14982
+ if (!inside(root, fs13.realpathSync(ancestor)))
14941
14983
  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` }] });
14942
14984
  } catch {
14943
14985
  return failure2("invalid_input", `candidate scope cannot be inspected: ${item}`);
@@ -14949,7 +14991,7 @@ var scopeRoots = (root, scope) => {
14949
14991
  function captureCandidate(root, scope, environment = []) {
14950
14992
  let checkout;
14951
14993
  try {
14952
- checkout = fs12.realpathSync(root);
14994
+ checkout = fs13.realpathSync(root);
14953
14995
  } catch {
14954
14996
  return failure2("invalid_input", "candidate root does not exist");
14955
14997
  }
@@ -14967,11 +15009,11 @@ function captureCandidate(root, scope, environment = []) {
14967
15009
  if (item === ".git" || item === ".workit")
14968
15010
  continue;
14969
15011
  names.add(item);
14970
- if (!fs12.existsSync(target))
15012
+ if (!fs13.existsSync(target))
14971
15013
  continue;
14972
15014
  let stat;
14973
15015
  try {
14974
- stat = fs12.lstatSync(target);
15016
+ stat = fs13.lstatSync(target);
14975
15017
  } catch {
14976
15018
  uncertain = true;
14977
15019
  continue;
@@ -14987,17 +15029,17 @@ function captureCandidate(root, scope, environment = []) {
14987
15029
  for (const item of [...names].toSorted()) {
14988
15030
  if (!scopeMatches(item, normalizedScope))
14989
15031
  continue;
14990
- const target = path15.join(checkout, item);
15032
+ const target = path16.join(checkout, item);
14991
15033
  try {
14992
- const stat = fs12.lstatSync(target);
15034
+ const stat = fs13.lstatSync(target);
14993
15035
  if (stat.isSymbolicLink()) {
14994
- const link = fs12.readlinkSync(target);
15036
+ const link = fs13.readlinkSync(target);
14995
15037
  files.push({ path: item, kind: "symlink", digest: digestBytes(link), executable: null });
14996
15038
  } else if (stat.isFile()) {
14997
15039
  files.push({
14998
15040
  path: item,
14999
15041
  kind: "file",
15000
- digest: digestBytes(fs12.readFileSync(target)),
15042
+ digest: digestBytes(fs13.readFileSync(target)),
15001
15043
  executable: (stat.mode & 73) !== 0
15002
15044
  });
15003
15045
  } else if (!stat.isDirectory()) {
@@ -15162,7 +15204,7 @@ var findingVerificationPasses = (findingCandidateId, evidence) => evidence.statu
15162
15204
  var verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
15163
15205
  let root;
15164
15206
  try {
15165
- root = fs12.realpathSync(checkoutRoot);
15207
+ root = fs13.realpathSync(checkoutRoot);
15166
15208
  } catch {
15167
15209
  return failure2("permission_denied", "checkout root is unavailable");
15168
15210
  }
@@ -15171,23 +15213,23 @@ var verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
15171
15213
  continue;
15172
15214
  if (!reference.digest)
15173
15215
  return failure2("invalid_input", "document references require a byte digest");
15174
- const target = path15.resolve(root, reference.path);
15175
- if (target !== root && !target.startsWith(`${root}${path15.sep}`))
15216
+ const target = path16.resolve(root, reference.path);
15217
+ if (target !== root && !target.startsWith(`${root}${path16.sep}`))
15176
15218
  return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
15177
15219
  fields: [
15178
15220
  { path: "contentRefs.path", reason: `${reference.path} is outside the checkout` }
15179
15221
  ]
15180
15222
  });
15181
15223
  try {
15182
- const below = path15.relative(root, target);
15224
+ const below = path16.relative(root, target);
15183
15225
  let current = root;
15184
- for (const segment of below.split(path15.sep)) {
15226
+ for (const segment of below.split(path16.sep)) {
15185
15227
  if (!segment)
15186
15228
  continue;
15187
- current = path15.join(current, segment);
15188
- const stat = fs12.lstatSync(current);
15189
- const real = fs12.realpathSync(current);
15190
- if (real !== root && !real.startsWith(`${root}${path15.sep}`))
15229
+ current = path16.join(current, segment);
15230
+ const stat = fs13.lstatSync(current);
15231
+ const real = fs13.realpathSync(current);
15232
+ if (real !== root && !real.startsWith(`${root}${path16.sep}`))
15191
15233
  return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
15192
15234
  fields: [
15193
15235
  {
@@ -15203,7 +15245,7 @@ var verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
15203
15245
  if (current !== target && !stat.isDirectory())
15204
15246
  return failure2("invalid_input", "document reference ancestor is not a directory");
15205
15247
  }
15206
- if (digestBytes(fs12.readFileSync(target)) !== reference.digest)
15248
+ if (digestBytes(fs13.readFileSync(target)) !== reference.digest)
15207
15249
  return failure2("permission_denied", "decision document bytes have changed");
15208
15250
  } catch {
15209
15251
  return failure2("invalid_input", "decision document is unavailable");
@@ -15572,7 +15614,8 @@ Autonomy contract:
15572
15614
  satisfies a gate; an ad-hoc \`workit check -- <cmd>\` never does.
15573
15615
  - Author is not verifier: your own verdict is \`--self\`, shown as
15574
15616
  self-reviewed, never verified. High risk, \`verification: independent\` and
15575
- merge need a verifier with its own session (\`WORKIT_SESSION_ID=<lead>-v<n>\`).
15617
+ merge need a verifier with its own host-derived session (a subagent's
15618
+ \`<lead>:<child>\`, set by the host); never hand-mint one such as \`<lead>-v1\`.
15576
15619
  - A local-commit endpoint does not imply PR readiness, and a local commit alone
15577
15620
  is not evidence of a requested remote push. Before reporting delivery,
15578
15621
  reconcile every requested item and observe it (\`workit verify-delivery\`).
@@ -17400,9 +17443,9 @@ var capabilitiesFor = (descriptor, observed = {}) => descriptor.capabilities.map
17400
17443
  };
17401
17444
  });
17402
17445
  // packages/workit-core/src/hooks/context.ts
17403
- import { createHash as createHash10 } from "node:crypto";
17404
- import fs13 from "node:fs";
17405
- import path16 from "node:path";
17446
+ import { createHash as createHash11 } from "node:crypto";
17447
+ import fs14 from "node:fs";
17448
+ import path17 from "node:path";
17406
17449
  var MIGRATION_PENDING_NOTE = "workit migration pending — run `workit task status`";
17407
17450
  var migrationPending = (result) => !result.ok && result.code === "needs_input" && (result.error ?? "").startsWith(MIGRATION_PENDING);
17408
17451
  var boundTo = (entry, session) => entry.sessions.some((item) => item.host === session.host && item.handle === session.handle);
@@ -17487,7 +17530,7 @@ function entryCompactContext(store, entry, session, context) {
17487
17530
  return null;
17488
17531
  const freshness = { mode: "signal", current: () => recentSignal(store.root) };
17489
17532
  const observed = task?.data.evidence.some(isObservedCheck) ?? false;
17490
- const files = (task?.data.decisions ?? []).flatMap((decision) => decision.data.binding.contentRefs.flatMap((ref) => ref.kind === "file" ? [path16.resolve(store.root, ref.path)] : []));
17533
+ const files = (task?.data.decisions ?? []).flatMap((decision) => decision.data.binding.contentRefs.flatMap((ref) => ref.kind === "file" ? [path17.resolve(store.root, ref.path)] : []));
17491
17534
  const observedFiles = filesKey(files);
17492
17535
  const compact = new WorkitCore(store, context).compactContext(entry?.id ?? null, freshness, origin && { origin: origin.origin, taskId: origin.entry.id });
17493
17536
  if (!compact.ok || !compact.data)
@@ -17556,7 +17599,7 @@ var turnContextText = (input, descriptor) => {
17556
17599
  }
17557
17600
  };
17558
17601
  var TURN_TTL_MS = 7 * 24 * 60 * 60 * 1000;
17559
- var digestOf = (text) => createHash10("sha256").update(text).digest("hex");
17602
+ var digestOf = (text) => createHash11("sha256").update(text).digest("hex");
17560
17603
  var turnMarker = (input) => {
17561
17604
  if (!input.session.id)
17562
17605
  return null;
@@ -17565,32 +17608,32 @@ var turnMarker = (input) => {
17565
17608
  if (location instanceof Error)
17566
17609
  return null;
17567
17610
  const session = [input.host, input.session.id, input.session.agentId ?? ""].join("\x00");
17568
- return path16.join(location.dir, "hooks", `turn-${digestOf(session).slice(0, 32)}.json`);
17611
+ return path17.join(location.dir, "hooks", `turn-${digestOf(session).slice(0, 32)}.json`);
17569
17612
  } catch {
17570
17613
  return null;
17571
17614
  }
17572
17615
  };
17573
17616
  var writeTurnDigest = (file, digest) => {
17574
17617
  try {
17575
- fs13.mkdirSync(path16.dirname(file), { recursive: true });
17576
- fs13.writeFileSync(file, `${JSON.stringify({ digest })}
17618
+ fs14.mkdirSync(path17.dirname(file), { recursive: true });
17619
+ fs14.writeFileSync(file, `${JSON.stringify({ digest })}
17577
17620
  `);
17578
17621
  } catch {}
17579
17622
  };
17580
17623
  var clearTurnDigest = (file) => {
17581
17624
  try {
17582
- fs13.rmSync(file, { force: true });
17625
+ fs14.rmSync(file, { force: true });
17583
17626
  } catch {}
17584
17627
  };
17585
17628
  var pruneTurnDigests = (dir, now) => {
17586
17629
  try {
17587
- for (const name of fs13.readdirSync(dir)) {
17630
+ for (const name of fs14.readdirSync(dir)) {
17588
17631
  if (!name.startsWith("turn-"))
17589
17632
  continue;
17590
- const file = path16.join(dir, name);
17633
+ const file = path17.join(dir, name);
17591
17634
  try {
17592
- if (now - fs13.statSync(file).mtimeMs > TURN_TTL_MS)
17593
- fs13.rmSync(file, { force: true });
17635
+ if (now - fs14.statSync(file).mtimeMs > TURN_TTL_MS)
17636
+ fs14.rmSync(file, { force: true });
17594
17637
  } catch {}
17595
17638
  }
17596
17639
  } catch {}
@@ -17606,7 +17649,7 @@ var changedTurnContext = (input, text) => {
17606
17649
  return text;
17607
17650
  const digest = digestOf(text);
17608
17651
  try {
17609
- const previous = JSON.parse(fs13.readFileSync(file, "utf8"));
17652
+ const previous = JSON.parse(fs14.readFileSync(file, "utf8"));
17610
17653
  if (previous.digest === digest)
17611
17654
  return null;
17612
17655
  } catch {}
@@ -17617,14 +17660,14 @@ var seedTurnContext = (input, descriptor, text = turnContextText(input, descript
17617
17660
  const file = turnMarker(input);
17618
17661
  if (!file)
17619
17662
  return;
17620
- pruneTurnDigests(path16.dirname(file), Date.now());
17663
+ pruneTurnDigests(path17.dirname(file), Date.now());
17621
17664
  if (text)
17622
17665
  writeTurnDigest(file, digestOf(text));
17623
17666
  else
17624
17667
  clearTurnDigest(file);
17625
17668
  };
17626
17669
  // packages/workit-core/src/core/branch.ts
17627
- import { createHash as createHash11 } from "node:crypto";
17670
+ import { createHash as createHash12 } from "node:crypto";
17628
17671
  var withReleaseTracks = (workspaceRoot, policy) => {
17629
17672
  const read = workspaceReleaseTracks(workspaceRoot);
17630
17673
  if (read.error)
@@ -17692,7 +17735,7 @@ var branchPolicySnapshotFor = (workspaceRoot) => {
17692
17735
  const source = resolved.provenance.branchPolicy;
17693
17736
  const allowed = branchPolicy.allowed.map((pattern) => `${pattern.source}/${pattern.flags}`).toSorted();
17694
17737
  const protectedRefs = [...branchPolicy.protected].map((name) => name.toLowerCase()).toSorted();
17695
- const fingerprint = createHash11("sha256").update(JSON.stringify({ allowed, protectedRefs, source })).digest("hex");
17738
+ const fingerprint = createHash12("sha256").update(JSON.stringify({ allowed, protectedRefs, source })).digest("hex");
17696
17739
  return {
17697
17740
  branchPolicy,
17698
17741
  namePolicy: { allowed: branchPolicy.allowed, protected: branchPolicy.protected },
@@ -17741,7 +17784,7 @@ var shellPolicy = (cwd, command) => {
17741
17784
  };
17742
17785
  // packages/workit-core/src/hooks/write-gate.ts
17743
17786
  import { realpathSync as realpathSync5 } from "node:fs";
17744
- import path17 from "node:path";
17787
+ import path18 from "node:path";
17745
17788
 
17746
17789
  // packages/workit-core/src/hooks/shell-words.ts
17747
17790
  var closingQuote = (command, start, dialect) => {
@@ -17871,22 +17914,22 @@ var NONE2 = { kind: "none" };
17871
17914
  var CASE_INSENSITIVE = process.platform === "darwin" || process.platform === "win32";
17872
17915
  var canonical2 = (file) => {
17873
17916
  let rest = "";
17874
- for (let dir = path17.resolve(file);; dir = path17.dirname(dir)) {
17917
+ for (let dir = path18.resolve(file);; dir = path18.dirname(dir)) {
17875
17918
  try {
17876
- return path17.join(realpathSync5(dir), rest);
17919
+ return path18.join(realpathSync5(dir), rest);
17877
17920
  } catch {
17878
- if (path17.dirname(dir) === dir)
17879
- return path17.resolve(file);
17880
- rest = rest ? path17.join(path17.basename(dir), rest) : path17.basename(dir);
17921
+ if (path18.dirname(dir) === dir)
17922
+ return path18.resolve(file);
17923
+ rest = rest ? path18.join(path18.basename(dir), rest) : path18.basename(dir);
17881
17924
  }
17882
17925
  }
17883
17926
  };
17884
17927
  var exempt = (cwd, root, file, plans) => {
17885
17928
  const fold = (value) => CASE_INSENSITIVE ? value.toLowerCase() : value;
17886
- const relative = path17.relative(fold(canonical2(root)), fold(canonical2(path17.resolve(cwd, file))));
17887
- if (relative.startsWith("..") || path17.isAbsolute(relative))
17929
+ const relative = path18.relative(fold(canonical2(root)), fold(canonical2(path18.resolve(cwd, file))));
17930
+ if (relative.startsWith("..") || path18.isAbsolute(relative))
17888
17931
  return true;
17889
- const posix = relative.split(path17.sep).join("/");
17932
+ const posix = relative.split(path18.sep).join("/");
17890
17933
  const segments = posix.split("/");
17891
17934
  return /\.mdx?$/i.test(posix) || segments[0] === "docs" || segments.includes("plans") || [...plans].some((plan) => fold(plan) === posix);
17892
17935
  };
@@ -17984,7 +18027,7 @@ var shellWrites = (command) => {
17984
18027
  return { writes: true, targets: unknown ? null : targets };
17985
18028
  };
17986
18029
  var cache2 = new Map;
17987
- var planKeyOf = (root, plans) => [...plans].map((file) => fileSignature(path17.resolve(root, file)) ?? "-").join("\x00");
18030
+ var planKeyOf = (root, plans) => [...plans].map((file) => fileSignature(path18.resolve(root, file)) ?? "-").join("\x00");
17988
18031
  var gateFor = (cwd) => {
17989
18032
  const store = new TaskStore(cwd);
17990
18033
  const listed = store.listTaskIndex();
@@ -18044,15 +18087,15 @@ import { spawnSync as spawnSync12 } from "node:child_process";
18044
18087
 
18045
18088
  // packages/workit-core/src/hooks/raw-git.ts
18046
18089
  import { spawnSync as spawnSync11 } from "node:child_process";
18047
- import { createHash as createHash13 } from "node:crypto";
18048
- import fs15 from "node:fs";
18090
+ import { createHash as createHash14 } from "node:crypto";
18091
+ import fs16 from "node:fs";
18049
18092
  import os4 from "node:os";
18050
- import path19 from "node:path";
18093
+ import path20 from "node:path";
18051
18094
 
18052
18095
  // packages/workit-core/src/hooks/session-marker.ts
18053
- import { createHash as createHash12 } from "node:crypto";
18054
- import fs14 from "node:fs";
18055
- import path18 from "node:path";
18096
+ import { createHash as createHash13 } from "node:crypto";
18097
+ import fs15 from "node:fs";
18098
+ import path19 from "node:path";
18056
18099
  var sessionMarkerFile = (input, session, store) => {
18057
18100
  let dir = store;
18058
18101
  if (dir === undefined) {
@@ -18061,13 +18104,13 @@ var sessionMarkerFile = (input, session, store) => {
18061
18104
  return null;
18062
18105
  dir = location.dir;
18063
18106
  }
18064
- const name = createHash12("sha256").update(`${input.host}\x00${session}`).digest("hex").slice(0, 32);
18065
- return path18.join(dir, "hooks", `skills-${name}.json`);
18107
+ const name = createHash13("sha256").update(`${input.host}\x00${session}`).digest("hex").slice(0, 32);
18108
+ return path19.join(dir, "hooks", `skills-${name}.json`);
18066
18109
  };
18067
18110
  var list2 = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
18068
18111
  var readSessionMarker = (file) => {
18069
18112
  try {
18070
- const value = JSON.parse(fs14.readFileSync(file, "utf8"));
18113
+ const value = JSON.parse(fs15.readFileSync(file, "utf8"));
18071
18114
  return { nudged: list2(value.nudged), loaded: list2(value.loaded), raw: list2(value.raw) };
18072
18115
  } catch {
18073
18116
  return { nudged: [], loaded: [], raw: [] };
@@ -18075,8 +18118,8 @@ var readSessionMarker = (file) => {
18075
18118
  };
18076
18119
  var writeSessionMarker = (file, marker) => {
18077
18120
  try {
18078
- fs14.mkdirSync(path18.dirname(file), { recursive: true });
18079
- fs14.writeFileSync(file, JSON.stringify(marker));
18121
+ fs15.mkdirSync(path19.dirname(file), { recursive: true });
18122
+ fs15.writeFileSync(file, JSON.stringify(marker));
18080
18123
  } catch {}
18081
18124
  };
18082
18125
 
@@ -18097,12 +18140,12 @@ var GIT_VALUE_OPTIONS = new Set([
18097
18140
  "--config-env",
18098
18141
  "--super-prefix"
18099
18142
  ]);
18100
- var isAbsolute = (value) => path19.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\");
18143
+ var isAbsolute = (value) => path20.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\");
18101
18144
  var joinDir = (base, next) => {
18102
18145
  if (base === undefined || /[$`*?]/.test(next) || next === "-")
18103
18146
  return;
18104
- const expanded = next === "~" || next.startsWith("~/") ? path19.join(os4.homedir(), next.slice(1)) : next;
18105
- return base === null || isAbsolute(expanded) ? expanded : path19.join(base, expanded);
18147
+ const expanded = next === "~" || next.startsWith("~/") ? path20.join(os4.homedir(), next.slice(1)) : next;
18148
+ return base === null || isAbsolute(expanded) ? expanded : path20.join(base, expanded);
18106
18149
  };
18107
18150
  var cdTarget = (words) => {
18108
18151
  const args = words.slice(1);
@@ -18355,7 +18398,7 @@ var repoAt = (dir) => {
18355
18398
  return { location, dir, branch: resolveTaskKey(dir, location).branch };
18356
18399
  };
18357
18400
  var isWorkitWorkspace = (repo) => {
18358
- if (fs15.existsSync(repo.location.dir))
18401
+ if (fs16.existsSync(repo.location.dir))
18359
18402
  return true;
18360
18403
  try {
18361
18404
  return resolveRuntimeWorkspaceVcs(repo.location.top ?? repo.dir) !== null;
@@ -18386,17 +18429,17 @@ var headSha2 = (repo) => {
18386
18429
  if (!git || git.reftable)
18387
18430
  return null;
18388
18431
  try {
18389
- const head = fs15.readFileSync(path19.join(git.gitDir, "HEAD"), "utf8").trim();
18432
+ const head = fs16.readFileSync(path20.join(git.gitDir, "HEAD"), "utf8").trim();
18390
18433
  if (/^[0-9a-f]{40,64}$/.test(head))
18391
18434
  return head;
18392
18435
  const ref = /^ref: (refs\/.+)$/.exec(head)?.[1];
18393
18436
  if (!ref)
18394
18437
  return null;
18395
- const common = path19.dirname(repo.location.dir);
18438
+ const common = path20.dirname(repo.location.dir);
18396
18439
  try {
18397
- return fs15.readFileSync(path19.join(common, ref), "utf8").trim() || null;
18440
+ return fs16.readFileSync(path20.join(common, ref), "utf8").trim() || null;
18398
18441
  } catch {}
18399
- const packed = fs15.readFileSync(path19.join(common, "packed-refs"), "utf8");
18442
+ const packed = fs16.readFileSync(path20.join(common, "packed-refs"), "utf8");
18400
18443
  return new RegExp(`^([0-9a-f]{40,64}) ${ref.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`, "m").exec(packed)?.[1] ?? null;
18401
18444
  } catch {
18402
18445
  return null;
@@ -18433,7 +18476,7 @@ var actionsIn = (cwd, command, dialect) => {
18433
18476
  const action = rawAction(invocation);
18434
18477
  if (!action)
18435
18478
  continue;
18436
- const dir = path19.resolve(cwd, invocation.dir ?? ".");
18479
+ const dir = path20.resolve(cwd, invocation.dir ?? ".");
18437
18480
  if (!repos.has(dir)) {
18438
18481
  const repo = repoAt(dir);
18439
18482
  repos.set(dir, repo && isWorkitWorkspace(repo) ? repo : null);
@@ -18502,8 +18545,8 @@ function rawGitPre(input, command, options = {}) {
18502
18545
  var deny = (reason) => ({ kind: "deny", reason, unblock: null });
18503
18546
  var NEXT_COMMAND = "next";
18504
18547
  var MARKER_TTL_SECONDS = 3600;
18505
- var markerFile = (repo, session, key) => path19.join(repo.location.dir, "hooks", `commit-${createHash13("sha256").update(`${session}\x00${key}`).digest("hex").slice(0, 32)}.json`);
18506
- var callKey = (toolUseId, command) => toolUseId ?? `cmd:${createHash13("sha256").update(command).digest("hex")}`;
18548
+ var markerFile = (repo, session, key) => path20.join(repo.location.dir, "hooks", `commit-${createHash14("sha256").update(`${session}\x00${key}`).digest("hex").slice(0, 32)}.json`);
18549
+ var callKey = (toolUseId, command) => toolUseId ?? `cmd:${createHash14("sha256").update(command).digest("hex")}`;
18507
18550
  function noteRawCommit(input, command, key) {
18508
18551
  try {
18509
18552
  if (!input.session.id || !/\bcommit\b/.test(command))
@@ -18513,8 +18556,8 @@ function noteRawCommit(input, command, key) {
18513
18556
  if (action.kind !== "commit")
18514
18557
  continue;
18515
18558
  const file = markerFile(repo, input.session.id, key);
18516
- fs15.mkdirSync(path19.dirname(file), { recursive: true });
18517
- fs15.writeFileSync(file, `${JSON.stringify({ head: headSha2(repo), at })}
18559
+ fs16.mkdirSync(path20.dirname(file), { recursive: true });
18560
+ fs16.writeFileSync(file, `${JSON.stringify({ head: headSha2(repo), at })}
18518
18561
  `);
18519
18562
  }
18520
18563
  } catch {}
@@ -18537,11 +18580,11 @@ var headCommit = (dir) => {
18537
18580
  var settle2 = (input, repo, file) => {
18538
18581
  let marker;
18539
18582
  try {
18540
- marker = JSON.parse(fs15.readFileSync(file, "utf8"));
18583
+ marker = JSON.parse(fs16.readFileSync(file, "utf8"));
18541
18584
  } catch {
18542
18585
  return;
18543
18586
  }
18544
- fs15.rmSync(file, { force: true });
18587
+ fs16.rmSync(file, { force: true });
18545
18588
  const session = input.session.id;
18546
18589
  const now = Date.now() / 1000;
18547
18590
  if (typeof marker.at !== "number" || now - marker.at > MARKER_TTL_SECONDS)
@@ -18590,7 +18633,7 @@ function settlePendingCommit(input) {
18590
18633
  if (!repo)
18591
18634
  return;
18592
18635
  const file = markerFile(repo, input.session.id, NEXT_COMMAND);
18593
- if (fs15.existsSync(file))
18636
+ if (fs16.existsSync(file))
18594
18637
  settle2(input, repo, file);
18595
18638
  } catch {}
18596
18639
  }
@@ -18980,12 +19023,12 @@ ${line}` };
18980
19023
  };
18981
19024
  // packages/workit-core/src/hooks/hosts/fields.ts
18982
19025
  import { existsSync as existsSync6, realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
18983
- import path20 from "node:path";
19026
+ import path21 from "node:path";
18984
19027
  var isRecord4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
18985
19028
  var nonEmpty2 = (value) => typeof value === "string" && value.trim() !== "";
18986
19029
  var optionalText = (value) => typeof value === "string" ? value : null;
18987
19030
  var existingDirectory = (value) => {
18988
- if (!nonEmpty2(value) || !path20.isAbsolute(value) || !existsSync6(value))
19031
+ if (!nonEmpty2(value) || !path21.isAbsolute(value) || !existsSync6(value))
18989
19032
  return null;
18990
19033
  try {
18991
19034
  return statSync2(value).isDirectory() ? realpathSync6(value) : null;
@@ -19085,6 +19128,8 @@ ${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
19085
19128
  if (role !== "judge" || !event.agentId)
19086
19129
  return readOnly;
19087
19130
  const own = subagentSession(session, event.agentId);
19131
+ if (session)
19132
+ recordIssuedSession(input.cwd || process.cwd(), session, own);
19088
19133
  return `${readOnly} Its own Workit session is ${own}: record verdicts with \`workit ledger verdict <result> --session ${own} ...\` so the ledger tells it apart from the author.`;
19089
19134
  };
19090
19135
  function handleHook(input, deps) {
@@ -19716,12 +19761,12 @@ var codexAdapter = {
19716
19761
  };
19717
19762
  },
19718
19763
  render: render2,
19719
- addendum: (input) => `<workit-codex-mutations>Codex MCP is read-only: unattested callers cannot mutate. Run workit verbs with the workit CLI on the shell (node_modules/.bin/workit, or npx -y @brainervirus/workit-cli): check, git branch|commit|push, pr, ci, stack, ledger, handoff; task-family mutations take --json${input.session.id ? ` --actor ${input.session.id}` : ""}. workit acts as this thread (CODEX_THREAD_ID${input.session.id ? `=${input.session.id}` : ""}) unless WORKIT_SESSION_ID is set. A verifier or reviewer records workit ledger verdict under its own session, never the author's: a workit-verifier or workit-reviewer agent uses the --session its SubagentStart context names; any other uses one the lead assigns (WORKIT_HOST=codex_cli WORKIT_SESSION_ID=<lead>-v<n>). Merge and release need a workspace grant (workit grant show); a question answer is not host permission.</workit-codex-mutations>`
19764
+ addendum: (input) => `<workit-codex-mutations>Codex MCP is read-only: unattested callers cannot mutate. Run workit verbs with the workit CLI on the shell (node_modules/.bin/workit, or npx -y @brainervirus/workit-cli): check, git branch|commit|push, pr, ci, stack, ledger, handoff; task-family mutations take --json${input.session.id ? ` --actor ${input.session.id}` : ""}. workit acts as this thread (CODEX_THREAD_ID${input.session.id ? `=${input.session.id}` : ""}) unless WORKIT_SESSION_ID is set. A verifier or reviewer records workit ledger verdict under its own session, never the author's: a workit-verifier or workit-reviewer agent uses the --session its SubagentStart context names; any other passes --as verifier (an id derived from its own thread). A hand-minted id such as <lead>-v1 is refused as forged_session. Merge and release need a workspace grant (workit grant show); a question answer is not host permission.</workit-codex-mutations>`
19720
19765
  };
19721
19766
 
19722
19767
  // packages/workit-core/src/hooks/hosts/cursor.ts
19723
- import fs16 from "node:fs";
19724
- import path21 from "node:path";
19768
+ import fs17 from "node:fs";
19769
+ import path22 from "node:path";
19725
19770
  var undocumented = { support: "undocumented", native: null };
19726
19771
  var none = { support: "none", native: null };
19727
19772
  var CURSOR_DESCRIPTOR = {
@@ -19918,17 +19963,17 @@ var protocolEvent2 = (input) => {
19918
19963
  };
19919
19964
  var TRANSCRIPT_TAIL_BYTES = 256 * 1024;
19920
19965
  var lastAssistantText = (file) => {
19921
- if (!file || !path21.isAbsolute(file))
19966
+ if (!file || !path22.isAbsolute(file))
19922
19967
  return null;
19923
19968
  try {
19924
- const size = fs16.statSync(file).size;
19969
+ const size = fs17.statSync(file).size;
19925
19970
  const start = Math.max(0, size - TRANSCRIPT_TAIL_BYTES);
19926
19971
  const buffer = Buffer.alloc(size - start);
19927
- const fd = fs16.openSync(file, "r");
19972
+ const fd = fs17.openSync(file, "r");
19928
19973
  try {
19929
- fs16.readSync(fd, buffer, 0, buffer.length, start);
19974
+ fs17.readSync(fd, buffer, 0, buffer.length, start);
19930
19975
  } finally {
19931
- fs16.closeSync(fd);
19976
+ fs17.closeSync(fd);
19932
19977
  }
19933
19978
  const lines = buffer.toString("utf8").split(`
19934
19979
  `);
@@ -19955,7 +20000,7 @@ var lastAssistantText = (file) => {
19955
20000
  return null;
19956
20001
  }
19957
20002
  };
19958
- var within = (root, dir) => dir === root || dir.startsWith(root.endsWith(path21.sep) ? root : `${root}${path21.sep}`);
20003
+ var within = (root, dir) => dir === root || dir.startsWith(root.endsWith(path22.sep) ? root : `${root}${path22.sep}`);
19959
20004
  var hookCwd = (input) => {
19960
20005
  const cwd = existingDirectory(input.cwd);
19961
20006
  if (cwd && input.hook_event_name === "beforeShellExecution")