tamperward 2.39.9 → 2.39.10
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 +152 -135
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -769,6 +769,28 @@ function inspectResolved(abs) {
|
|
|
769
769
|
function textOf2(e) {
|
|
770
770
|
return e.content == null ? null : e.content.toString("utf8");
|
|
771
771
|
}
|
|
772
|
+
function notARegularFile(e) {
|
|
773
|
+
switch (e.kind) {
|
|
774
|
+
case "symlink":
|
|
775
|
+
return `is a symbolic link to ${escapeControl(e.detail)}`;
|
|
776
|
+
case "directory":
|
|
777
|
+
return "is a directory";
|
|
778
|
+
case "irregular":
|
|
779
|
+
return `is a ${e.detail}`;
|
|
780
|
+
case "oversize":
|
|
781
|
+
return `is ${e.detail}, above the ${READ_CAP / (1024 * 1024)} MiB the gate reads`;
|
|
782
|
+
default:
|
|
783
|
+
return `cannot be read (${e.detail})`;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
function readStateFile(abs) {
|
|
787
|
+
const e = inspectPath(abs);
|
|
788
|
+
if (e.kind === "absent") return null;
|
|
789
|
+
if (e.kind === "file") return textOf2(e) ?? "";
|
|
790
|
+
throw new StateFileError(
|
|
791
|
+
`${abs} ${notARegularFile(e)}; the gate reads its session state only as a regular file \u2014 remove what stands there so the state can be re-established`
|
|
792
|
+
);
|
|
793
|
+
}
|
|
772
794
|
function describe(e, shown) {
|
|
773
795
|
switch (e.kind) {
|
|
774
796
|
case "symlink":
|
|
@@ -809,7 +831,7 @@ function unjudgeableProtected(cwd, policy, changes) {
|
|
|
809
831
|
}
|
|
810
832
|
return out3;
|
|
811
833
|
}
|
|
812
|
-
var READ_CAP, NO_META, O_READ;
|
|
834
|
+
var READ_CAP, NO_META, O_READ, StateFileError;
|
|
813
835
|
var init_disk = __esm({
|
|
814
836
|
"src/disk.ts"() {
|
|
815
837
|
"use strict";
|
|
@@ -818,6 +840,8 @@ var init_disk = __esm({
|
|
|
818
840
|
READ_CAP = 64 * 1024 * 1024;
|
|
819
841
|
NO_META = { mode: 0, size: 0, mtimeMs: 0 };
|
|
820
842
|
O_READ = constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0);
|
|
843
|
+
StateFileError = class extends Error {
|
|
844
|
+
};
|
|
821
845
|
}
|
|
822
846
|
});
|
|
823
847
|
|
|
@@ -10868,20 +10892,6 @@ function parseOrThrow(src, where) {
|
|
|
10868
10892
|
}
|
|
10869
10893
|
return parsePolicy(raw, where);
|
|
10870
10894
|
}
|
|
10871
|
-
function notARegularFile(e) {
|
|
10872
|
-
switch (e.kind) {
|
|
10873
|
-
case "symlink":
|
|
10874
|
-
return `is a symbolic link to ${escapeControl(e.detail)}`;
|
|
10875
|
-
case "directory":
|
|
10876
|
-
return "is a directory";
|
|
10877
|
-
case "irregular":
|
|
10878
|
-
return `is a ${e.detail}`;
|
|
10879
|
-
case "oversize":
|
|
10880
|
-
return `is ${e.detail}, above the ${READ_CAP / (1024 * 1024)} MiB the gate reads`;
|
|
10881
|
-
default:
|
|
10882
|
-
return `cannot be read (${e.detail})`;
|
|
10883
|
-
}
|
|
10884
|
-
}
|
|
10885
10895
|
function loadPolicy(cwd = process.cwd()) {
|
|
10886
10896
|
const entry = inspectPath(join8(repoRoot(cwd), POLICY_FILE));
|
|
10887
10897
|
if (entry.kind === "absent") return defaultPolicy();
|
|
@@ -11553,7 +11563,7 @@ var init_deny = __esm({
|
|
|
11553
11563
|
});
|
|
11554
11564
|
|
|
11555
11565
|
// src/session.ts
|
|
11556
|
-
import {
|
|
11566
|
+
import { mkdirSync as mkdirSync2, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
11557
11567
|
import { dirname as dirname3, join as join10 } from "node:path";
|
|
11558
11568
|
function writeBaseline(p, sha3) {
|
|
11559
11569
|
mkdirSync2(dirname3(p), { recursive: true });
|
|
@@ -11578,13 +11588,8 @@ function turnBaseline(cwd, sessionId) {
|
|
|
11578
11588
|
if (!sessionId) return null;
|
|
11579
11589
|
const p = baselinePath(cwd, sessionId);
|
|
11580
11590
|
if (!p) return null;
|
|
11581
|
-
|
|
11582
|
-
|
|
11583
|
-
const v = readFileSync6(p, "utf8").trim();
|
|
11584
|
-
if (SHA.test(v)) return v;
|
|
11585
|
-
}
|
|
11586
|
-
} catch {
|
|
11587
|
-
}
|
|
11591
|
+
const v = readStateFile(p)?.trim();
|
|
11592
|
+
if (v !== void 0 && SHA.test(v)) return v;
|
|
11588
11593
|
const head = headSha(cwd);
|
|
11589
11594
|
if (!head) return null;
|
|
11590
11595
|
try {
|
|
@@ -11608,6 +11613,7 @@ var UNSAFE, SHA, BaselineWriteError;
|
|
|
11608
11613
|
var init_session = __esm({
|
|
11609
11614
|
"src/session.ts"() {
|
|
11610
11615
|
"use strict";
|
|
11616
|
+
init_disk();
|
|
11611
11617
|
init_build();
|
|
11612
11618
|
UNSAFE = /[^A-Za-z0-9_-]/g;
|
|
11613
11619
|
SHA = /^[0-9a-f]{40}$/;
|
|
@@ -11623,7 +11629,7 @@ var init_session = __esm({
|
|
|
11623
11629
|
|
|
11624
11630
|
// src/effect.ts
|
|
11625
11631
|
import { createHash as createHash4 } from "node:crypto";
|
|
11626
|
-
import {
|
|
11632
|
+
import { lstatSync as lstatSync4, mkdirSync as mkdirSync3, readdirSync, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
11627
11633
|
import { join as join11 } from "node:path";
|
|
11628
11634
|
function ptreeFrom(value) {
|
|
11629
11635
|
if (!isRecord(value)) return null;
|
|
@@ -11715,9 +11721,11 @@ function driftBetween(expected, current) {
|
|
|
11715
11721
|
return { changed, deleted, added };
|
|
11716
11722
|
}
|
|
11717
11723
|
function loadTree(p) {
|
|
11718
|
-
if (!p
|
|
11724
|
+
if (!p) return null;
|
|
11725
|
+
const text = readStateFile(p);
|
|
11726
|
+
if (text === null) return null;
|
|
11719
11727
|
try {
|
|
11720
|
-
return ptreeFrom(JSON.parse(
|
|
11728
|
+
return ptreeFrom(JSON.parse(text));
|
|
11721
11729
|
} catch {
|
|
11722
11730
|
return null;
|
|
11723
11731
|
}
|
|
@@ -11770,7 +11778,7 @@ var init_effect = __esm({
|
|
|
11770
11778
|
});
|
|
11771
11779
|
|
|
11772
11780
|
// src/cli/watch.ts
|
|
11773
|
-
import { appendFileSync as appendFileSync3, lstatSync as lstatSync5, mkdirSync as mkdirSync4,
|
|
11781
|
+
import { appendFileSync as appendFileSync3, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readdirSync as readdirSync2, watch, writeFileSync as writeFileSync4 } from "node:fs";
|
|
11774
11782
|
import { join as join12 } from "node:path";
|
|
11775
11783
|
import { createHash as createHash5 } from "node:crypto";
|
|
11776
11784
|
function snap(abs) {
|
|
@@ -11788,8 +11796,10 @@ function watcherHealthPath(log) {
|
|
|
11788
11796
|
return `${log}.health.json`;
|
|
11789
11797
|
}
|
|
11790
11798
|
function readWatcherHealth(log) {
|
|
11799
|
+
const text = readStateFile(watcherHealthPath(log));
|
|
11800
|
+
if (text === null) return null;
|
|
11791
11801
|
try {
|
|
11792
|
-
const value = JSON.parse(
|
|
11802
|
+
const value = JSON.parse(text);
|
|
11793
11803
|
if (!isRecord(value)) return null;
|
|
11794
11804
|
const { state, backend, pid, started_at } = value;
|
|
11795
11805
|
if (value.version !== 1 || typeof pid !== "number" || typeof started_at !== "string") return null;
|
|
@@ -11823,7 +11833,13 @@ function pidAlive(pid) {
|
|
|
11823
11833
|
}
|
|
11824
11834
|
}
|
|
11825
11835
|
function watcherTelemetry(log) {
|
|
11826
|
-
|
|
11836
|
+
let health;
|
|
11837
|
+
try {
|
|
11838
|
+
health = readWatcherHealth(log);
|
|
11839
|
+
} catch (e) {
|
|
11840
|
+
if (!(e instanceof StateFileError)) throw e;
|
|
11841
|
+
return { state: "unavailable", health: null, reason: e.message };
|
|
11842
|
+
}
|
|
11827
11843
|
if (!health) return { state: "unavailable", health: null, reason: "no health record" };
|
|
11828
11844
|
if (health.state === "stopped")
|
|
11829
11845
|
return { state: "unavailable", health, reason: "observer stopped" };
|
|
@@ -12317,7 +12333,7 @@ var init_fs_events = __esm({
|
|
|
12317
12333
|
|
|
12318
12334
|
// src/cli/audit.ts
|
|
12319
12335
|
import { createHash as createHash6, randomBytes } from "node:crypto";
|
|
12320
|
-
import { appendFileSync as appendFileSync4, closeSync as closeSync4, existsSync as
|
|
12336
|
+
import { appendFileSync as appendFileSync4, closeSync as closeSync4, existsSync as existsSync5, mkdirSync as mkdirSync5, openSync as openSync4, readSync as readSync3 } from "node:fs";
|
|
12321
12337
|
import { dirname as dirname4, isAbsolute as isAbsolute8, join as join13, resolve as resolve4 } from "node:path";
|
|
12322
12338
|
function sessionHash(sessionId) {
|
|
12323
12339
|
if (!sessionId) return void 0;
|
|
@@ -12576,7 +12592,7 @@ function runStats(opts = {}) {
|
|
|
12576
12592
|
const file = opts.file ? isAbsolute8(opts.file) ? opts.file : resolve4(cwd, opts.file) : configured && configured !== "auto" ? isAbsolute8(configured) ? configured : resolve4(cwd, configured) : defaultAuditPath(cwd);
|
|
12577
12593
|
const cutoff = opts.since ? parseSince(opts.since) : null;
|
|
12578
12594
|
if (!file) throw new Error("stats needs --file outside a Git repository");
|
|
12579
|
-
if (!
|
|
12595
|
+
if (!existsSync5(file)) {
|
|
12580
12596
|
if (explicitFile) throw new Error(`audit file not found: ${file}`);
|
|
12581
12597
|
const empty2 = summarizeAudit([]);
|
|
12582
12598
|
process.stdout.write(opts.json ? JSON.stringify(empty2) + "\n" : renderAuditStats(empty2));
|
|
@@ -12615,14 +12631,14 @@ var init_audit = __esm({
|
|
|
12615
12631
|
});
|
|
12616
12632
|
|
|
12617
12633
|
// src/cli/hook.ts
|
|
12618
|
-
import { readFileSync as
|
|
12634
|
+
import { readFileSync as readFileSync6, appendFileSync as appendFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync6 } from "node:fs";
|
|
12619
12635
|
import { createHash as createHash7 } from "node:crypto";
|
|
12620
12636
|
function setSnapshotCache(cache3) {
|
|
12621
12637
|
snapshotCache = cache3;
|
|
12622
12638
|
}
|
|
12623
12639
|
function readStdin() {
|
|
12624
12640
|
try {
|
|
12625
|
-
return
|
|
12641
|
+
return readFileSync6(0, "utf8");
|
|
12626
12642
|
} catch (e) {
|
|
12627
12643
|
throw new HookInputError(`cannot read the hook payload on stdin: ${e instanceof Error ? e.message : String(e)}`);
|
|
12628
12644
|
}
|
|
@@ -12912,10 +12928,11 @@ function turnTransientBlocks(cwd, sessionId, policy, changes) {
|
|
|
12912
12928
|
recordObserverHealth(cwd, sessionId, telemetry.state, telemetry.reason);
|
|
12913
12929
|
}
|
|
12914
12930
|
const cp = cursorPath(cwd, sessionId);
|
|
12915
|
-
if (!
|
|
12931
|
+
if (!existsSync6(log)) return none;
|
|
12916
12932
|
let offset = 0;
|
|
12917
|
-
|
|
12918
|
-
|
|
12933
|
+
const cursorText = cp ? readStateFile(cp) : null;
|
|
12934
|
+
if (cursorText !== null) {
|
|
12935
|
+
const n2 = Number(cursorText);
|
|
12919
12936
|
offset = Number.isFinite(n2) ? n2 : 0;
|
|
12920
12937
|
}
|
|
12921
12938
|
const drained = drainEvents(log, offset);
|
|
@@ -13189,13 +13206,13 @@ var init_ptree_cache = __esm({
|
|
|
13189
13206
|
});
|
|
13190
13207
|
|
|
13191
13208
|
// src/cli/hook-service.ts
|
|
13192
|
-
import { chmodSync, existsSync as
|
|
13209
|
+
import { chmodSync, existsSync as existsSync7, lstatSync as lstatSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync7, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
13193
13210
|
import { createConnection as createConnection2, createServer } from "node:net";
|
|
13194
13211
|
import { realpathSync as realpathSync4 } from "node:fs";
|
|
13195
13212
|
import { sep } from "node:path";
|
|
13196
13213
|
function readServiceState(paths) {
|
|
13197
13214
|
try {
|
|
13198
|
-
const v = JSON.parse(
|
|
13215
|
+
const v = JSON.parse(readFileSync7(paths.state, "utf8"));
|
|
13199
13216
|
if (!isRecord(v)) return null;
|
|
13200
13217
|
const { pid, version, root, started_at } = v;
|
|
13201
13218
|
if (typeof pid !== "number" || typeof version !== "string" || typeof root !== "string" || typeof started_at !== "string") return null;
|
|
@@ -13277,7 +13294,7 @@ function removeQuietly(p) {
|
|
|
13277
13294
|
}
|
|
13278
13295
|
}
|
|
13279
13296
|
function ensurePrivateDir(dir, uid) {
|
|
13280
|
-
if (!
|
|
13297
|
+
if (!existsSync7(dir)) mkdirSync6(dir, { recursive: true, mode: 448 });
|
|
13281
13298
|
const st = lstatSync7(dir);
|
|
13282
13299
|
if (!st.isDirectory()) throw new Error(`${dir} is not a directory`);
|
|
13283
13300
|
if (st.uid !== uid) throw new Error(`${dir} is owned by uid ${st.uid}, not ${uid}; refusing to serve from it`);
|
|
@@ -13474,7 +13491,7 @@ async function stopHookService(paths, expectedRoot) {
|
|
|
13474
13491
|
process.kill(st.pid, "SIGTERM");
|
|
13475
13492
|
} catch {
|
|
13476
13493
|
}
|
|
13477
|
-
const gone = () => !pidAlive2(st.pid) || !
|
|
13494
|
+
const gone = () => !pidAlive2(st.pid) || !existsSync7(paths.socket);
|
|
13478
13495
|
const until = Date.now() + STOP_WAIT_MS;
|
|
13479
13496
|
while (!gone() && Date.now() < until) sleepSync(50);
|
|
13480
13497
|
if (!gone()) throw new Error(`hook service pid ${st.pid} did not exit within ${STOP_WAIT_MS / 1e3}s`);
|
|
@@ -13756,7 +13773,7 @@ var init_safe_write = __esm({
|
|
|
13756
13773
|
// src/cli/init.ts
|
|
13757
13774
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
13758
13775
|
import { createHash as createHash8 } from "node:crypto";
|
|
13759
|
-
import { existsSync as
|
|
13776
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync8, realpathSync as realpathSync5 } from "node:fs";
|
|
13760
13777
|
import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute9, join as join15, relative as relative4, resolve as resolve6 } from "node:path";
|
|
13761
13778
|
function gitConfig(cwd, key2) {
|
|
13762
13779
|
try {
|
|
@@ -13850,34 +13867,34 @@ function verifierCandidates(cwd) {
|
|
|
13850
13867
|
if (!candidates.includes(command)) candidates.push(command);
|
|
13851
13868
|
};
|
|
13852
13869
|
try {
|
|
13853
|
-
const pkg = JSON.parse(
|
|
13870
|
+
const pkg = JSON.parse(readFileSync8(join15(cwd, "package.json"), "utf8"));
|
|
13854
13871
|
const test = isRecord(pkg) && isRecord(pkg.scripts) ? pkg.scripts.test : void 0;
|
|
13855
13872
|
if (typeof test === "string" && test.trim() !== "" && !/error:\s*no test specified/i.test(test)) add("npm test");
|
|
13856
13873
|
} catch {
|
|
13857
13874
|
}
|
|
13858
13875
|
try {
|
|
13859
|
-
const pyproject =
|
|
13876
|
+
const pyproject = readFileSync8(join15(cwd, "pyproject.toml"), "utf8");
|
|
13860
13877
|
if (/^\s*\[tool\.pytest(?:\.ini_options)?\]\s*$/m.test(pyproject)) add("pytest");
|
|
13861
13878
|
} catch {
|
|
13862
13879
|
}
|
|
13863
|
-
if (
|
|
13880
|
+
if (existsSync8(join15(cwd, "pytest.ini"))) add("pytest");
|
|
13864
13881
|
try {
|
|
13865
|
-
const setupCfg =
|
|
13882
|
+
const setupCfg = readFileSync8(join15(cwd, "setup.cfg"), "utf8");
|
|
13866
13883
|
if (/^\s*\[tool:pytest\]\s*$/m.test(setupCfg)) add("pytest");
|
|
13867
13884
|
} catch {
|
|
13868
13885
|
}
|
|
13869
13886
|
try {
|
|
13870
|
-
const tox =
|
|
13887
|
+
const tox = readFileSync8(join15(cwd, "tox.ini"), "utf8");
|
|
13871
13888
|
if (/^\s*\[tox\]\s*$/m.test(tox)) add("tox");
|
|
13872
13889
|
} catch {
|
|
13873
13890
|
}
|
|
13874
13891
|
try {
|
|
13875
|
-
const cargo =
|
|
13892
|
+
const cargo = readFileSync8(join15(cwd, "Cargo.toml"), "utf8");
|
|
13876
13893
|
if (/^\s*\[(?:package|workspace)\]\s*(?:#.*)?$/m.test(cargo)) add("cargo test");
|
|
13877
13894
|
} catch {
|
|
13878
13895
|
}
|
|
13879
13896
|
try {
|
|
13880
|
-
const goMod =
|
|
13897
|
+
const goMod = readFileSync8(join15(cwd, "go.mod"), "utf8");
|
|
13881
13898
|
if (/^\s*module\s+\S+\s*(?:\/\/.*)?$/m.test(goMod)) add("go test ./...");
|
|
13882
13899
|
} catch {
|
|
13883
13900
|
}
|
|
@@ -13920,7 +13937,7 @@ function planPolicy(cwd) {
|
|
|
13920
13937
|
const path = join15(cwd, POLICY_FILE);
|
|
13921
13938
|
const refused = refuseNonRegular(path);
|
|
13922
13939
|
if (refused) return { item: "policy", path: POLICY_FILE, status: "error", detail: refused };
|
|
13923
|
-
if (
|
|
13940
|
+
if (existsSync8(path)) {
|
|
13924
13941
|
try {
|
|
13925
13942
|
loadPolicy(cwd);
|
|
13926
13943
|
} catch (e) {
|
|
@@ -13939,7 +13956,7 @@ function planPolicy(cwd) {
|
|
|
13939
13956
|
function planGitignore(cwd) {
|
|
13940
13957
|
const rel = ".gitignore";
|
|
13941
13958
|
const path = join15(cwd, rel);
|
|
13942
|
-
if (!
|
|
13959
|
+
if (!existsSync8(join15(cwd, "node_modules"))) return null;
|
|
13943
13960
|
let existing = "";
|
|
13944
13961
|
let kind;
|
|
13945
13962
|
try {
|
|
@@ -13949,7 +13966,7 @@ function planGitignore(cwd) {
|
|
|
13949
13966
|
}
|
|
13950
13967
|
const refused = refuseNonRegular(path);
|
|
13951
13968
|
if (refused) return { item: "gitignore", path: rel, status: "error", detail: refused };
|
|
13952
|
-
if (kind === "file") existing =
|
|
13969
|
+
if (kind === "file") existing = readFileSync8(path, "utf8");
|
|
13953
13970
|
try {
|
|
13954
13971
|
const tracked = execFileSync6("git", ["ls-files", "--cached", "--", "node_modules"], {
|
|
13955
13972
|
cwd,
|
|
@@ -14004,10 +14021,10 @@ function planClaudeHooks(cwd) {
|
|
|
14004
14021
|
const refused = refuseNonRegular(path);
|
|
14005
14022
|
if (refused) return { item: "agent", path: rel, status: "error", detail: refused };
|
|
14006
14023
|
let settings = {};
|
|
14007
|
-
if (
|
|
14024
|
+
if (existsSync8(path)) {
|
|
14008
14025
|
let parsed;
|
|
14009
14026
|
try {
|
|
14010
|
-
parsed = JSON.parse(
|
|
14027
|
+
parsed = JSON.parse(readFileSync8(path, "utf8"));
|
|
14011
14028
|
} catch {
|
|
14012
14029
|
return {
|
|
14013
14030
|
item: "agent",
|
|
@@ -14056,7 +14073,7 @@ function planClaudeHooks(cwd) {
|
|
|
14056
14073
|
return {
|
|
14057
14074
|
item: "agent",
|
|
14058
14075
|
path: rel,
|
|
14059
|
-
status:
|
|
14076
|
+
status: existsSync8(path) ? "update" : "create",
|
|
14060
14077
|
detail: [
|
|
14061
14078
|
needPre && "wire PreToolUse deny",
|
|
14062
14079
|
needStop && "wire Stop sweep",
|
|
@@ -14100,7 +14117,7 @@ function hooksDir(cwd) {
|
|
|
14100
14117
|
if (out3) return resolve6(cwd, out3);
|
|
14101
14118
|
} catch {
|
|
14102
14119
|
}
|
|
14103
|
-
return
|
|
14120
|
+
return existsSync8(join15(cwd, ".git")) ? join15(cwd, ".git", "hooks") : null;
|
|
14104
14121
|
}
|
|
14105
14122
|
function display(cwd, path) {
|
|
14106
14123
|
const rel = relative4(cwd, path);
|
|
@@ -14127,11 +14144,11 @@ function planPreCommit(cwd) {
|
|
|
14127
14144
|
const skip = (detail) => ({ item: "pre-commit", path: "(none)", status: "skip", detail });
|
|
14128
14145
|
let path;
|
|
14129
14146
|
let note;
|
|
14130
|
-
if (
|
|
14147
|
+
if (existsSync8(join15(cwd, ".husky"))) {
|
|
14131
14148
|
path = join15(cwd, ".husky", "pre-commit");
|
|
14132
14149
|
note = "husky";
|
|
14133
14150
|
} else {
|
|
14134
|
-
const managed = MANAGED_HOOKS.find((m) => m.configs.some((c) =>
|
|
14151
|
+
const managed = MANAGED_HOOKS.find((m) => m.configs.some((c) => existsSync8(join15(cwd, c))));
|
|
14135
14152
|
if (managed) {
|
|
14136
14153
|
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}`);
|
|
14137
14154
|
}
|
|
@@ -14149,7 +14166,7 @@ function planPreCommit(cwd) {
|
|
|
14149
14166
|
const rel = display(cwd, path);
|
|
14150
14167
|
const refused = refuseNonRegular(path);
|
|
14151
14168
|
if (refused) return { item: "pre-commit", path: rel, status: "error", detail: refused };
|
|
14152
|
-
const existing =
|
|
14169
|
+
const existing = existsSync8(path) ? readFileSync8(path, "utf8") : null;
|
|
14153
14170
|
const hookMode = () => existingMode(path, 493) | 73;
|
|
14154
14171
|
if (existing === null) {
|
|
14155
14172
|
return {
|
|
@@ -14240,7 +14257,7 @@ function planCodeowners(cwd) {
|
|
|
14240
14257
|
const path = join15(cwd, existingRel ?? rel);
|
|
14241
14258
|
const refused = refuseNonRegular(path);
|
|
14242
14259
|
if (refused) return { item: "codeowners", path: existingRel ?? rel, status: "error", detail: refused };
|
|
14243
|
-
const existing = existingRel ?
|
|
14260
|
+
const existing = existingRel ? readFileSync8(path, "utf8") : null;
|
|
14244
14261
|
const missing = CODEOWNERS_PATHS.filter((p) => existing === null || !coveredBy(existing, p));
|
|
14245
14262
|
if (existingRel !== void 0 && missing.length === 0) {
|
|
14246
14263
|
return { item: "codeowners", path: existingRel, status: "ok", detail: "gate paths already have code owners" };
|
|
@@ -14280,7 +14297,7 @@ function planWorkflow(cwd, force) {
|
|
|
14280
14297
|
};
|
|
14281
14298
|
const refused = refuseNonRegular(path);
|
|
14282
14299
|
if (refused) return { item: "ci", path: rel, status: "error", detail: refused };
|
|
14283
|
-
if (!
|
|
14300
|
+
if (!existsSync8(path)) {
|
|
14284
14301
|
return {
|
|
14285
14302
|
item: "ci",
|
|
14286
14303
|
path: rel,
|
|
@@ -14291,7 +14308,7 @@ function planWorkflow(cwd, force) {
|
|
|
14291
14308
|
}
|
|
14292
14309
|
let src;
|
|
14293
14310
|
try {
|
|
14294
|
-
src =
|
|
14311
|
+
src = readFileSync8(path, "utf8");
|
|
14295
14312
|
} catch {
|
|
14296
14313
|
return { item: "ci", path: rel, status: "error", detail: "exists but cannot be read \u2014 refusing to overwrite" };
|
|
14297
14314
|
}
|
|
@@ -14638,10 +14655,10 @@ var init_fingerprint = __esm({
|
|
|
14638
14655
|
// src/dependency-env.ts
|
|
14639
14656
|
import { createHash as createHash10 } from "node:crypto";
|
|
14640
14657
|
import {
|
|
14641
|
-
existsSync as
|
|
14658
|
+
existsSync as existsSync9,
|
|
14642
14659
|
lstatSync as lstatSync9,
|
|
14643
14660
|
readdirSync as readdirSync3,
|
|
14644
|
-
readFileSync as
|
|
14661
|
+
readFileSync as readFileSync9,
|
|
14645
14662
|
readlinkSync as readlinkSync2,
|
|
14646
14663
|
realpathSync as realpathSync6,
|
|
14647
14664
|
statSync as statSync3
|
|
@@ -14699,7 +14716,7 @@ function fingerprintRoot(root, cwd, h) {
|
|
|
14699
14716
|
st = statSync3(path);
|
|
14700
14717
|
if (!st.isFile()) throw new Error("not a regular file");
|
|
14701
14718
|
h.update(label + "\0external-file\0" + path + "\0" + String(st.mode) + "\0");
|
|
14702
|
-
h.update(
|
|
14719
|
+
h.update(readFileSync9(path));
|
|
14703
14720
|
h.update("\0");
|
|
14704
14721
|
} catch (e) {
|
|
14705
14722
|
throw new Unattestable(
|
|
@@ -14733,7 +14750,7 @@ function fingerprintRoot(root, cwd, h) {
|
|
|
14733
14750
|
h.update(rel + "\0" + ident.kind + "\0" + String(ident.mode) + "\0");
|
|
14734
14751
|
if (ident.kind === "file") {
|
|
14735
14752
|
try {
|
|
14736
|
-
h.update(
|
|
14753
|
+
h.update(readFileSync9(path));
|
|
14737
14754
|
h.update("\0");
|
|
14738
14755
|
} catch (e) {
|
|
14739
14756
|
throw new Unattestable(
|
|
@@ -14792,7 +14809,7 @@ function snapshot(roots, probes, cwd) {
|
|
|
14792
14809
|
const h = createHash10("sha256");
|
|
14793
14810
|
for (const probe of probes) {
|
|
14794
14811
|
h.update(
|
|
14795
|
-
"probe\0" + probe.kind + "\0" + probe.path + "\0" + (
|
|
14812
|
+
"probe\0" + probe.kind + "\0" + probe.path + "\0" + (existsSync9(probe.path) ? "present" : "absent") + "\0"
|
|
14796
14813
|
);
|
|
14797
14814
|
}
|
|
14798
14815
|
for (const root of roots) fingerprintRoot(root, cwd, h);
|
|
@@ -14851,7 +14868,7 @@ function resolveExecutable(token, cwd, env) {
|
|
|
14851
14868
|
if (token.includes("/") || token.includes("\\")) {
|
|
14852
14869
|
const path = isAbsolute10(token) ? token : resolve7(cwd, token);
|
|
14853
14870
|
try {
|
|
14854
|
-
return
|
|
14871
|
+
return existsSync9(path) ? realpathSync6(path) : null;
|
|
14855
14872
|
} catch {
|
|
14856
14873
|
return null;
|
|
14857
14874
|
}
|
|
@@ -14859,7 +14876,7 @@ function resolveExecutable(token, cwd, env) {
|
|
|
14859
14876
|
for (const entry of (env.PATH ?? "").split(delimiter).filter(Boolean)) {
|
|
14860
14877
|
const candidate = resolve7(entry, token);
|
|
14861
14878
|
try {
|
|
14862
|
-
if (
|
|
14879
|
+
if (existsSync9(candidate) && statSync3(candidate).isFile()) return realpathSync6(candidate);
|
|
14863
14880
|
} catch {
|
|
14864
14881
|
}
|
|
14865
14882
|
}
|
|
@@ -14882,7 +14899,7 @@ function inferredVenvFromToken(token, cwd) {
|
|
|
14882
14899
|
const parentName = basename4(parent).toLowerCase();
|
|
14883
14900
|
if (parentName !== "bin" && parentName !== "scripts") return null;
|
|
14884
14901
|
const root = dirname6(parent);
|
|
14885
|
-
return
|
|
14902
|
+
return existsSync9(join16(root, "pyvenv.cfg")) ? root : null;
|
|
14886
14903
|
}
|
|
14887
14904
|
function unsupportedEcosystem(command, token) {
|
|
14888
14905
|
const name = token ? basename4(token).toLowerCase() : "";
|
|
@@ -14898,13 +14915,13 @@ function inferredVenv(executable) {
|
|
|
14898
14915
|
const parentName = basename4(parent).toLowerCase();
|
|
14899
14916
|
if (parentName !== "bin" && parentName !== "scripts") return null;
|
|
14900
14917
|
const root = dirname6(parent);
|
|
14901
|
-
return
|
|
14918
|
+
return existsSync9(join16(root, "pyvenv.cfg")) ? root : null;
|
|
14902
14919
|
}
|
|
14903
14920
|
function venvProblem(root) {
|
|
14904
14921
|
const cfg = join16(root, "pyvenv.cfg");
|
|
14905
|
-
if (!
|
|
14922
|
+
if (!existsSync9(cfg)) return "VIRTUAL_ENV " + JSON.stringify(root) + " has no pyvenv.cfg";
|
|
14906
14923
|
try {
|
|
14907
|
-
const body =
|
|
14924
|
+
const body = readFileSync9(cfg, "utf8");
|
|
14908
14925
|
if (/^\s*include-system-site-packages\s*=\s*true\s*$/im.test(body)) {
|
|
14909
14926
|
return "Python environment " + JSON.stringify(root) + " enables system site-packages; those external package roots are not bounded";
|
|
14910
14927
|
}
|
|
@@ -14929,7 +14946,7 @@ function discoverDependencyEnvironment(cwdInput, command, env = process.env) {
|
|
|
14929
14946
|
};
|
|
14930
14947
|
try {
|
|
14931
14948
|
const nodeModules = join16(cwd, "node_modules");
|
|
14932
|
-
if (
|
|
14949
|
+
if (existsSync9(nodeModules)) addRoot("node_modules", nodeModules);
|
|
14933
14950
|
else probes.push({ kind: "node_modules", path: nodeModules });
|
|
14934
14951
|
const token = firstExecutable(command);
|
|
14935
14952
|
const executable = resolveExecutable(token, cwd, env);
|
|
@@ -14941,7 +14958,7 @@ function discoverDependencyEnvironment(cwdInput, command, env = process.env) {
|
|
|
14941
14958
|
venv = resolve7(env.VIRTUAL_ENV);
|
|
14942
14959
|
} else {
|
|
14943
14960
|
venv = inferredVenv(executable) ?? inferredVenvFromToken(token, cwd);
|
|
14944
|
-
if (!venv && /(?:^|\s)uv\s+run(?:\s|$)/.test(command) &&
|
|
14961
|
+
if (!venv && /(?:^|\s)uv\s+run(?:\s|$)/.test(command) && existsSync9(join16(cwd, ".venv", "pyvenv.cfg"))) {
|
|
14945
14962
|
venv = join16(cwd, ".venv");
|
|
14946
14963
|
}
|
|
14947
14964
|
}
|
|
@@ -15420,7 +15437,7 @@ if (child) {
|
|
|
15420
15437
|
// src/verifier-backend.ts
|
|
15421
15438
|
import { createHash as createHash11, randomUUID } from "node:crypto";
|
|
15422
15439
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
15423
|
-
import { accessSync as accessSync2, constants as constants4, readFileSync as
|
|
15440
|
+
import { accessSync as accessSync2, constants as constants4, readFileSync as readFileSync10, realpathSync as realpathSync7, statSync as statSync4 } from "node:fs";
|
|
15424
15441
|
import { delimiter as delimiter2, dirname as dirname7, join as join18, resolve as resolve8 } from "node:path";
|
|
15425
15442
|
function identity() {
|
|
15426
15443
|
const uid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
@@ -15465,7 +15482,7 @@ function findExecutable(name) {
|
|
|
15465
15482
|
return null;
|
|
15466
15483
|
}
|
|
15467
15484
|
function fileSha256(path) {
|
|
15468
|
-
return createHash11("sha256").update(
|
|
15485
|
+
return createHash11("sha256").update(readFileSync10(path)).digest("hex");
|
|
15469
15486
|
}
|
|
15470
15487
|
function engineClientEnv() {
|
|
15471
15488
|
return {
|
|
@@ -15899,7 +15916,7 @@ var init_verifier_backend = __esm({
|
|
|
15899
15916
|
// src/verification-state.ts
|
|
15900
15917
|
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
15901
15918
|
import { createHash as createHash12 } from "node:crypto";
|
|
15902
|
-
import { mkdirSync as mkdirSync8, readFileSync as
|
|
15919
|
+
import { mkdirSync as mkdirSync8, readFileSync as readFileSync11, rmSync as rmSync7, writeFileSync as writeFileSync9 } from "node:fs";
|
|
15903
15920
|
import { dirname as dirname8, join as join19 } from "node:path";
|
|
15904
15921
|
function git2(args, cwd) {
|
|
15905
15922
|
return execFileSync8("git", args, {
|
|
@@ -15958,7 +15975,7 @@ function interventionWiring(cwd) {
|
|
|
15958
15975
|
return sources.map(([source, path]) => {
|
|
15959
15976
|
let parsed;
|
|
15960
15977
|
try {
|
|
15961
|
-
parsed = JSON.parse(
|
|
15978
|
+
parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
15962
15979
|
} catch {
|
|
15963
15980
|
return { source, present: false };
|
|
15964
15981
|
}
|
|
@@ -16111,7 +16128,7 @@ function readVerificationRecord(cwd) {
|
|
|
16111
16128
|
if (!path) return null;
|
|
16112
16129
|
let raw;
|
|
16113
16130
|
try {
|
|
16114
|
-
raw =
|
|
16131
|
+
raw = readFileSync11(path, "utf8");
|
|
16115
16132
|
} catch {
|
|
16116
16133
|
return null;
|
|
16117
16134
|
}
|
|
@@ -16160,7 +16177,7 @@ function readVerifyingMarker(cwd) {
|
|
|
16160
16177
|
if (!path) return null;
|
|
16161
16178
|
let parsed;
|
|
16162
16179
|
try {
|
|
16163
|
-
parsed = JSON.parse(
|
|
16180
|
+
parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
16164
16181
|
} catch {
|
|
16165
16182
|
return null;
|
|
16166
16183
|
}
|
|
@@ -16524,7 +16541,7 @@ var init_verification_receipt = __esm({
|
|
|
16524
16541
|
// src/cli/verify.ts
|
|
16525
16542
|
import { execFileSync as execFileSync9, spawnSync as spawnSync3 } from "node:child_process";
|
|
16526
16543
|
import { createHash as createHash14 } from "node:crypto";
|
|
16527
|
-
import { chmodSync as chmodSync2, cpSync, lstatSync as lstatSync10, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync3, readFileSync as
|
|
16544
|
+
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 writeFileSync11, existsSync as existsSync10 } from "node:fs";
|
|
16528
16545
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
16529
16546
|
import { dirname as dirname10, isAbsolute as isAbsolute11, join as join21, relative as relative6, resolve as resolve9, sep as sep4 } from "node:path";
|
|
16530
16547
|
function oracleAssuranceReport() {
|
|
@@ -16720,7 +16737,7 @@ function probeFilesystemCaseSensitivity(dir) {
|
|
|
16720
16737
|
const lower = join21(dir, ".tw-case-probe-a");
|
|
16721
16738
|
try {
|
|
16722
16739
|
writeFileSync11(upper, "", { flag: "wx" });
|
|
16723
|
-
return !
|
|
16740
|
+
return !existsSync10(lower);
|
|
16724
16741
|
} finally {
|
|
16725
16742
|
rmSync9(upper, { force: true });
|
|
16726
16743
|
}
|
|
@@ -16784,7 +16801,7 @@ function overlayDigest(dest, paths) {
|
|
|
16784
16801
|
try {
|
|
16785
16802
|
const st = lstatSync10(p);
|
|
16786
16803
|
h.update(String(st.mode));
|
|
16787
|
-
h.update(st.isSymbolicLink() ? readlinkSync3(p) :
|
|
16804
|
+
h.update(st.isSymbolicLink() ? readlinkSync3(p) : readFileSync12(p));
|
|
16788
16805
|
} catch {
|
|
16789
16806
|
h.update("<gone>");
|
|
16790
16807
|
}
|
|
@@ -17598,7 +17615,7 @@ var init_verify = __esm({
|
|
|
17598
17615
|
// src/cli/run.ts
|
|
17599
17616
|
import { execFileSync as execFileSync10, spawn, spawnSync as spawnSync4 } from "node:child_process";
|
|
17600
17617
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
17601
|
-
import { accessSync as accessSync3, constants as fsConstants, mkdtempSync as mkdtempSync4, readdirSync as readdirSync4, readFileSync as
|
|
17618
|
+
import { accessSync as accessSync3, constants as fsConstants, mkdtempSync as mkdtempSync4, readdirSync as readdirSync4, readFileSync as readFileSync13, readlinkSync as readlinkSync4, realpathSync as realpathSync8, rmSync as rmSync10, statSync as statSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
17602
17619
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
17603
17620
|
import { dirname as dirname11, join as join22, resolve as resolve10 } from "node:path";
|
|
17604
17621
|
function authoritativeRunLifecyclePlatform(platform = process.platform) {
|
|
@@ -17752,7 +17769,7 @@ function runAgentSupervised(argv, cwd, budgetSecs, linuxPythonCandidates, lifecy
|
|
|
17752
17769
|
}
|
|
17753
17770
|
let state = {};
|
|
17754
17771
|
try {
|
|
17755
|
-
state = JSON.parse(
|
|
17772
|
+
state = JSON.parse(readFileSync13(resultFile, "utf8"));
|
|
17756
17773
|
} catch {
|
|
17757
17774
|
return {
|
|
17758
17775
|
exit: 1,
|
|
@@ -17796,7 +17813,7 @@ function observerExited(pid) {
|
|
|
17796
17813
|
if (!pidAlive4(pid)) return true;
|
|
17797
17814
|
if (process.platform !== "linux") return false;
|
|
17798
17815
|
try {
|
|
17799
|
-
const stat =
|
|
17816
|
+
const stat = readFileSync13(`/proc/${pid}/stat`, "utf8");
|
|
17800
17817
|
const state = stat.slice(stat.lastIndexOf(")") + 2).split(" ")[0];
|
|
17801
17818
|
return state === "Z" || state === "X";
|
|
17802
17819
|
} catch (e) {
|
|
@@ -17918,7 +17935,7 @@ function git4(args, cwd) {
|
|
|
17918
17935
|
}
|
|
17919
17936
|
function nowTicks() {
|
|
17920
17937
|
try {
|
|
17921
|
-
return Math.floor(parseFloat(
|
|
17938
|
+
return Math.floor(parseFloat(readFileSync13("/proc/uptime", "utf8").split(" ")[0]) * 100);
|
|
17922
17939
|
} catch {
|
|
17923
17940
|
return Number.POSITIVE_INFINITY;
|
|
17924
17941
|
}
|
|
@@ -17941,7 +17958,7 @@ function survivorsHoldingTree(cwd, spawnedAfterTicks) {
|
|
|
17941
17958
|
const n2 = Number(pid);
|
|
17942
17959
|
if (n2 === process.pid) continue;
|
|
17943
17960
|
try {
|
|
17944
|
-
const stat =
|
|
17961
|
+
const stat = readFileSync13(`/proc/${pid}/stat`, "utf8");
|
|
17945
17962
|
const startTicks = Number(stat.slice(stat.lastIndexOf(")") + 2).split(" ")[19]);
|
|
17946
17963
|
if (!Number.isFinite(startTicks) || startTicks < spawnedAfterTicks) continue;
|
|
17947
17964
|
} catch {
|
|
@@ -18514,7 +18531,7 @@ raise SystemExit(0)
|
|
|
18514
18531
|
|
|
18515
18532
|
// src/cli/doctor.ts
|
|
18516
18533
|
import { execFileSync as execFileSync11 } from "node:child_process";
|
|
18517
|
-
import { existsSync as
|
|
18534
|
+
import { existsSync as existsSync11, readFileSync as readFileSync14, readdirSync as readdirSync5 } from "node:fs";
|
|
18518
18535
|
import { join as join23, resolve as resolve11 } from "node:path";
|
|
18519
18536
|
function lifecyclePlatformCheck(platform = process.platform, linuxPython = platform === "linux" ? trustedLinuxPython() : null) {
|
|
18520
18537
|
if (platform === "linux") {
|
|
@@ -18570,10 +18587,10 @@ function wiringState(status, authority) {
|
|
|
18570
18587
|
return authority ? "BROKEN" : "WARN";
|
|
18571
18588
|
}
|
|
18572
18589
|
function pinsInFile(path) {
|
|
18573
|
-
if (!
|
|
18590
|
+
if (!existsSync11(path)) return [];
|
|
18574
18591
|
let src = "";
|
|
18575
18592
|
try {
|
|
18576
|
-
src =
|
|
18593
|
+
src = readFileSync14(path, "utf8");
|
|
18577
18594
|
} catch {
|
|
18578
18595
|
return [];
|
|
18579
18596
|
}
|
|
@@ -18594,13 +18611,13 @@ function workflowPermissionCheck(cwd, workflowRels = [".github/workflows/tamperw
|
|
|
18594
18611
|
const warnings = [];
|
|
18595
18612
|
for (const rel of workflowRels) {
|
|
18596
18613
|
const path = resolve11(cwd, rel);
|
|
18597
|
-
if (!
|
|
18614
|
+
if (!existsSync11(path)) {
|
|
18598
18615
|
broken.push(`${rel} is missing`);
|
|
18599
18616
|
continue;
|
|
18600
18617
|
}
|
|
18601
18618
|
let doc;
|
|
18602
18619
|
try {
|
|
18603
|
-
doc = yaml.parse(
|
|
18620
|
+
doc = yaml.parse(readFileSync14(path, "utf8"));
|
|
18604
18621
|
} catch (e) {
|
|
18605
18622
|
broken.push(`${rel} is not valid YAML (${e instanceof Error ? e.message : String(e)})`);
|
|
18606
18623
|
continue;
|
|
@@ -18999,7 +19016,7 @@ function diagnose(opts = {}) {
|
|
|
18999
19016
|
} else {
|
|
19000
19017
|
const workflowDirRel = ".github/workflows";
|
|
19001
19018
|
const workflowDir = resolve11(cwd, workflowDirRel);
|
|
19002
|
-
if (!
|
|
19019
|
+
if (!existsSync11(workflowDir)) {
|
|
19003
19020
|
return fail("ci-verifier", `${workflowDirRel}: workflow directory does not exist`);
|
|
19004
19021
|
}
|
|
19005
19022
|
let entries;
|
|
@@ -19019,12 +19036,12 @@ function diagnose(opts = {}) {
|
|
|
19019
19036
|
const authorityWorkflows = [];
|
|
19020
19037
|
for (const workflowRel of workflowRels) {
|
|
19021
19038
|
const workflowPath = resolve11(cwd, workflowRel);
|
|
19022
|
-
if (!
|
|
19039
|
+
if (!existsSync11(workflowPath)) {
|
|
19023
19040
|
return fail("ci-verifier", `${workflowRel}: workflow does not exist`);
|
|
19024
19041
|
}
|
|
19025
19042
|
let doc;
|
|
19026
19043
|
try {
|
|
19027
|
-
doc = yaml.parse(
|
|
19044
|
+
doc = yaml.parse(readFileSync14(workflowPath, "utf8"));
|
|
19028
19045
|
} catch (e) {
|
|
19029
19046
|
return fail(
|
|
19030
19047
|
"ci-verifier",
|
|
@@ -19335,9 +19352,9 @@ var init_status2 = __esm({
|
|
|
19335
19352
|
// src/cli/trace-verify.ts
|
|
19336
19353
|
import { execFileSync as execFileSync12, spawnSync as spawnSync5 } from "node:child_process";
|
|
19337
19354
|
import {
|
|
19338
|
-
existsSync as
|
|
19355
|
+
existsSync as existsSync12,
|
|
19339
19356
|
mkdtempSync as mkdtempSync5,
|
|
19340
|
-
readFileSync as
|
|
19357
|
+
readFileSync as readFileSync15,
|
|
19341
19358
|
readdirSync as readdirSync6,
|
|
19342
19359
|
realpathSync as realpathSync9,
|
|
19343
19360
|
rmSync as rmSync11,
|
|
@@ -19594,7 +19611,7 @@ function materializeBase(base, cwd, dest) {
|
|
|
19594
19611
|
}
|
|
19595
19612
|
const hostModules = join24(cwd, "node_modules");
|
|
19596
19613
|
const tracedModules = join24(dest, "node_modules");
|
|
19597
|
-
if (
|
|
19614
|
+
if (existsSync12(hostModules) && !existsSync12(tracedModules)) {
|
|
19598
19615
|
symlinkSync2(resolve12(hostModules), tracedModules, "dir");
|
|
19599
19616
|
}
|
|
19600
19617
|
}
|
|
@@ -19651,7 +19668,7 @@ function straceOnce(root, command, budget) {
|
|
|
19651
19668
|
}
|
|
19652
19669
|
);
|
|
19653
19670
|
const logs = traced.error ? [] : traceFiles(prefix);
|
|
19654
|
-
const accesses = logs.flatMap((path) => parseStraceFileAccess(
|
|
19671
|
+
const accesses = logs.flatMap((path) => parseStraceFileAccess(readFileSync15(path, "utf8"), TRACE_ROOT));
|
|
19655
19672
|
const raw = {
|
|
19656
19673
|
spawnError: traced.error ? traced.error.message : null,
|
|
19657
19674
|
status: traced.status,
|
|
@@ -19906,7 +19923,7 @@ var init_immutable = __esm({
|
|
|
19906
19923
|
});
|
|
19907
19924
|
|
|
19908
19925
|
// src/runtimes.ts
|
|
19909
|
-
import { existsSync as
|
|
19926
|
+
import { existsSync as existsSync13, readFileSync as readFileSync16 } from "node:fs";
|
|
19910
19927
|
import { join as join25 } from "node:path";
|
|
19911
19928
|
function isRecord6(x) {
|
|
19912
19929
|
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
@@ -19936,8 +19953,8 @@ function claudeSettingsBeyondTamperward(cwd) {
|
|
|
19936
19953
|
const path = join25(cwd, ".claude", "settings.json");
|
|
19937
19954
|
let raw;
|
|
19938
19955
|
try {
|
|
19939
|
-
if (!
|
|
19940
|
-
raw =
|
|
19956
|
+
if (!existsSync13(path)) return false;
|
|
19957
|
+
raw = readFileSync16(path, "utf8");
|
|
19941
19958
|
} catch {
|
|
19942
19959
|
return false;
|
|
19943
19960
|
}
|
|
@@ -19963,7 +19980,7 @@ function detectRuntimes(cwd) {
|
|
|
19963
19980
|
for (const rt of KNOWN_RUNTIMES) {
|
|
19964
19981
|
const marker = rt.markers.find((m) => {
|
|
19965
19982
|
try {
|
|
19966
|
-
return
|
|
19983
|
+
return existsSync13(join25(cwd, m));
|
|
19967
19984
|
} catch {
|
|
19968
19985
|
return false;
|
|
19969
19986
|
}
|
|
@@ -20988,7 +21005,7 @@ var init_adapter3 = __esm({
|
|
|
20988
21005
|
|
|
20989
21006
|
// src/adapters/copilot-sdk/changes.ts
|
|
20990
21007
|
import { execFileSync as execFileSync13 } from "node:child_process";
|
|
20991
|
-
import { mkdtempSync as mkdtempSync6, writeFileSync as writeFileSync13, readFileSync as
|
|
21008
|
+
import { mkdtempSync as mkdtempSync6, writeFileSync as writeFileSync13, readFileSync as readFileSync17, rmSync as rmSync12, existsSync as existsSync14, realpathSync as realpathSync10 } from "node:fs";
|
|
20992
21009
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
20993
21010
|
import { basename as basename5, dirname as dirname12, isAbsolute as isAbsolute16, relative as relative11, resolve as resolve15, join as join26 } from "node:path";
|
|
20994
21011
|
function asStr4(v) {
|
|
@@ -21007,7 +21024,7 @@ function canonicalContainedTarget(abs, root) {
|
|
|
21007
21024
|
}
|
|
21008
21025
|
let dir = abs;
|
|
21009
21026
|
const tail = [];
|
|
21010
|
-
while (!
|
|
21027
|
+
while (!existsSync14(dir)) {
|
|
21011
21028
|
const parent = dirname12(dir);
|
|
21012
21029
|
if (parent === dir) break;
|
|
21013
21030
|
tail.unshift(basename5(dir));
|
|
@@ -21082,7 +21099,7 @@ function reconstructAfterViaGit(rawDiff, display2, before, isCreate) {
|
|
|
21082
21099
|
if (statPath !== TARGET) throw new Error(`write diff reconstructs a different file (${statPath}) than the bound target`);
|
|
21083
21100
|
git8(["--check"]);
|
|
21084
21101
|
git8([]);
|
|
21085
|
-
return op === "delete" ? null :
|
|
21102
|
+
return op === "delete" ? null : readFileSync17(targetPath, "utf8");
|
|
21086
21103
|
} catch (e) {
|
|
21087
21104
|
throw new Error(`could not reconstruct the write to ${display2} from its diff via git apply: ${e instanceof Error ? e.message : String(e)}`);
|
|
21088
21105
|
} finally {
|
|
@@ -21835,7 +21852,7 @@ var init_runtime_qualification = __esm({
|
|
|
21835
21852
|
|
|
21836
21853
|
// src/cli/runtime.ts
|
|
21837
21854
|
import { execFileSync as execFileSync14 } from "node:child_process";
|
|
21838
|
-
import { existsSync as
|
|
21855
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync18, writeFileSync as writeFileSync14 } from "node:fs";
|
|
21839
21856
|
import { join as join27, dirname as dirname13 } from "node:path";
|
|
21840
21857
|
function storePath(cwd) {
|
|
21841
21858
|
const dir = gitDir(cwd);
|
|
@@ -21843,9 +21860,9 @@ function storePath(cwd) {
|
|
|
21843
21860
|
}
|
|
21844
21861
|
function readStore(cwd) {
|
|
21845
21862
|
const path = storePath(cwd);
|
|
21846
|
-
if (!path || !
|
|
21863
|
+
if (!path || !existsSync15(path)) return null;
|
|
21847
21864
|
try {
|
|
21848
|
-
const parsed = JSON.parse(
|
|
21865
|
+
const parsed = JSON.parse(readFileSync18(path, "utf8"));
|
|
21849
21866
|
if (parsed && typeof parsed === "object" && parsed.records && typeof parsed.records === "object") return parsed;
|
|
21850
21867
|
} catch {
|
|
21851
21868
|
return null;
|
|
@@ -22014,9 +22031,9 @@ function resolveHookConfigHash(canonicalId, cwd) {
|
|
|
22014
22031
|
"github-copilot-cli": join27(cwd, ".github", "hooks", "tamperward.json")
|
|
22015
22032
|
};
|
|
22016
22033
|
const file = files[canonicalId];
|
|
22017
|
-
if (!file || !
|
|
22034
|
+
if (!file || !existsSync15(file)) return null;
|
|
22018
22035
|
try {
|
|
22019
|
-
const raw =
|
|
22036
|
+
const raw = readFileSync18(file, "utf8");
|
|
22020
22037
|
let hooks = raw;
|
|
22021
22038
|
try {
|
|
22022
22039
|
const parsed = JSON.parse(raw);
|
|
@@ -22295,7 +22312,7 @@ var init_runtime = __esm({
|
|
|
22295
22312
|
|
|
22296
22313
|
// src/cli/onboard.ts
|
|
22297
22314
|
import { execFileSync as execFileSync15 } from "node:child_process";
|
|
22298
|
-
import { lstatSync as lstatSync11, mkdtempSync as mkdtempSync7, readFileSync as
|
|
22315
|
+
import { lstatSync as lstatSync11, mkdtempSync as mkdtempSync7, readFileSync as readFileSync19, realpathSync as realpathSync11, rmSync as rmSync13 } from "node:fs";
|
|
22299
22316
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
22300
22317
|
import { join as join28, relative as relative12, resolve as resolve16, sep as sep6 } from "node:path";
|
|
22301
22318
|
import { createInterface } from "node:readline";
|
|
@@ -22368,7 +22385,7 @@ function writeVerifyCommand(cwd, command) {
|
|
|
22368
22385
|
return `${POLICY_FILE} is not a regular file; refusing to follow or replace a symlink or special file`;
|
|
22369
22386
|
}
|
|
22370
22387
|
const mode = existingMode(path, 420);
|
|
22371
|
-
const original = kind === "file" ?
|
|
22388
|
+
const original = kind === "file" ? readFileSync19(path, "utf8") : null;
|
|
22372
22389
|
let next;
|
|
22373
22390
|
try {
|
|
22374
22391
|
const doc = parseDocument(original && original.trim() ? original : "version: 1\n");
|
|
@@ -23023,7 +23040,7 @@ var init_capture = __esm({
|
|
|
23023
23040
|
|
|
23024
23041
|
// src/research/manifest.ts
|
|
23025
23042
|
import { createHash as createHash16 } from "node:crypto";
|
|
23026
|
-
import { readFileSync as
|
|
23043
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
23027
23044
|
import { dirname as dirname14, resolve as resolve18 } from "node:path";
|
|
23028
23045
|
function taskFrom(raw, index, manifestDir) {
|
|
23029
23046
|
const where = `task #${index + 1}`;
|
|
@@ -23057,7 +23074,7 @@ function readManifest(path) {
|
|
|
23057
23074
|
const abs = resolve18(path);
|
|
23058
23075
|
let bytes;
|
|
23059
23076
|
try {
|
|
23060
|
-
bytes =
|
|
23077
|
+
bytes = readFileSync20(abs);
|
|
23061
23078
|
} catch (e) {
|
|
23062
23079
|
throw new ResearchError(`cannot read task manifest ${abs}: ${e instanceof Error ? e.message : String(e)}`);
|
|
23063
23080
|
}
|
|
@@ -23476,7 +23493,7 @@ var init_record = __esm({
|
|
|
23476
23493
|
// src/research/run.ts
|
|
23477
23494
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
23478
23495
|
import { execFileSync as execFileSync16 } from "node:child_process";
|
|
23479
|
-
import { closeSync as closeSync5, existsSync as
|
|
23496
|
+
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 writeFileSync15, writeSync } from "node:fs";
|
|
23480
23497
|
import { hostname } from "node:os";
|
|
23481
23498
|
import { join as join29, resolve as resolve19 } from "node:path";
|
|
23482
23499
|
function git7(args, cwd) {
|
|
@@ -23490,7 +23507,7 @@ function researchLockPath(ledger) {
|
|
|
23490
23507
|
}
|
|
23491
23508
|
function readLockOwner(path) {
|
|
23492
23509
|
try {
|
|
23493
|
-
const parsed = JSON.parse(
|
|
23510
|
+
const parsed = JSON.parse(readFileSync21(path, "utf8"));
|
|
23494
23511
|
if (!isRecord(parsed) || typeof parsed.pid !== "number" || !Number.isInteger(parsed.pid) || parsed.pid <= 0) return null;
|
|
23495
23512
|
if (typeof parsed.host !== "string" || typeof parsed.started_at !== "string" || typeof parsed.token !== "string") return null;
|
|
23496
23513
|
return { pid: parsed.pid, host: parsed.host, started_at: parsed.started_at, token: parsed.token };
|
|
@@ -23513,7 +23530,7 @@ function lockHolder(path) {
|
|
|
23513
23530
|
function acquireResearchLock(ledger, breakStaleLock = false) {
|
|
23514
23531
|
mkdirSync12(ledger, { recursive: true });
|
|
23515
23532
|
const path = researchLockPath(ledger);
|
|
23516
|
-
if (breakStaleLock &&
|
|
23533
|
+
if (breakStaleLock && existsSync16(path)) {
|
|
23517
23534
|
const owner2 = readLockOwner(path);
|
|
23518
23535
|
if (!owner2) {
|
|
23519
23536
|
throw new ResearchError(`research output ${ledger} has an unreadable lock at ${path}; verify no run is active, then remove it deliberately`);
|
|
@@ -23575,7 +23592,7 @@ function acquireResearchLock(ledger, breakStaleLock = false) {
|
|
|
23575
23592
|
if (released) return;
|
|
23576
23593
|
released = true;
|
|
23577
23594
|
try {
|
|
23578
|
-
if (
|
|
23595
|
+
if (readFileSync21(path, "utf8") === text) unlinkSync(path);
|
|
23579
23596
|
} catch {
|
|
23580
23597
|
}
|
|
23581
23598
|
}
|
|
@@ -23584,7 +23601,7 @@ function acquireResearchLock(ledger, breakStaleLock = false) {
|
|
|
23584
23601
|
function resumableRecord(path, expected) {
|
|
23585
23602
|
let raw;
|
|
23586
23603
|
try {
|
|
23587
|
-
raw = JSON.parse(
|
|
23604
|
+
raw = JSON.parse(readFileSync21(path, "utf8"));
|
|
23588
23605
|
} catch (e) {
|
|
23589
23606
|
throw new ResearchError(`ledger record ${path} is malformed (${errorMessage(e).split("\n")[0]}); remove it to regenerate the pair, or use a new --out`);
|
|
23590
23607
|
}
|
|
@@ -23886,7 +23903,7 @@ function runResearch(opts) {
|
|
|
23886
23903
|
try {
|
|
23887
23904
|
for (let pair = 1; pair <= pairs; pair++) {
|
|
23888
23905
|
const path = pairRecordPath(ledger, task.id, pair);
|
|
23889
|
-
if (!
|
|
23906
|
+
if (!existsSync16(path)) continue;
|
|
23890
23907
|
const existing = resumableRecord(path, {
|
|
23891
23908
|
task: task.id,
|
|
23892
23909
|
pair,
|
|
@@ -24006,7 +24023,7 @@ var init_run2 = __esm({
|
|
|
24006
24023
|
});
|
|
24007
24024
|
|
|
24008
24025
|
// src/research/ledger-files.ts
|
|
24009
|
-
import { closeSync as closeSync6, constants as constants5, fstatSync as fstatSync3, lstatSync as lstatSync12, openSync as openSync6, readFileSync as
|
|
24026
|
+
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";
|
|
24010
24027
|
import { join as join30, resolve as resolve20 } from "node:path";
|
|
24011
24028
|
function lstatOrNull(path) {
|
|
24012
24029
|
try {
|
|
@@ -24049,7 +24066,7 @@ function readRegularFile(path, realPairsDir, name) {
|
|
|
24049
24066
|
if (!opened.isFile() || !sameInode || opened.nlink !== 1) {
|
|
24050
24067
|
throw new ResearchError(`ledger record ${path} changed between listing and reading; refusing to read it`);
|
|
24051
24068
|
}
|
|
24052
|
-
return
|
|
24069
|
+
return readFileSync22(fd);
|
|
24053
24070
|
} finally {
|
|
24054
24071
|
closeSync6(fd);
|
|
24055
24072
|
}
|
|
@@ -24222,7 +24239,7 @@ var init_summarize = __esm({
|
|
|
24222
24239
|
|
|
24223
24240
|
// src/research/init.ts
|
|
24224
24241
|
import { createHash as createHash17 } from "node:crypto";
|
|
24225
|
-
import { existsSync as
|
|
24242
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync23, writeFileSync as writeFileSync16 } from "node:fs";
|
|
24226
24243
|
import { basename as basename6, dirname as dirname15, resolve as resolve21 } from "node:path";
|
|
24227
24244
|
function idFrom(repo) {
|
|
24228
24245
|
const clean = repo.replace(/[\\/]$/, "").split(/[\\/]/).pop() || "task";
|
|
@@ -24234,7 +24251,7 @@ function createResearchManifest(opts) {
|
|
|
24234
24251
|
if (!opts.prompt) throw new ResearchError("research init requires --prompt");
|
|
24235
24252
|
if (!opts.verifyCommand) throw new ResearchError("research init requires --verify-command");
|
|
24236
24253
|
const out3 = resolve21(opts.out);
|
|
24237
|
-
if (
|
|
24254
|
+
if (existsSync17(out3)) throw new ResearchError(`research init refuses to overwrite ${out3}; choose a new path`);
|
|
24238
24255
|
const id = opts.id ?? idFrom(opts.repo);
|
|
24239
24256
|
if (!/^[A-Za-z0-9._-]+$/.test(id)) throw new ResearchError(`research init id must match [A-Za-z0-9._-] (got "${id}")`);
|
|
24240
24257
|
if (opts.verifyBudget !== void 0 && (!Number.isFinite(opts.verifyBudget) || opts.verifyBudget <= 0)) {
|
|
@@ -24274,7 +24291,7 @@ function runResearchInit(opts) {
|
|
|
24274
24291
|
}
|
|
24275
24292
|
}
|
|
24276
24293
|
function requireHash(path) {
|
|
24277
|
-
return createHash17("sha256").update(
|
|
24294
|
+
return createHash17("sha256").update(readFileSync23(path)).digest("hex");
|
|
24278
24295
|
}
|
|
24279
24296
|
var init_init2 = __esm({
|
|
24280
24297
|
"src/research/init.ts"() {
|
|
@@ -24342,7 +24359,7 @@ var init_report2 = __esm({
|
|
|
24342
24359
|
import { createHash as createHash18 } from "node:crypto";
|
|
24343
24360
|
import { isDeepStrictEqual } from "node:util";
|
|
24344
24361
|
import { gzipSync, gunzipSync } from "node:zlib";
|
|
24345
|
-
import { mkdirSync as mkdirSync14, readFileSync as
|
|
24362
|
+
import { mkdirSync as mkdirSync14, readFileSync as readFileSync24, writeFileSync as writeFileSync17 } from "node:fs";
|
|
24346
24363
|
import { dirname as dirname16, resolve as resolve22 } from "node:path";
|
|
24347
24364
|
function octal(value, width) {
|
|
24348
24365
|
return value.toString(8).padStart(width - 1, "0") + "\0";
|
|
@@ -24448,7 +24465,7 @@ function jsonBytes(value) {
|
|
|
24448
24465
|
function validateResearchBundle(path) {
|
|
24449
24466
|
let files;
|
|
24450
24467
|
try {
|
|
24451
|
-
files = parseTar(gunzipSync(
|
|
24468
|
+
files = parseTar(gunzipSync(readFileSync24(resolve22(path))));
|
|
24452
24469
|
} catch (e) {
|
|
24453
24470
|
throw new ResearchError(`cannot read research bundle ${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
24454
24471
|
}
|
|
@@ -24518,7 +24535,7 @@ function createResearchBundle(opts) {
|
|
|
24518
24535
|
const { records, entries } = packagedRecords(ledger);
|
|
24519
24536
|
const summary = summarizeRecords(records);
|
|
24520
24537
|
if (opts.manifest) {
|
|
24521
|
-
const manifest =
|
|
24538
|
+
const manifest = readFileSync24(resolve22(opts.manifest));
|
|
24522
24539
|
const sha3 = createHash18("sha256").update(manifest).digest("hex");
|
|
24523
24540
|
if (sha3 !== summary.manifest_sha256) throw new ResearchError(`manifest sha256 ${sha3} does not match ledger ${summary.manifest_sha256}`);
|
|
24524
24541
|
entries.push({ name: "manifest.json", bytes: manifest });
|
|
@@ -24689,7 +24706,7 @@ var init_research = __esm({
|
|
|
24689
24706
|
});
|
|
24690
24707
|
|
|
24691
24708
|
// src/cli/receipt.ts
|
|
24692
|
-
import { appendFileSync as appendFileSync6, readFileSync as
|
|
24709
|
+
import { appendFileSync as appendFileSync6, readFileSync as readFileSync25, writeFileSync as writeFileSync18 } from "node:fs";
|
|
24693
24710
|
function parseReceipt(args) {
|
|
24694
24711
|
const [sub, ...rest] = args;
|
|
24695
24712
|
const exportOpts = {};
|
|
@@ -24816,7 +24833,7 @@ function ciAdjudicate(cwd, opts) {
|
|
|
24816
24833
|
if (opts.ciResult !== void 0) {
|
|
24817
24834
|
let doc;
|
|
24818
24835
|
try {
|
|
24819
|
-
doc = JSON.parse(
|
|
24836
|
+
doc = JSON.parse(readFileSync25(opts.ciResult, "utf8"));
|
|
24820
24837
|
} catch (e) {
|
|
24821
24838
|
return {
|
|
24822
24839
|
ci: { verdict: "CANNOT_VERIFY", binding, binding_error: `unreadable CI verify result: ${e instanceof Error ? e.message : String(e)}` },
|
|
@@ -24962,7 +24979,7 @@ function loadClaimedReceipt(path) {
|
|
|
24962
24979
|
}
|
|
24963
24980
|
let raw;
|
|
24964
24981
|
try {
|
|
24965
|
-
raw =
|
|
24982
|
+
raw = readFileSync25(path, "utf8");
|
|
24966
24983
|
} catch (e) {
|
|
24967
24984
|
return { disposition: "MALFORMED", detail: `receipt file could not be read (${e instanceof Error ? e.message : String(e)})` };
|
|
24968
24985
|
}
|
|
@@ -25823,7 +25840,7 @@ var init_main = __esm({
|
|
|
25823
25840
|
// src/cli/index.ts
|
|
25824
25841
|
init_hook_client();
|
|
25825
25842
|
init_exit();
|
|
25826
|
-
import { readFileSync as
|
|
25843
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
25827
25844
|
function loadMain() {
|
|
25828
25845
|
return Promise.resolve().then(() => (init_main(), main_exports));
|
|
25829
25846
|
}
|
|
@@ -25836,7 +25853,7 @@ async function launch(argv) {
|
|
|
25836
25853
|
if (kind && hookServiceEnabled()) {
|
|
25837
25854
|
let raw = null;
|
|
25838
25855
|
try {
|
|
25839
|
-
raw =
|
|
25856
|
+
raw = readFileSync26(0, "utf8");
|
|
25840
25857
|
} catch {
|
|
25841
25858
|
raw = null;
|
|
25842
25859
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.39.
|
|
3
|
+
"version": "2.39.10",
|
|
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",
|