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.
- package/dist/cli/index.js +88 -64
- 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,
|
|
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 =
|
|
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
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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) || !
|
|
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
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
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 (
|
|
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:
|
|
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
|
|
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 (
|
|
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) =>
|
|
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 =
|
|
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 (!
|
|
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
|
|
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" + (
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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 (!
|
|
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 (
|
|
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) &&
|
|
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
|
|
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 !
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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 (
|
|
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
|
|
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 (!
|
|
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
|
|
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
|
|
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 (!
|
|
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
|
|
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 || !
|
|
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
|
|
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 &&
|
|
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 =
|
|
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 (!
|
|
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
|
|
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 =
|
|
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
|
|
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 (
|
|
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.
|
|
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",
|