tamperward 2.39.12 → 2.39.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli/index.js +88 -64
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -791,6 +791,37 @@ function readStateFile(abs) {
791
791
  `${abs} ${notARegularFile(e)}; the gate reads its state files only as regular files \u2014 remove what stands there so the state can be re-established`
792
792
  );
793
793
  }
794
+ function openRegular(abs, refused) {
795
+ let st;
796
+ try {
797
+ st = lstatSync2(abs);
798
+ } catch (e) {
799
+ const code2 = errCode(e);
800
+ if (code2 === "ENOENT" || code2 === "ENOTDIR") return null;
801
+ throw new StateFileError(`${abs} cannot be read (${errText(e)})${refused}`);
802
+ }
803
+ if (!st.isFile()) throw new StateFileError(`${abs} ${notARegularFile(classify(abs, st))}${refused}`);
804
+ let fd;
805
+ try {
806
+ fd = openSync(abs, O_READ);
807
+ } catch (e) {
808
+ const code2 = errCode(e);
809
+ if (code2 === "ENOENT") return null;
810
+ throw new StateFileError(
811
+ `${abs} ${code2 === "ELOOP" || code2 === "ENXIO" ? `changed shape while it was being opened (${errText(e)})` : `cannot be read (${errText(e)})`}${refused}`
812
+ );
813
+ }
814
+ let now;
815
+ try {
816
+ now = fstatSync(fd);
817
+ } catch (e) {
818
+ closeSync(fd);
819
+ throw new StateFileError(`${abs} cannot be read (${errText(e)})${refused}`);
820
+ }
821
+ if (now.isFile()) return fd;
822
+ closeSync(fd);
823
+ throw new StateFileError(`${abs} is a ${now.isDirectory() ? "directory" : irregularName(now)}${refused}`);
824
+ }
794
825
  function stateDirectory(gitDir3) {
795
826
  const dir = join3(gitDir3, "tamperward");
796
827
  const st = lstatSync2(dir, { throwIfNoEntry: false });
@@ -12432,7 +12463,7 @@ var init_fs_events = __esm({
12432
12463
 
12433
12464
  // src/cli/audit.ts
12434
12465
  import { createHash as createHash6, randomBytes as randomBytes2 } from "node:crypto";
12435
- import { closeSync as closeSync4, existsSync as existsSync5, mkdirSync as mkdirSync5, openSync as openSync4, readSync as readSync3 } from "node:fs";
12466
+ import { closeSync as closeSync4, mkdirSync as mkdirSync5, readSync as readSync3 } from "node:fs";
12436
12467
  import { dirname as dirname4, isAbsolute as isAbsolute8, join as join13, resolve as resolve4 } from "node:path";
12437
12468
  function sessionHash(sessionId) {
12438
12469
  if (!sessionId) return void 0;
@@ -12552,7 +12583,8 @@ function parseAuditLine(line, lineNumber) {
12552
12583
  return parseAuditEvent(value, lineNumber);
12553
12584
  }
12554
12585
  function forEachAuditLine(file, onLine, maxLineBytes = MAX_AUDIT_LINE_BYTES) {
12555
- const fd = openSync4(file, "r");
12586
+ const fd = openRegular(file, STATS_READ_REFUSED);
12587
+ if (fd === null) return false;
12556
12588
  try {
12557
12589
  const chunk = Buffer.allocUnsafe(64 * 1024);
12558
12590
  let pending = [];
@@ -12592,6 +12624,7 @@ function forEachAuditLine(file, onLine, maxLineBytes = MAX_AUDIT_LINE_BYTES) {
12592
12624
  } finally {
12593
12625
  closeSync4(fd);
12594
12626
  }
12627
+ return true;
12595
12628
  }
12596
12629
  function parseSince(value, nowMs = Date.now()) {
12597
12630
  const relative13 = /^(\d+)(m|h|d)$/.exec(value);
@@ -12654,11 +12687,6 @@ function createAuditAggregator() {
12654
12687
  }
12655
12688
  };
12656
12689
  }
12657
- function summarizeAudit(events) {
12658
- const aggregator = createAuditAggregator();
12659
- for (const event of events) aggregator.add(event);
12660
- return aggregator.finish();
12661
- }
12662
12690
  function renderAuditStats(summary) {
12663
12691
  const out3 = [
12664
12692
  "TamperWard audit stats",
@@ -12691,23 +12719,18 @@ function runStats(opts = {}) {
12691
12719
  const file = opts.file ? isAbsolute8(opts.file) ? opts.file : resolve4(cwd, opts.file) : configured && configured !== "auto" ? isAbsolute8(configured) ? configured : resolve4(cwd, configured) : defaultAuditPath(cwd);
12692
12720
  const cutoff = opts.since ? parseSince(opts.since) : null;
12693
12721
  if (!file) throw new Error("stats needs --file outside a Git repository");
12694
- if (!existsSync5(file)) {
12695
- if (explicitFile) throw new Error(`audit file not found: ${file}`);
12696
- const empty2 = summarizeAudit([]);
12697
- process.stdout.write(opts.json ? JSON.stringify(empty2) + "\n" : renderAuditStats(empty2));
12698
- return 0;
12699
- }
12700
12722
  const aggregator = createAuditAggregator();
12701
- forEachAuditLine(file, (line, lineNumber) => {
12723
+ const read = forEachAuditLine(file, (line, lineNumber) => {
12702
12724
  const event = parseAuditLine(line, lineNumber);
12703
12725
  if (cutoff !== null && Date.parse(event.timestamp) < cutoff) return;
12704
12726
  aggregator.add(event);
12705
12727
  });
12728
+ if (!read && explicitFile) throw new Error(`audit file not found: ${file}`);
12706
12729
  const summary = aggregator.finish();
12707
12730
  process.stdout.write(opts.json ? JSON.stringify(summary) + "\n" : renderAuditStats(summary));
12708
12731
  return 0;
12709
12732
  }
12710
- var AUDIT_SCHEMA_VERSION, AUDIT_LOG_ENV, MAX_AUDIT_LINE_BYTES, ALLOWED_KEYS;
12733
+ var AUDIT_SCHEMA_VERSION, AUDIT_LOG_ENV, MAX_AUDIT_LINE_BYTES, ALLOWED_KEYS, STATS_READ_REFUSED;
12711
12734
  var init_audit = __esm({
12712
12735
  "src/cli/audit.ts"() {
12713
12736
  "use strict";
@@ -12727,11 +12750,12 @@ var init_audit = __esm({
12727
12750
  "decision",
12728
12751
  "session"
12729
12752
  ]);
12753
+ STATS_READ_REFUSED = "; stats reads the audit log only as a regular file \u2014 remove what stands there so the log can be read";
12730
12754
  }
12731
12755
  });
12732
12756
 
12733
12757
  // src/cli/hook.ts
12734
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync6 } from "node:fs";
12758
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync5 } from "node:fs";
12735
12759
  import { createHash as createHash7 } from "node:crypto";
12736
12760
  function setSnapshotCache(cache3) {
12737
12761
  snapshotCache = cache3;
@@ -13028,7 +13052,7 @@ function turnTransientBlocks(cwd, sessionId, policy, changes) {
13028
13052
  recordObserverHealth(cwd, sessionId, telemetry.state, telemetry.reason);
13029
13053
  }
13030
13054
  const cp = cursorPath(cwd, sessionId);
13031
- if (!existsSync6(log)) return none;
13055
+ if (!existsSync5(log)) return none;
13032
13056
  let offset = 0;
13033
13057
  const cursorText = cp ? readStateFile(cp) : null;
13034
13058
  if (cursorText !== null) {
@@ -13306,7 +13330,7 @@ var init_ptree_cache = __esm({
13306
13330
  });
13307
13331
 
13308
13332
  // src/cli/hook-service.ts
13309
- import { chmodSync, existsSync as existsSync7, lstatSync as lstatSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync7, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "node:fs";
13333
+ import { chmodSync, existsSync as existsSync6, lstatSync as lstatSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync7, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "node:fs";
13310
13334
  import { createConnection as createConnection2, createServer } from "node:net";
13311
13335
  import { realpathSync as realpathSync4 } from "node:fs";
13312
13336
  import { sep } from "node:path";
@@ -13394,7 +13418,7 @@ function removeQuietly(p) {
13394
13418
  }
13395
13419
  }
13396
13420
  function ensurePrivateDir(dir, uid) {
13397
- if (!existsSync7(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
13421
+ if (!existsSync6(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
13398
13422
  const st = lstatSync8(dir);
13399
13423
  if (!st.isDirectory()) throw new Error(`${dir} is not a directory`);
13400
13424
  if (st.uid !== uid) throw new Error(`${dir} is owned by uid ${st.uid}, not ${uid}; refusing to serve from it`);
@@ -13591,7 +13615,7 @@ async function stopHookService(paths, expectedRoot) {
13591
13615
  process.kill(st.pid, "SIGTERM");
13592
13616
  } catch {
13593
13617
  }
13594
- const gone = () => !pidAlive2(st.pid) || !existsSync7(paths.socket);
13618
+ const gone = () => !pidAlive2(st.pid) || !existsSync6(paths.socket);
13595
13619
  const until = Date.now() + STOP_WAIT_MS;
13596
13620
  while (!gone() && Date.now() < until) sleepSync(50);
13597
13621
  if (!gone()) throw new Error(`hook service pid ${st.pid} did not exit within ${STOP_WAIT_MS / 1e3}s`);
@@ -13828,7 +13852,7 @@ var init_verifier_limits = __esm({
13828
13852
  // src/cli/init.ts
13829
13853
  import { execFileSync as execFileSync6 } from "node:child_process";
13830
13854
  import { createHash as createHash8 } from "node:crypto";
13831
- import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync8, realpathSync as realpathSync5 } from "node:fs";
13855
+ import { existsSync as existsSync7, mkdirSync as mkdirSync7, readFileSync as readFileSync8, realpathSync as realpathSync5 } from "node:fs";
13832
13856
  import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute9, join as join15, relative as relative4, resolve as resolve6 } from "node:path";
13833
13857
  function gitConfig(cwd, key2) {
13834
13858
  try {
@@ -13932,7 +13956,7 @@ function verifierCandidates(cwd) {
13932
13956
  if (/^\s*\[tool\.pytest(?:\.ini_options)?\]\s*$/m.test(pyproject)) add("pytest");
13933
13957
  } catch {
13934
13958
  }
13935
- if (existsSync8(join15(cwd, "pytest.ini"))) add("pytest");
13959
+ if (existsSync7(join15(cwd, "pytest.ini"))) add("pytest");
13936
13960
  try {
13937
13961
  const setupCfg = readFileSync8(join15(cwd, "setup.cfg"), "utf8");
13938
13962
  if (/^\s*\[tool:pytest\]\s*$/m.test(setupCfg)) add("pytest");
@@ -13992,7 +14016,7 @@ function planPolicy(cwd) {
13992
14016
  const path = join15(cwd, POLICY_FILE);
13993
14017
  const refused = refuseNonRegular(path);
13994
14018
  if (refused) return { item: "policy", path: POLICY_FILE, status: "error", detail: refused };
13995
- if (existsSync8(path)) {
14019
+ if (existsSync7(path)) {
13996
14020
  try {
13997
14021
  loadPolicy(cwd);
13998
14022
  } catch (e) {
@@ -14011,7 +14035,7 @@ function planPolicy(cwd) {
14011
14035
  function planGitignore(cwd) {
14012
14036
  const rel = ".gitignore";
14013
14037
  const path = join15(cwd, rel);
14014
- if (!existsSync8(join15(cwd, "node_modules"))) return null;
14038
+ if (!existsSync7(join15(cwd, "node_modules"))) return null;
14015
14039
  let existing = "";
14016
14040
  let kind;
14017
14041
  try {
@@ -14076,7 +14100,7 @@ function planClaudeHooks(cwd) {
14076
14100
  const refused = refuseNonRegular(path);
14077
14101
  if (refused) return { item: "agent", path: rel, status: "error", detail: refused };
14078
14102
  let settings = {};
14079
- if (existsSync8(path)) {
14103
+ if (existsSync7(path)) {
14080
14104
  let parsed;
14081
14105
  try {
14082
14106
  parsed = JSON.parse(readFileSync8(path, "utf8"));
@@ -14128,7 +14152,7 @@ function planClaudeHooks(cwd) {
14128
14152
  return {
14129
14153
  item: "agent",
14130
14154
  path: rel,
14131
- status: existsSync8(path) ? "update" : "create",
14155
+ status: existsSync7(path) ? "update" : "create",
14132
14156
  detail: [
14133
14157
  needPre && "wire PreToolUse deny",
14134
14158
  needStop && "wire Stop sweep",
@@ -14172,7 +14196,7 @@ function hooksDir(cwd) {
14172
14196
  if (out3) return resolve6(cwd, out3);
14173
14197
  } catch {
14174
14198
  }
14175
- return existsSync8(join15(cwd, ".git")) ? join15(cwd, ".git", "hooks") : null;
14199
+ return existsSync7(join15(cwd, ".git")) ? join15(cwd, ".git", "hooks") : null;
14176
14200
  }
14177
14201
  function display(cwd, path) {
14178
14202
  const rel = relative4(cwd, path);
@@ -14199,11 +14223,11 @@ function planPreCommit(cwd) {
14199
14223
  const skip = (detail) => ({ item: "pre-commit", path: "(none)", status: "skip", detail });
14200
14224
  let path;
14201
14225
  let note;
14202
- if (existsSync8(join15(cwd, ".husky"))) {
14226
+ if (existsSync7(join15(cwd, ".husky"))) {
14203
14227
  path = join15(cwd, ".husky", "pre-commit");
14204
14228
  note = "husky";
14205
14229
  } else {
14206
- const managed = MANAGED_HOOKS.find((m) => m.configs.some((c) => existsSync8(join15(cwd, c))));
14230
+ const managed = MANAGED_HOOKS.find((m) => m.configs.some((c) => existsSync7(join15(cwd, c))));
14207
14231
  if (managed) {
14208
14232
  return skip(`${managed.name} manages this repository's hooks and regenerates them on install, so a line in the hooks directory would not last \u2014 ${managed.hint}`);
14209
14233
  }
@@ -14221,7 +14245,7 @@ function planPreCommit(cwd) {
14221
14245
  const rel = display(cwd, path);
14222
14246
  const refused = refuseNonRegular(path);
14223
14247
  if (refused) return { item: "pre-commit", path: rel, status: "error", detail: refused };
14224
- const existing = existsSync8(path) ? readFileSync8(path, "utf8") : null;
14248
+ const existing = existsSync7(path) ? readFileSync8(path, "utf8") : null;
14225
14249
  const hookMode = () => existingMode(path, 493) | 73;
14226
14250
  if (existing === null) {
14227
14251
  return {
@@ -14352,7 +14376,7 @@ function planWorkflow(cwd, force) {
14352
14376
  };
14353
14377
  const refused = refuseNonRegular(path);
14354
14378
  if (refused) return { item: "ci", path: rel, status: "error", detail: refused };
14355
- if (!existsSync8(path)) {
14379
+ if (!existsSync7(path)) {
14356
14380
  return {
14357
14381
  item: "ci",
14358
14382
  path: rel,
@@ -14710,7 +14734,7 @@ var init_fingerprint = __esm({
14710
14734
  // src/dependency-env.ts
14711
14735
  import { createHash as createHash10 } from "node:crypto";
14712
14736
  import {
14713
- existsSync as existsSync9,
14737
+ existsSync as existsSync8,
14714
14738
  lstatSync as lstatSync9,
14715
14739
  readdirSync as readdirSync3,
14716
14740
  readFileSync as readFileSync9,
@@ -14864,7 +14888,7 @@ function snapshot(roots, probes, cwd) {
14864
14888
  const h = createHash10("sha256");
14865
14889
  for (const probe of probes) {
14866
14890
  h.update(
14867
- "probe\0" + probe.kind + "\0" + probe.path + "\0" + (existsSync9(probe.path) ? "present" : "absent") + "\0"
14891
+ "probe\0" + probe.kind + "\0" + probe.path + "\0" + (existsSync8(probe.path) ? "present" : "absent") + "\0"
14868
14892
  );
14869
14893
  }
14870
14894
  for (const root of roots) fingerprintRoot(root, cwd, h);
@@ -14923,7 +14947,7 @@ function resolveExecutable(token, cwd, env) {
14923
14947
  if (token.includes("/") || token.includes("\\")) {
14924
14948
  const path = isAbsolute10(token) ? token : resolve7(cwd, token);
14925
14949
  try {
14926
- return existsSync9(path) ? realpathSync6(path) : null;
14950
+ return existsSync8(path) ? realpathSync6(path) : null;
14927
14951
  } catch {
14928
14952
  return null;
14929
14953
  }
@@ -14931,7 +14955,7 @@ function resolveExecutable(token, cwd, env) {
14931
14955
  for (const entry of (env.PATH ?? "").split(delimiter).filter(Boolean)) {
14932
14956
  const candidate = resolve7(entry, token);
14933
14957
  try {
14934
- if (existsSync9(candidate) && statSync3(candidate).isFile()) return realpathSync6(candidate);
14958
+ if (existsSync8(candidate) && statSync3(candidate).isFile()) return realpathSync6(candidate);
14935
14959
  } catch {
14936
14960
  }
14937
14961
  }
@@ -14954,7 +14978,7 @@ function inferredVenvFromToken(token, cwd) {
14954
14978
  const parentName = basename4(parent).toLowerCase();
14955
14979
  if (parentName !== "bin" && parentName !== "scripts") return null;
14956
14980
  const root = dirname6(parent);
14957
- return existsSync9(join16(root, "pyvenv.cfg")) ? root : null;
14981
+ return existsSync8(join16(root, "pyvenv.cfg")) ? root : null;
14958
14982
  }
14959
14983
  function unsupportedEcosystem(command, token) {
14960
14984
  const name = token ? basename4(token).toLowerCase() : "";
@@ -14970,11 +14994,11 @@ function inferredVenv(executable) {
14970
14994
  const parentName = basename4(parent).toLowerCase();
14971
14995
  if (parentName !== "bin" && parentName !== "scripts") return null;
14972
14996
  const root = dirname6(parent);
14973
- return existsSync9(join16(root, "pyvenv.cfg")) ? root : null;
14997
+ return existsSync8(join16(root, "pyvenv.cfg")) ? root : null;
14974
14998
  }
14975
14999
  function venvProblem(root) {
14976
15000
  const cfg = join16(root, "pyvenv.cfg");
14977
- if (!existsSync9(cfg)) return "VIRTUAL_ENV " + JSON.stringify(root) + " has no pyvenv.cfg";
15001
+ if (!existsSync8(cfg)) return "VIRTUAL_ENV " + JSON.stringify(root) + " has no pyvenv.cfg";
14978
15002
  try {
14979
15003
  const body = readFileSync9(cfg, "utf8");
14980
15004
  if (/^\s*include-system-site-packages\s*=\s*true\s*$/im.test(body)) {
@@ -15001,7 +15025,7 @@ function discoverDependencyEnvironment(cwdInput, command, env = process.env) {
15001
15025
  };
15002
15026
  try {
15003
15027
  const nodeModules = join16(cwd, "node_modules");
15004
- if (existsSync9(nodeModules)) addRoot("node_modules", nodeModules);
15028
+ if (existsSync8(nodeModules)) addRoot("node_modules", nodeModules);
15005
15029
  else probes.push({ kind: "node_modules", path: nodeModules });
15006
15030
  const token = firstExecutable(command);
15007
15031
  const executable = resolveExecutable(token, cwd, env);
@@ -15013,7 +15037,7 @@ function discoverDependencyEnvironment(cwdInput, command, env = process.env) {
15013
15037
  venv = resolve7(env.VIRTUAL_ENV);
15014
15038
  } else {
15015
15039
  venv = inferredVenv(executable) ?? inferredVenvFromToken(token, cwd);
15016
- if (!venv && /(?:^|\s)uv\s+run(?:\s|$)/.test(command) && existsSync9(join16(cwd, ".venv", "pyvenv.cfg"))) {
15040
+ if (!venv && /(?:^|\s)uv\s+run(?:\s|$)/.test(command) && existsSync8(join16(cwd, ".venv", "pyvenv.cfg"))) {
15017
15041
  venv = join16(cwd, ".venv");
15018
15042
  }
15019
15043
  }
@@ -16616,7 +16640,7 @@ var init_verification_receipt = __esm({
16616
16640
  // src/cli/verify.ts
16617
16641
  import { execFileSync as execFileSync9, spawnSync as spawnSync3 } from "node:child_process";
16618
16642
  import { createHash as createHash14 } from "node:crypto";
16619
- import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync10, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync3, readFileSync as readFileSync12, readlinkSync as readlinkSync3, rmSync as rmSync9, symlinkSync, writeFileSync as writeFileSync8, existsSync as existsSync10 } from "node:fs";
16643
+ import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync10, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync3, readFileSync as readFileSync12, readlinkSync as readlinkSync3, rmSync as rmSync9, symlinkSync, writeFileSync as writeFileSync8, existsSync as existsSync9 } from "node:fs";
16620
16644
  import { tmpdir as tmpdir4 } from "node:os";
16621
16645
  import { dirname as dirname10, isAbsolute as isAbsolute11, join as join21, relative as relative6, resolve as resolve9, sep as sep4 } from "node:path";
16622
16646
  function oracleAssuranceReport() {
@@ -16812,7 +16836,7 @@ function probeFilesystemCaseSensitivity(dir) {
16812
16836
  const lower = join21(dir, ".tw-case-probe-a");
16813
16837
  try {
16814
16838
  writeFileSync8(upper, "", { flag: "wx" });
16815
- return !existsSync10(lower);
16839
+ return !existsSync9(lower);
16816
16840
  } finally {
16817
16841
  rmSync9(upper, { force: true });
16818
16842
  }
@@ -18605,7 +18629,7 @@ raise SystemExit(0)
18605
18629
 
18606
18630
  // src/cli/doctor.ts
18607
18631
  import { execFileSync as execFileSync11 } from "node:child_process";
18608
- import { existsSync as existsSync11, readFileSync as readFileSync14, readdirSync as readdirSync5 } from "node:fs";
18632
+ import { existsSync as existsSync10, readFileSync as readFileSync14, readdirSync as readdirSync5 } from "node:fs";
18609
18633
  import { join as join23, resolve as resolve11 } from "node:path";
18610
18634
  function lifecyclePlatformCheck(platform = process.platform, linuxPython = platform === "linux" ? trustedLinuxPython() : null) {
18611
18635
  if (platform === "linux") {
@@ -18661,7 +18685,7 @@ function wiringState(status, authority) {
18661
18685
  return authority ? "BROKEN" : "WARN";
18662
18686
  }
18663
18687
  function pinsInFile(path) {
18664
- if (!existsSync11(path)) return [];
18688
+ if (!existsSync10(path)) return [];
18665
18689
  let src = "";
18666
18690
  try {
18667
18691
  src = readFileSync14(path, "utf8");
@@ -18685,7 +18709,7 @@ function workflowPermissionCheck(cwd, workflowRels = [".github/workflows/tamperw
18685
18709
  const warnings = [];
18686
18710
  for (const rel of workflowRels) {
18687
18711
  const path = resolve11(cwd, rel);
18688
- if (!existsSync11(path)) {
18712
+ if (!existsSync10(path)) {
18689
18713
  broken.push(`${rel} is missing`);
18690
18714
  continue;
18691
18715
  }
@@ -19090,7 +19114,7 @@ function diagnose(opts = {}) {
19090
19114
  } else {
19091
19115
  const workflowDirRel = ".github/workflows";
19092
19116
  const workflowDir = resolve11(cwd, workflowDirRel);
19093
- if (!existsSync11(workflowDir)) {
19117
+ if (!existsSync10(workflowDir)) {
19094
19118
  return fail("ci-verifier", `${workflowDirRel}: workflow directory does not exist`);
19095
19119
  }
19096
19120
  let entries;
@@ -19110,7 +19134,7 @@ function diagnose(opts = {}) {
19110
19134
  const authorityWorkflows = [];
19111
19135
  for (const workflowRel of workflowRels) {
19112
19136
  const workflowPath = resolve11(cwd, workflowRel);
19113
- if (!existsSync11(workflowPath)) {
19137
+ if (!existsSync10(workflowPath)) {
19114
19138
  return fail("ci-verifier", `${workflowRel}: workflow does not exist`);
19115
19139
  }
19116
19140
  let doc;
@@ -19429,7 +19453,7 @@ var init_status2 = __esm({
19429
19453
  // src/cli/trace-verify.ts
19430
19454
  import { execFileSync as execFileSync12, spawnSync as spawnSync5 } from "node:child_process";
19431
19455
  import {
19432
- existsSync as existsSync12,
19456
+ existsSync as existsSync11,
19433
19457
  mkdtempSync as mkdtempSync5,
19434
19458
  readFileSync as readFileSync15,
19435
19459
  readdirSync as readdirSync6,
@@ -19688,7 +19712,7 @@ function materializeBase(base, cwd, dest) {
19688
19712
  }
19689
19713
  const hostModules = join24(cwd, "node_modules");
19690
19714
  const tracedModules = join24(dest, "node_modules");
19691
- if (existsSync12(hostModules) && !existsSync12(tracedModules)) {
19715
+ if (existsSync11(hostModules) && !existsSync11(tracedModules)) {
19692
19716
  symlinkSync2(resolve12(hostModules), tracedModules, "dir");
19693
19717
  }
19694
19718
  }
@@ -20000,7 +20024,7 @@ var init_immutable = __esm({
20000
20024
  });
20001
20025
 
20002
20026
  // src/runtimes.ts
20003
- import { existsSync as existsSync13, readFileSync as readFileSync16 } from "node:fs";
20027
+ import { existsSync as existsSync12, readFileSync as readFileSync16 } from "node:fs";
20004
20028
  import { join as join25 } from "node:path";
20005
20029
  function isRecord6(x) {
20006
20030
  return typeof x === "object" && x !== null && !Array.isArray(x);
@@ -20030,7 +20054,7 @@ function claudeSettingsBeyondTamperward(cwd) {
20030
20054
  const path = join25(cwd, ".claude", "settings.json");
20031
20055
  let raw;
20032
20056
  try {
20033
- if (!existsSync13(path)) return false;
20057
+ if (!existsSync12(path)) return false;
20034
20058
  raw = readFileSync16(path, "utf8");
20035
20059
  } catch {
20036
20060
  return false;
@@ -20057,7 +20081,7 @@ function detectRuntimes(cwd) {
20057
20081
  for (const rt of KNOWN_RUNTIMES) {
20058
20082
  const marker = rt.markers.find((m) => {
20059
20083
  try {
20060
- return existsSync13(join25(cwd, m));
20084
+ return existsSync12(join25(cwd, m));
20061
20085
  } catch {
20062
20086
  return false;
20063
20087
  }
@@ -21082,7 +21106,7 @@ var init_adapter3 = __esm({
21082
21106
 
21083
21107
  // src/adapters/copilot-sdk/changes.ts
21084
21108
  import { execFileSync as execFileSync13 } from "node:child_process";
21085
- import { mkdtempSync as mkdtempSync6, writeFileSync as writeFileSync10, readFileSync as readFileSync17, rmSync as rmSync12, existsSync as existsSync14, realpathSync as realpathSync10 } from "node:fs";
21109
+ import { mkdtempSync as mkdtempSync6, writeFileSync as writeFileSync10, readFileSync as readFileSync17, rmSync as rmSync12, existsSync as existsSync13, realpathSync as realpathSync10 } from "node:fs";
21086
21110
  import { tmpdir as tmpdir7 } from "node:os";
21087
21111
  import { basename as basename5, dirname as dirname12, isAbsolute as isAbsolute16, relative as relative11, resolve as resolve15, join as join26 } from "node:path";
21088
21112
  function asStr4(v) {
@@ -21101,7 +21125,7 @@ function canonicalContainedTarget(abs, root) {
21101
21125
  }
21102
21126
  let dir = abs;
21103
21127
  const tail = [];
21104
- while (!existsSync14(dir)) {
21128
+ while (!existsSync13(dir)) {
21105
21129
  const parent = dirname12(dir);
21106
21130
  if (parent === dir) break;
21107
21131
  tail.unshift(basename5(dir));
@@ -21929,7 +21953,7 @@ var init_runtime_qualification = __esm({
21929
21953
 
21930
21954
  // src/cli/runtime.ts
21931
21955
  import { execFileSync as execFileSync14 } from "node:child_process";
21932
- import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync18 } from "node:fs";
21956
+ import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync18 } from "node:fs";
21933
21957
  import { join as join27, dirname as dirname13 } from "node:path";
21934
21958
  function storePath(cwd) {
21935
21959
  const dir = gitDir(cwd);
@@ -22110,7 +22134,7 @@ function resolveHookConfigHash(canonicalId, cwd) {
22110
22134
  "github-copilot-cli": join27(cwd, ".github", "hooks", "tamperward.json")
22111
22135
  };
22112
22136
  const file = files[canonicalId];
22113
- if (!file || !existsSync15(file)) return null;
22137
+ if (!file || !existsSync14(file)) return null;
22114
22138
  try {
22115
22139
  const raw = readFileSync18(file, "utf8");
22116
22140
  let hooks = raw;
@@ -23588,7 +23612,7 @@ var init_record = __esm({
23588
23612
  // src/research/run.ts
23589
23613
  import { randomUUID as randomUUID2 } from "node:crypto";
23590
23614
  import { execFileSync as execFileSync16 } from "node:child_process";
23591
- import { closeSync as closeSync5, existsSync as existsSync16, linkSync, mkdirSync as mkdirSync12, openSync as openSync5, readFileSync as readFileSync21, renameSync as renameSync4, rmSync as rmSync14, unlinkSync, writeFileSync as writeFileSync11, writeSync as writeSync2 } from "node:fs";
23615
+ import { closeSync as closeSync5, existsSync as existsSync15, linkSync, mkdirSync as mkdirSync12, openSync as openSync4, readFileSync as readFileSync21, renameSync as renameSync4, rmSync as rmSync14, unlinkSync, writeFileSync as writeFileSync11, writeSync as writeSync2 } from "node:fs";
23592
23616
  import { hostname } from "node:os";
23593
23617
  import { join as join29, resolve as resolve19 } from "node:path";
23594
23618
  function git7(args, cwd) {
@@ -23625,7 +23649,7 @@ function lockHolder(path) {
23625
23649
  function acquireResearchLock(ledger, breakStaleLock = false) {
23626
23650
  mkdirSync12(ledger, { recursive: true });
23627
23651
  const path = researchLockPath(ledger);
23628
- if (breakStaleLock && existsSync16(path)) {
23652
+ if (breakStaleLock && existsSync15(path)) {
23629
23653
  const owner2 = readLockOwner(path);
23630
23654
  if (!owner2) {
23631
23655
  throw new ResearchError(`research output ${ledger} has an unreadable lock at ${path}; verify no run is active, then remove it deliberately`);
@@ -23668,7 +23692,7 @@ function acquireResearchLock(ledger, breakStaleLock = false) {
23668
23692
  const text = JSON.stringify(owner) + "\n";
23669
23693
  let fd = -1;
23670
23694
  try {
23671
- fd = openSync5(path, "wx", 384);
23695
+ fd = openSync4(path, "wx", 384);
23672
23696
  writeSync2(fd, text);
23673
23697
  closeSync5(fd);
23674
23698
  fd = -1;
@@ -23998,7 +24022,7 @@ function runResearch(opts) {
23998
24022
  try {
23999
24023
  for (let pair = 1; pair <= pairs; pair++) {
24000
24024
  const path = pairRecordPath(ledger, task.id, pair);
24001
- if (!existsSync16(path)) continue;
24025
+ if (!existsSync15(path)) continue;
24002
24026
  const existing = resumableRecord(path, {
24003
24027
  task: task.id,
24004
24028
  pair,
@@ -24118,7 +24142,7 @@ var init_run2 = __esm({
24118
24142
  });
24119
24143
 
24120
24144
  // src/research/ledger-files.ts
24121
- import { closeSync as closeSync6, constants as constants5, fstatSync as fstatSync3, lstatSync as lstatSync12, openSync as openSync6, readFileSync as readFileSync22, readdirSync as readdirSync7, realpathSync as realpathSync12 } from "node:fs";
24145
+ import { closeSync as closeSync6, constants as constants5, fstatSync as fstatSync3, lstatSync as lstatSync12, openSync as openSync5, readFileSync as readFileSync22, readdirSync as readdirSync7, realpathSync as realpathSync12 } from "node:fs";
24122
24146
  import { join as join30, resolve as resolve20 } from "node:path";
24123
24147
  function lstatOrNull(path) {
24124
24148
  try {
@@ -24151,7 +24175,7 @@ function readRegularFile(path, realPairsDir, name) {
24151
24175
  const flags = constants5.O_RDONLY | (constants5.O_NOFOLLOW ?? 0);
24152
24176
  let fd;
24153
24177
  try {
24154
- fd = openSync6(path, flags);
24178
+ fd = openSync5(path, flags);
24155
24179
  } catch (e) {
24156
24180
  throw new ResearchError(`cannot open ledger record ${path}: ${errorMessage(e)}`);
24157
24181
  }
@@ -24334,7 +24358,7 @@ var init_summarize = __esm({
24334
24358
 
24335
24359
  // src/research/init.ts
24336
24360
  import { createHash as createHash17 } from "node:crypto";
24337
- import { existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync23, writeFileSync as writeFileSync12 } from "node:fs";
24361
+ import { existsSync as existsSync16, mkdirSync as mkdirSync13, readFileSync as readFileSync23, writeFileSync as writeFileSync12 } from "node:fs";
24338
24362
  import { basename as basename6, dirname as dirname15, resolve as resolve21 } from "node:path";
24339
24363
  function idFrom(repo) {
24340
24364
  const clean = repo.replace(/[\\/]$/, "").split(/[\\/]/).pop() || "task";
@@ -24346,7 +24370,7 @@ function createResearchManifest(opts) {
24346
24370
  if (!opts.prompt) throw new ResearchError("research init requires --prompt");
24347
24371
  if (!opts.verifyCommand) throw new ResearchError("research init requires --verify-command");
24348
24372
  const out3 = resolve21(opts.out);
24349
- if (existsSync17(out3)) throw new ResearchError(`research init refuses to overwrite ${out3}; choose a new path`);
24373
+ if (existsSync16(out3)) throw new ResearchError(`research init refuses to overwrite ${out3}; choose a new path`);
24350
24374
  const id = opts.id ?? idFrom(opts.repo);
24351
24375
  if (!/^[A-Za-z0-9._-]+$/.test(id)) throw new ResearchError(`research init id must match [A-Za-z0-9._-] (got "${id}")`);
24352
24376
  if (opts.verifyBudget !== void 0 && (!Number.isFinite(opts.verifyBudget) || opts.verifyBudget <= 0)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamperward",
3
- "version": "2.39.12",
3
+ "version": "2.39.13",
4
4
  "description": "The deterministic agent-integrity gate. One ruleset, evaluated on the actual diff/commands as a verdict, enforced everywhere a change can be made.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "hexrift",