tamperward 2.23.2 → 2.23.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli/index.js +75 -13
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -9934,7 +9934,7 @@ var init_verifier_limits = __esm({
9934
9934
  // src/cli/init.ts
9935
9935
  import { execFileSync as execFileSync6 } from "node:child_process";
9936
9936
  import { createHash as createHash6 } from "node:crypto";
9937
- import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync7, chmodSync as chmodSync2, statSync as statSync2 } from "node:fs";
9937
+ import { existsSync as existsSync10, lstatSync as lstatSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync7, chmodSync as chmodSync2, statSync as statSync2 } from "node:fs";
9938
9938
  import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute8, join as join14, relative as relative3, resolve as resolve3 } from "node:path";
9939
9939
  function gitConfig(cwd, key2) {
9940
9940
  try {
@@ -10112,6 +10112,65 @@ function planPolicy(cwd) {
10112
10112
  apply: () => writeFileSync7(path, POLICY_CONTENT)
10113
10113
  };
10114
10114
  }
10115
+ function planGitignore(cwd) {
10116
+ const rel = ".gitignore";
10117
+ const path = join14(cwd, rel);
10118
+ if (!existsSync10(join14(cwd, "node_modules"))) return null;
10119
+ let existing = "";
10120
+ if (existsSync10(path)) {
10121
+ let st;
10122
+ try {
10123
+ st = lstatSync7(path);
10124
+ } catch (e) {
10125
+ return { item: "gitignore", path: rel, status: "error", detail: "cannot inspect \u2014 " + errText3(e) };
10126
+ }
10127
+ if (!st.isFile()) {
10128
+ return {
10129
+ item: "gitignore",
10130
+ path: rel,
10131
+ status: "error",
10132
+ detail: st.isSymbolicLink() ? "is a symbolic link \u2014 refusing to follow it" : "exists but is not a regular file \u2014 refusing to write"
10133
+ };
10134
+ }
10135
+ existing = readFileSync12(path, "utf8");
10136
+ }
10137
+ try {
10138
+ const tracked = execFileSync6("git", ["ls-files", "--cached", "--", "node_modules"], {
10139
+ cwd,
10140
+ encoding: "utf8",
10141
+ stdio: ["ignore", "pipe", "pipe"]
10142
+ }).trim();
10143
+ if (tracked) {
10144
+ return {
10145
+ item: "gitignore",
10146
+ path: rel,
10147
+ status: "skip",
10148
+ detail: "node_modules is already tracked/staged \u2014 left unchanged; TamperWard will scan it as repository content"
10149
+ };
10150
+ }
10151
+ } catch {
10152
+ }
10153
+ const meaningful = existing.split(/\r?\n/).map((line) => line.trim()).filter((line) => line !== "" && !line.startsWith("#"));
10154
+ if (meaningful.some((line) => line.startsWith("!") && line.includes("node_modules"))) {
10155
+ return {
10156
+ item: "gitignore",
10157
+ path: rel,
10158
+ status: "skip",
10159
+ detail: "contains an explicit node_modules negation \u2014 left untouched; review the repository ignore policy before committing dependencies"
10160
+ };
10161
+ }
10162
+ if (meaningful.some((line) => /^(?:\/|\*\*\/)?node_modules\/?$/.test(line))) {
10163
+ return { item: "gitignore", path: rel, status: "ok", detail: "node_modules is already ignored by the repository" };
10164
+ }
10165
+ const next = existing.length === 0 ? "node_modules/\n" : existing.replace(/\n?$/, "\n") + "node_modules/\n";
10166
+ return {
10167
+ item: "gitignore",
10168
+ path: rel,
10169
+ status: existsSync10(path) ? "update" : "create",
10170
+ detail: "exclude installed Node dependencies from repository diffs",
10171
+ apply: () => writeFileSync7(path, next)
10172
+ };
10173
+ }
10115
10174
  function planClaudeHooks(cwd) {
10116
10175
  const rel = ".claude/settings.json";
10117
10176
  const path = join14(cwd, rel);
@@ -10425,8 +10484,10 @@ function planned(item, path, plan) {
10425
10484
  }
10426
10485
  function planInit(cwd, opts = {}) {
10427
10486
  requireShippedVersion();
10487
+ const gitignore = planGitignore(cwd);
10428
10488
  return [
10429
10489
  planned("policy", POLICY_FILE, () => planPolicy(cwd)),
10490
+ ...gitignore ? [gitignore] : [],
10430
10491
  planned("agent", ".claude/settings.json", () => planClaudeHooks(cwd)),
10431
10492
  planned("pre-commit", "(hooks)", () => planPreCommit(cwd)),
10432
10493
  planned("ci", ".github/workflows/tamperward.yml", () => planWorkflow(cwd, opts.forceWorkflow ?? false)),
@@ -10660,7 +10721,7 @@ var init_fingerprint = __esm({
10660
10721
  import { createHash as createHash8 } from "node:crypto";
10661
10722
  import {
10662
10723
  existsSync as existsSync11,
10663
- lstatSync as lstatSync7,
10724
+ lstatSync as lstatSync8,
10664
10725
  readdirSync as readdirSync3,
10665
10726
  readFileSync as readFileSync13,
10666
10727
  readlinkSync as readlinkSync2,
@@ -10685,7 +10746,7 @@ function inside(root, candidate) {
10685
10746
  return rel === "" || rel !== ".." && !rel.startsWith(".." + sep2) && !isAbsolute9(rel);
10686
10747
  }
10687
10748
  function modeKind(path) {
10688
- const st = lstatSync7(path);
10749
+ const st = lstatSync8(path);
10689
10750
  if (st.isFile()) return { kind: "file", mode: st.mode };
10690
10751
  if (st.isDirectory()) return { kind: "dir", mode: st.mode };
10691
10752
  if (st.isSymbolicLink()) return { kind: "symlink", mode: st.mode };
@@ -10695,7 +10756,7 @@ function fingerprintRoot(root, cwd, h) {
10695
10756
  let rootStat;
10696
10757
  let currentReal;
10697
10758
  try {
10698
- rootStat = lstatSync7(root.path);
10759
+ rootStat = lstatSync8(root.path);
10699
10760
  currentReal = realpathSync4(root.path);
10700
10761
  } catch (e) {
10701
10762
  throw new Unattestable(
@@ -11865,7 +11926,7 @@ var init_verifier_backend = __esm({
11865
11926
  // src/cli/verify.ts
11866
11927
  import { execFileSync as execFileSync8, spawnSync as spawnSync3 } from "node:child_process";
11867
11928
  import { createHash as createHash10 } from "node:crypto";
11868
- import { chmodSync as chmodSync3, cpSync, lstatSync as lstatSync8, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, readFileSync as readFileSync16, readlinkSync as readlinkSync3, rmSync as rmSync5, symlinkSync, writeFileSync as writeFileSync9 } from "node:fs";
11929
+ import { chmodSync as chmodSync3, cpSync, lstatSync as lstatSync9, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, readFileSync as readFileSync16, readlinkSync as readlinkSync3, rmSync as rmSync5, symlinkSync, writeFileSync as writeFileSync9 } from "node:fs";
11869
11930
  import { tmpdir as tmpdir4 } from "node:os";
11870
11931
  import { dirname as dirname7, isAbsolute as isAbsolute10, join as join18, relative as relative5, resolve as resolve6, sep as sep3 } from "node:path";
11871
11932
  function oracleAssuranceReport() {
@@ -11938,7 +11999,7 @@ function validateSymlinkGraph(target, out3, root, dependencyRoot, label) {
11938
11999
  const current = join18(base, ...stack);
11939
12000
  let st;
11940
12001
  try {
11941
- st = lstatSync8(current);
12002
+ st = lstatSync9(current);
11942
12003
  } catch {
11943
12004
  continue;
11944
12005
  }
@@ -11974,7 +12035,7 @@ function rejectLinkedParent(cwd, rel) {
11974
12035
  current = join18(current, part);
11975
12036
  let st;
11976
12037
  try {
11977
- st = lstatSync8(current);
12038
+ st = lstatSync9(current);
11978
12039
  } catch {
11979
12040
  continue;
11980
12041
  }
@@ -11991,7 +12052,7 @@ function materialize(cwd, dest, dependencyRoot) {
11991
12052
  rejectLinkedParent(cwd, rel);
11992
12053
  let st;
11993
12054
  try {
11994
- st = lstatSync8(src);
12055
+ st = lstatSync9(src);
11995
12056
  } catch {
11996
12057
  continue;
11997
12058
  }
@@ -12016,7 +12077,7 @@ function materialize(cwd, dest, dependencyRoot) {
12016
12077
  }
12017
12078
  function dropSymlink(p) {
12018
12079
  try {
12019
- if (lstatSync8(p).isSymbolicLink()) rmSync5(p, { force: true });
12080
+ if (lstatSync9(p).isSymbolicLink()) rmSync5(p, { force: true });
12020
12081
  } catch {
12021
12082
  }
12022
12083
  }
@@ -12058,7 +12119,7 @@ function overlayDigest(dest, paths) {
12058
12119
  h.update("\0");
12059
12120
  const p = join18(dest, rel);
12060
12121
  try {
12061
- const st = lstatSync8(p);
12122
+ const st = lstatSync9(p);
12062
12123
  h.update(String(st.mode));
12063
12124
  h.update(st.isSymbolicLink() ? readlinkSync3(p) : readFileSync16(p));
12064
12125
  } catch {
@@ -14619,7 +14680,7 @@ var init_trace_verify = __esm({
14619
14680
  // src/cli/onboard.ts
14620
14681
  import { execFileSync as execFileSync12 } from "node:child_process";
14621
14682
  import { randomBytes as randomBytes2 } from "node:crypto";
14622
- import { lstatSync as lstatSync9, mkdtempSync as mkdtempSync6, readFileSync as readFileSync20, realpathSync as realpathSync9, renameSync as renameSync2, rmSync as rmSync8, writeFileSync as writeFileSync11 } from "node:fs";
14683
+ import { lstatSync as lstatSync10, mkdtempSync as mkdtempSync6, readFileSync as readFileSync20, realpathSync as realpathSync9, renameSync as renameSync2, rmSync as rmSync8, writeFileSync as writeFileSync11 } from "node:fs";
14623
14684
  import { tmpdir as tmpdir7 } from "node:os";
14624
14685
  import { join as join22, relative as relative7, resolve as resolve10, sep as sep5 } from "node:path";
14625
14686
  import { createInterface } from "node:readline";
@@ -14699,7 +14760,7 @@ function atomicReplaceFile(path, content, mode) {
14699
14760
  }
14700
14761
  function writeVerifyCommand(cwd, command) {
14701
14762
  const path = join22(cwd, POLICY_FILE);
14702
- const st = lstatSync9(path, { throwIfNoEntry: false });
14763
+ const st = lstatSync10(path, { throwIfNoEntry: false });
14703
14764
  if (st && (!st.isFile() || st.isSymbolicLink())) {
14704
14765
  return `${POLICY_FILE} is not a regular file; refusing to follow or replace a symlink or special file`;
14705
14766
  }
@@ -14846,6 +14907,7 @@ async function runOnboard(opts, io = {}) {
14846
14907
  const plan = planInit(cwd);
14847
14908
  const names = {
14848
14909
  policy: "Policy",
14910
+ gitignore: "Git ignore",
14849
14911
  agent: "Claude hooks",
14850
14912
  "pre-commit": "Pre-commit",
14851
14913
  ci: "CI workflow",
@@ -15090,7 +15152,7 @@ function runDemo(cwd, head, runners, out3) {
15090
15152
  return;
15091
15153
  }
15092
15154
  const targetPath = join22(wt, target.path);
15093
- const targetStat = lstatSync9(targetPath, { throwIfNoEntry: false });
15155
+ const targetStat = lstatSync10(targetPath, { throwIfNoEntry: false });
15094
15156
  if (!targetStat || !targetStat.isFile() || targetStat.isSymbolicLink()) {
15095
15157
  out3("Demo skipped: the selected test is not a regular file in the disposable worktree.");
15096
15158
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamperward",
3
- "version": "2.23.2",
3
+ "version": "2.23.3",
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",