tamperward 2.29.20 → 2.30.1
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 +78 -57
- package/package.json +3 -2
package/dist/cli/index.js
CHANGED
|
@@ -10980,6 +10980,41 @@ var init_machine_output = __esm({
|
|
|
10980
10980
|
}
|
|
10981
10981
|
});
|
|
10982
10982
|
|
|
10983
|
+
// src/cli/render/status.ts
|
|
10984
|
+
function paint(s, code2, on) {
|
|
10985
|
+
return on ? code2 + s + RESET : s;
|
|
10986
|
+
}
|
|
10987
|
+
function severityColour(sev) {
|
|
10988
|
+
return TONE[sev].colour;
|
|
10989
|
+
}
|
|
10990
|
+
function statusLine(severity, label, text, colour) {
|
|
10991
|
+
const t = TONE[severity];
|
|
10992
|
+
const painted = paint(label.padEnd(STATUS_LABEL_WIDTH), (t.bold ? BOLD : "") + t.colour, colour);
|
|
10993
|
+
return `${painted} ${text}`;
|
|
10994
|
+
}
|
|
10995
|
+
var ESC, RESET, BOLD, DIM, truecolour, RED, YELLOW, GREEN, CYAN, TONE, STATUS_LABEL_WIDTH;
|
|
10996
|
+
var init_status = __esm({
|
|
10997
|
+
"src/cli/render/status.ts"() {
|
|
10998
|
+
"use strict";
|
|
10999
|
+
ESC = "\x1B";
|
|
11000
|
+
RESET = `${ESC}[0m`;
|
|
11001
|
+
BOLD = `${ESC}[1m`;
|
|
11002
|
+
DIM = `${ESC}[2m`;
|
|
11003
|
+
truecolour = (r, g, b) => `${ESC}[38;2;${r};${g};${b}m`;
|
|
11004
|
+
RED = truecolour(255, 107, 107);
|
|
11005
|
+
YELLOW = truecolour(227, 179, 65);
|
|
11006
|
+
GREEN = truecolour(63, 185, 80);
|
|
11007
|
+
CYAN = truecolour(86, 212, 221);
|
|
11008
|
+
TONE = {
|
|
11009
|
+
ok: { colour: GREEN, bold: false },
|
|
11010
|
+
warn: { colour: YELLOW, bold: false },
|
|
11011
|
+
bad: { colour: RED, bold: true },
|
|
11012
|
+
info: { colour: CYAN, bold: false }
|
|
11013
|
+
};
|
|
11014
|
+
STATUS_LABEL_WIDTH = 8;
|
|
11015
|
+
}
|
|
11016
|
+
});
|
|
11017
|
+
|
|
10983
11018
|
// src/cli/render/text.ts
|
|
10984
11019
|
function colourEnabled(env = process.env, stream = process.stdout) {
|
|
10985
11020
|
if (env.NO_COLOR !== void 0 && env.NO_COLOR !== "") return false;
|
|
@@ -10992,9 +11027,6 @@ function terminalWidth(stream = process.stdout) {
|
|
|
10992
11027
|
if (!c || c < 40) return 80;
|
|
10993
11028
|
return Math.min(c, 100);
|
|
10994
11029
|
}
|
|
10995
|
-
function paint(s, code2, on) {
|
|
10996
|
-
return on ? code2 + s + RESET : s;
|
|
10997
|
-
}
|
|
10998
11030
|
function wrap(text, width) {
|
|
10999
11031
|
const out3 = [];
|
|
11000
11032
|
let cur = "";
|
|
@@ -11080,20 +11112,12 @@ function renderText(input, opts) {
|
|
|
11080
11112
|
}
|
|
11081
11113
|
return out3.join("\n").replace(/\n+$/, "") + "\n";
|
|
11082
11114
|
}
|
|
11083
|
-
var
|
|
11115
|
+
var SIGNOFF_NOTE;
|
|
11084
11116
|
var init_text = __esm({
|
|
11085
11117
|
"src/cli/render/text.ts"() {
|
|
11086
11118
|
"use strict";
|
|
11087
11119
|
init_policy();
|
|
11088
|
-
|
|
11089
|
-
RESET = `${ESC}[0m`;
|
|
11090
|
-
BOLD = `${ESC}[1m`;
|
|
11091
|
-
DIM = `${ESC}[2m`;
|
|
11092
|
-
truecolour = (r, g, b) => `${ESC}[38;2;${r};${g};${b}m`;
|
|
11093
|
-
RED = truecolour(255, 107, 107);
|
|
11094
|
-
YELLOW = truecolour(227, 179, 65);
|
|
11095
|
-
GREEN = truecolour(63, 185, 80);
|
|
11096
|
-
CYAN = truecolour(86, 212, 221);
|
|
11120
|
+
init_status();
|
|
11097
11121
|
SIGNOFF_NOTE = "A blocking finding clears only with a human sign-off. In CI that sign-off is out-of-band \u2014 a PR label applied by a reviewer \u2014 never a file committed on the branch under review. See SPEC \xA75.4.";
|
|
11098
11122
|
}
|
|
11099
11123
|
});
|
|
@@ -12261,7 +12285,9 @@ function parseSince(value, nowMs = Date.now()) {
|
|
|
12261
12285
|
return parsed;
|
|
12262
12286
|
}
|
|
12263
12287
|
function summarizeAudit(events) {
|
|
12264
|
-
const ordered = [...events].sort(
|
|
12288
|
+
const ordered = [...events].sort(
|
|
12289
|
+
(a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp) || a.id.localeCompare(b.id)
|
|
12290
|
+
);
|
|
12265
12291
|
const rules = /* @__PURE__ */ new Map();
|
|
12266
12292
|
const surfaces = /* @__PURE__ */ new Map();
|
|
12267
12293
|
const sessions = /* @__PURE__ */ new Set();
|
|
@@ -15938,8 +15964,14 @@ function verifyVerdictLine(verdict2, ctx) {
|
|
|
15938
15964
|
}
|
|
15939
15965
|
function runVerify(opts) {
|
|
15940
15966
|
const cwd = opts.cwd ?? process.cwd();
|
|
15967
|
+
const colour = opts.silent ? false : colourEnabled(process.env, process.stdout);
|
|
15968
|
+
const paintVerify = (s) => {
|
|
15969
|
+
if (!s.startsWith("verify:")) return s;
|
|
15970
|
+
const sev = /failing closed/i.test(s) ? "bad" : "info";
|
|
15971
|
+
return paint("verify:", (sev === "bad" ? BOLD : "") + severityColour(sev), colour) + s.slice("verify:".length);
|
|
15972
|
+
};
|
|
15941
15973
|
const out3 = opts.silent ? (_s) => {
|
|
15942
|
-
} : (s) => void process.stdout.write(s + "\n");
|
|
15974
|
+
} : (s) => void process.stdout.write(paintVerify(s) + "\n");
|
|
15943
15975
|
let filesystemCaseSensitive;
|
|
15944
15976
|
const caseReport = () => filesystemCaseSensitive === void 0 ? {} : { filesystem_case_sensitive: filesystemCaseSensitive };
|
|
15945
15977
|
const cannotVerify = (reason, detail, extra = {}) => {
|
|
@@ -16372,6 +16404,8 @@ var init_verify = __esm({
|
|
|
16372
16404
|
init_machine_output();
|
|
16373
16405
|
init_signoff();
|
|
16374
16406
|
init_suite_diagnostics();
|
|
16407
|
+
init_text();
|
|
16408
|
+
init_status();
|
|
16375
16409
|
OVERLAY_CLASSES = ["tests", "snapshots", "config"];
|
|
16376
16410
|
VERIFICATION_SURFACE = [
|
|
16377
16411
|
// Python / pytest — read from the rootdir, and conftest at any depth
|
|
@@ -17624,12 +17658,15 @@ function emitReport(opts, checks, authoritative) {
|
|
|
17624
17658
|
process.stdout.write(JSON.stringify(report2) + "\n");
|
|
17625
17659
|
return;
|
|
17626
17660
|
}
|
|
17661
|
+
const colour = colourEnabled(process.env, process.stdout);
|
|
17627
17662
|
for (const check2 of checks) {
|
|
17628
17663
|
if (check2.id === "observer") {
|
|
17629
17664
|
process.stdout.write(`tamperward doctor: transient observer: ${check2.detail}
|
|
17630
17665
|
`);
|
|
17631
17666
|
} else {
|
|
17632
|
-
|
|
17667
|
+
const sev = check2.state === "OK" ? "ok" : check2.state === "WARN" ? "warn" : check2.state === "BROKEN" ? "bad" : "info";
|
|
17668
|
+
const tag = paint(`[${check2.state}]`, (sev === "bad" ? BOLD : "") + severityColour(sev), colour);
|
|
17669
|
+
process.stdout.write(`tamperward doctor: ${tag} ${check2.id} \u2014 ${check2.detail}
|
|
17633
17670
|
`);
|
|
17634
17671
|
}
|
|
17635
17672
|
}
|
|
@@ -18019,6 +18056,8 @@ var init_doctor = __esm({
|
|
|
18019
18056
|
init_machine_output();
|
|
18020
18057
|
init_narrow();
|
|
18021
18058
|
init_repo_context();
|
|
18059
|
+
init_text();
|
|
18060
|
+
init_status();
|
|
18022
18061
|
VERIFY_COMMAND = /\btamperward(?:@\S+)?\s+verify\b/;
|
|
18023
18062
|
REPOSITORY_REQUIRED_CHECKS = [
|
|
18024
18063
|
"typecheck",
|
|
@@ -18663,9 +18702,6 @@ function readlineAsker(input, output) {
|
|
|
18663
18702
|
};
|
|
18664
18703
|
return ask;
|
|
18665
18704
|
}
|
|
18666
|
-
function paint2(text, code2, on) {
|
|
18667
|
-
return on ? code2 + text + RESET2 : text;
|
|
18668
|
-
}
|
|
18669
18705
|
function terminalText(text) {
|
|
18670
18706
|
return stripControl(text).replace(/\s+/g, " ").trim();
|
|
18671
18707
|
}
|
|
@@ -18731,9 +18767,9 @@ function writeVerifyCommand(cwd, command) {
|
|
|
18731
18767
|
}
|
|
18732
18768
|
async function runOnboard(opts, io = {}) {
|
|
18733
18769
|
const requestedCwd = resolve12(opts.cwd ?? process.cwd());
|
|
18734
|
-
const out3 = io.out ?? ((
|
|
18735
|
-
const errLine = (
|
|
18736
|
-
const rawErr = (
|
|
18770
|
+
const out3 = io.out ?? ((line2) => void process.stdout.write(line2 + "\n"));
|
|
18771
|
+
const errLine = (line2) => void process.stderr.write(line2 + "\n");
|
|
18772
|
+
const rawErr = (line2) => errLine(terminalText(line2));
|
|
18737
18773
|
const platform = io.platform ?? process.platform;
|
|
18738
18774
|
const colour = io.colour ?? colourEnabled(process.env, process.stdout);
|
|
18739
18775
|
const runners = {
|
|
@@ -18745,18 +18781,12 @@ async function runOnboard(opts, io = {}) {
|
|
|
18745
18781
|
};
|
|
18746
18782
|
const interactive = io.interactive ?? (Boolean(process.stdin.isTTY) && !process.env.CI && !process.env.GITHUB_ACTIONS);
|
|
18747
18783
|
const scripted = Boolean(opts.yes);
|
|
18748
|
-
const
|
|
18749
|
-
if (kind === "ok") return GREEN2;
|
|
18750
|
-
if (kind === "warn") return YELLOW2;
|
|
18751
|
-
if (kind === "bad") return RED2;
|
|
18752
|
-
if (kind === "info") return CYAN2;
|
|
18753
|
-
return DIM2;
|
|
18754
|
-
};
|
|
18784
|
+
const line = (label, text, kind) => kind === "dim" ? paint(label.padEnd(8), DIM, colour) + " " + terminalText(text) : statusLine(kind, label, terminalText(text), colour);
|
|
18755
18785
|
const status = (label, text, kind = "info") => {
|
|
18756
|
-
out3(
|
|
18786
|
+
out3(line(label, text, kind));
|
|
18757
18787
|
};
|
|
18758
18788
|
const errStatus = (label, text, kind = "info") => {
|
|
18759
|
-
errLine(
|
|
18789
|
+
errLine(line(label, text, kind));
|
|
18760
18790
|
};
|
|
18761
18791
|
const fail = (text) => errStatus("ERROR", text, "bad");
|
|
18762
18792
|
if (!interactive && !scripted) {
|
|
@@ -18806,7 +18836,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
18806
18836
|
const section = (n) => {
|
|
18807
18837
|
sectionNo = n;
|
|
18808
18838
|
out3("");
|
|
18809
|
-
out3(
|
|
18839
|
+
out3(paint(n + "/" + SECTIONS.length + " " + SECTIONS[n - 1], BOLD + CYAN, colour));
|
|
18810
18840
|
};
|
|
18811
18841
|
const wrote = [];
|
|
18812
18842
|
let verifyCommand;
|
|
@@ -18816,9 +18846,9 @@ async function runOnboard(opts, io = {}) {
|
|
|
18816
18846
|
let declined = false;
|
|
18817
18847
|
let doctorOutcome = null;
|
|
18818
18848
|
try {
|
|
18819
|
-
out3(
|
|
18820
|
-
out3(
|
|
18821
|
-
out3(
|
|
18849
|
+
out3(paint("TamperWard onboarding", BOLD, colour));
|
|
18850
|
+
out3(paint("v" + TW_VERSION + " \xB7 Node " + process.versions.node + " \xB7 " + platformLabel(platform) + "/" + process.arch, DIM, colour));
|
|
18851
|
+
out3(paint(terminalText(cwd), DIM, colour));
|
|
18822
18852
|
section(1);
|
|
18823
18853
|
const lifecycle = lifecyclePlatformCheck(platform);
|
|
18824
18854
|
const localVerifySupported = localVerifierShell(platform, "true") !== null;
|
|
@@ -18831,7 +18861,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
18831
18861
|
}
|
|
18832
18862
|
const head = git5(cwd, ["rev-parse", "--verify", "--quiet", "HEAD^{commit}"])?.trim() ?? null;
|
|
18833
18863
|
const treeStatus = git5(cwd, ["status", "--porcelain", "--untracked-files=all"]) ?? "";
|
|
18834
|
-
const dirty = treeStatus.split("\n").filter(Boolean).map((
|
|
18864
|
+
const dirty = treeStatus.split("\n").filter(Boolean).map((line2) => line2.slice(3).split(" -> ").at(-1) ?? "");
|
|
18835
18865
|
if (!head) {
|
|
18836
18866
|
const count = dirty.length;
|
|
18837
18867
|
status(
|
|
@@ -18953,7 +18983,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
18953
18983
|
}
|
|
18954
18984
|
if (!verifyCommand) {
|
|
18955
18985
|
status("ACTION", "Verification is not configured; CI will fail closed until it is.", "warn");
|
|
18956
|
-
out3(
|
|
18986
|
+
out3(paint(' Set it later with: tamperward onboard --verify-command "<suite command>"', DIM, colour));
|
|
18957
18987
|
} else if (!localVerifySupported) {
|
|
18958
18988
|
status("LIMITED", "Local verification is unavailable on " + platformLabel(platform) + "; use a digest-pinned container verifier.", "warn");
|
|
18959
18989
|
} else if (!head) {
|
|
@@ -18979,7 +19009,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
18979
19009
|
status("SKIP", "Safe demo becomes available after the first commit.", "dim");
|
|
18980
19010
|
} else {
|
|
18981
19011
|
const wanted = scripted ? Boolean(opts.demo) : opts.demo ? true : await confirm("Run the optional safe tamper demo? (temporary worktree only)", false, false);
|
|
18982
|
-
if (wanted) runDemo(cwd, head, runners, (
|
|
19012
|
+
if (wanted) runDemo(cwd, head, runners, (line2) => out3(terminalText(line2)));
|
|
18983
19013
|
}
|
|
18984
19014
|
}
|
|
18985
19015
|
section(4);
|
|
@@ -19027,14 +19057,14 @@ async function runOnboard(opts, io = {}) {
|
|
|
19027
19057
|
status("OK", "GitHub authority enforced for " + doctorOutcome.github.repo + "#" + doctorOutcome.github.branch + ".", "ok");
|
|
19028
19058
|
} else if (!repo) {
|
|
19029
19059
|
status("ACTION", "GitHub authority is not configured for this repository.", "warn");
|
|
19030
|
-
out3(
|
|
19031
|
-
out3(
|
|
19032
|
-
for (const
|
|
19060
|
+
out3(paint(" If GitHub will provide repository authority, run: " + terminalText(doctorCommand), DIM, colour));
|
|
19061
|
+
out3(paint(" If this repository will use GitHub CI authority, configure:", DIM, colour));
|
|
19062
|
+
for (const line2 of MANUAL_CONTROLS) out3(paint(" " + line2, DIM, colour));
|
|
19033
19063
|
} else {
|
|
19034
19064
|
status("ACTION", "GitHub authority is not verified yet.", "warn");
|
|
19035
|
-
out3(
|
|
19036
|
-
out3(
|
|
19037
|
-
for (const
|
|
19065
|
+
out3(paint(" " + terminalText(doctorCommand), DIM, colour));
|
|
19066
|
+
out3(paint(" GitHub authority requires all three controls:", DIM, colour));
|
|
19067
|
+
for (const line2 of MANUAL_CONTROLS) out3(paint(" " + line2, DIM, colour));
|
|
19038
19068
|
}
|
|
19039
19069
|
const commitPaths = [...new Set(wrote)].filter((path) => committableSetupPath(cwd, path));
|
|
19040
19070
|
if (commitPaths.length) {
|
|
@@ -19049,7 +19079,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
19049
19079
|
if (verifyResult) {
|
|
19050
19080
|
status("VERIFY", verifyResult.summary?.verdict ?? "exit " + verifyResult.code, verifyResult.code === 0 ? "ok" : "warn");
|
|
19051
19081
|
}
|
|
19052
|
-
out3(
|
|
19082
|
+
out3(paint(" Daily: tamperward check --worktree \xB7 tamperward verify --base <base>", DIM, colour));
|
|
19053
19083
|
return posture === "READY" || posture === "READY WITH WARNINGS" ? 0 : 1;
|
|
19054
19084
|
} catch (e) {
|
|
19055
19085
|
if (e instanceof Aborted) {
|
|
@@ -19067,9 +19097,7 @@ async function runOnboard(opts, io = {}) {
|
|
|
19067
19097
|
}
|
|
19068
19098
|
function renderCheck(check2, out3, colour) {
|
|
19069
19099
|
const broken = check2.state === "BROKEN";
|
|
19070
|
-
|
|
19071
|
-
const code2 = broken ? BOLD2 + RED2 : YELLOW2;
|
|
19072
|
-
out3(paint2(label.padEnd(8), code2, colour) + " " + terminalText(check2.id + " \u2014 " + check2.detail));
|
|
19100
|
+
out3(statusLine(broken ? "bad" : "warn", broken ? "ERROR" : "WARN", terminalText(check2.id + " \u2014 " + check2.detail), colour));
|
|
19073
19101
|
}
|
|
19074
19102
|
function postureOf(outcome) {
|
|
19075
19103
|
if (outcome.failure) return "INCOMPLETE";
|
|
@@ -19148,7 +19176,7 @@ function runDemo(cwd, head, runners, out3) {
|
|
|
19148
19176
|
out3("changed it while the demo ran; inspect with `git status`.");
|
|
19149
19177
|
}
|
|
19150
19178
|
}
|
|
19151
|
-
var Aborted, SECTIONS, MANUAL_CONTROLS,
|
|
19179
|
+
var Aborted, SECTIONS, MANUAL_CONTROLS, JS_TEST_PATH, JS_TEST_BLOCK;
|
|
19152
19180
|
var init_onboard = __esm({
|
|
19153
19181
|
"src/cli/onboard.ts"() {
|
|
19154
19182
|
"use strict";
|
|
@@ -19157,6 +19185,7 @@ var init_onboard = __esm({
|
|
|
19157
19185
|
init_doctor();
|
|
19158
19186
|
init_check();
|
|
19159
19187
|
init_text();
|
|
19188
|
+
init_status();
|
|
19160
19189
|
init_fingerprint();
|
|
19161
19190
|
init_policy();
|
|
19162
19191
|
init_policy_load();
|
|
@@ -19178,14 +19207,6 @@ var init_onboard = __esm({
|
|
|
19178
19207
|
"Code Owner review",
|
|
19179
19208
|
"dismiss stale approvals when new commits are pushed"
|
|
19180
19209
|
];
|
|
19181
|
-
ESC2 = "\x1B";
|
|
19182
|
-
RESET2 = `${ESC2}[0m`;
|
|
19183
|
-
BOLD2 = `${ESC2}[1m`;
|
|
19184
|
-
DIM2 = `${ESC2}[2m`;
|
|
19185
|
-
RED2 = `${ESC2}[31m`;
|
|
19186
|
-
YELLOW2 = `${ESC2}[33m`;
|
|
19187
|
-
GREEN2 = `${ESC2}[32m`;
|
|
19188
|
-
CYAN2 = `${ESC2}[36m`;
|
|
19189
19210
|
JS_TEST_PATH = /(?:^|\/)(?:[^/]+\.(?:test|spec)\.[cm]?[jt]sx?|__tests__\/[^/]+\.[cm]?[jt]sx?)$/;
|
|
19190
19211
|
JS_TEST_BLOCK = /^(\s*)(it|test|describe)(\s*\()/m;
|
|
19191
19212
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.30.1",
|
|
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",
|
|
@@ -47,7 +47,8 @@
|
|
|
47
47
|
"test": "vitest run",
|
|
48
48
|
"test:watch": "vitest",
|
|
49
49
|
"test:perf-smoke": "vitest run --config vitest.perf-smoke.config.ts --no-file-parallelism",
|
|
50
|
-
"check": "node dist/cli/index.js check"
|
|
50
|
+
"check": "node dist/cli/index.js check",
|
|
51
|
+
"probe:codex-runtime": "node harness/adapters/codex-probe.mjs"
|
|
51
52
|
},
|
|
52
53
|
"dependencies": {
|
|
53
54
|
"picomatch": "^4.0.2",
|