memento-mori-jester 0.1.102 → 0.1.103

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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to Memento Mori Jester are tracked here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.1.103
8
+
9
+ - Added `npm run pack:contents:check` to verify dry-run package contents include the support examples index, quickstart, lifecycle map, blank worksheet, and filled synthetic example.
10
+ - Wired `pack:dry` and `npm test` through the package contents smoke so release dry runs also exclude repo-local promo, site, private, cache, GitHub workflow, and credential-shaped files.
11
+ - Updated README, release docs, production-readiness docs, roadmap, and release notes for the package surface guard.
12
+
7
13
  ## 0.1.102
8
14
 
9
15
  - Added a checked public-safe support examples quickstart for a 60-second maintainer handoff from incoming report to lifecycle map, blank worksheet, filled synthetic example, backlog record, and backlog review.
package/README.md CHANGED
@@ -555,6 +555,7 @@ Run `npm run support:check` after editing issue templates, support docs, the rep
555
555
  Run `npm run promo:card` to regenerate the repo-local social preview card after changing its copy or design.
556
556
  Run `npm run promo:check` after editing promo assets; it checks the current demo video, stills, docs, and fixture evidence numbers stay in sync.
557
557
  Run `npm run site:check` after editing the repo-local landing page; it verifies the start command, demo links, social card, repo, release, and npm links.
558
+ Run `npm run pack:contents:check` when package contents change; it verifies the dry-run package includes the support examples index, quickstart, lifecycle map, blank worksheet, and filled synthetic example, while excluding repo-local promo, site, private, cache, and credential-shaped files.
558
559
 
559
560
  For vulnerabilities, private code exposure, or credential-handling concerns, follow [SECURITY.md](SECURITY.md) instead of opening a public issue with sensitive details.
560
561
 
@@ -568,6 +569,7 @@ npm.cmd run consumer:quickstart:check
568
569
  npm.cmd run reports:check
569
570
  npm.cmd run promo:check
570
571
  npm.cmd run production:check
572
+ npm.cmd run pack:contents:check
571
573
  npm.cmd run pack:dry
572
574
  git tag -a v0.1.x -m "Memento Mori Jester v0.1.x"
573
575
  git push origin main
package/ROADMAP.md CHANGED
@@ -6,6 +6,7 @@ Memento Mori Jester is usable today as a CLI, MCP server, GitHub Action, and git
6
6
 
7
7
  ## Recently Shipped
8
8
 
9
+ - Checked package contents support manifest smoke in v0.1.103, proving dry-run packages include the support examples index, quickstart, lifecycle map, blank worksheet, and filled synthetic example while excluding repo-local/private-ish files.
9
10
  - Checked support examples quickstart in v0.1.102, giving maintainers a 60-second handoff path from incoming report to map, worksheet, synthetic example, backlog record, and backlog review.
10
11
  - Checked support examples index in v0.1.101, telling maintainers when to use the lifecycle map, blank worksheet, and filled synthetic example.
11
12
  - Checked filled support lifecycle worksheet example in v0.1.100, showing a synthetic `docs-example` report through report, triage, response, closeout, prioritization, backlog record, and backlog review.
@@ -9,6 +9,7 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
9
9
  - GitHub Releases and npm publishing are automated from annotated `v*` tags through GitHub Actions trusted publishing.
10
10
  - CI runs tests and a package dry run on every push to `main` and pull request.
11
11
  - The local playground, GitHub Action, MCP setup snippets, preset examples, fixtures, and release notes ship in the npm package.
12
+ - Package dry runs include a support examples manifest smoke so the index, quickstart, lifecycle map, blank worksheet, and filled synthetic example keep shipping from the tarball.
12
13
  - Repo-local promo assets stay outside the npm package, but `npm run promo:check` keeps the current demo video, stills, social card, docs, and fixture evidence numbers aligned.
13
14
  - The repo-local landing page stays outside the npm package, but `npm run site:check` keeps its start command and public links aligned.
14
15
 
@@ -16,7 +17,8 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
16
17
 
17
18
  - `package.json` includes repository, homepage, bugs, binaries, exports, public package files, and public publish access.
18
19
  - `package-lock.json` version matches `package.json`.
19
- - `npm run pack:dry` confirms the package includes `dist`, `docs`, `examples`, `scripts`, `README.md`, `CHANGELOG.md`, `ROADMAP.md`, and `LICENSE`.
20
+ - `npm run pack:dry` confirms the package includes `dist`, `docs`, `examples`, `scripts`, `README.md`, `CHANGELOG.md`, `ROADMAP.md`, and `LICENSE`, then runs `npm run pack:contents:check`.
21
+ - `npm run pack:contents:check` verifies the dry-run package includes the support examples index, quickstart, lifecycle map, blank worksheet, and filled synthetic example, and excludes repo-local promo, site, private, cache, GitHub workflow, and credential-shaped files.
20
22
  - `SECURITY.md` ships with the package so vulnerability reporting guidance is visible from the repository and npm tarball.
21
23
  - `prepublishOnly` runs tests and a package dry run for local publish attempts.
22
24
 
@@ -70,6 +72,7 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
70
72
  - `npm run support:check` verifies issue templates, support docs, the report gallery feedback template, support examples quickstart, support examples index, support lifecycle map, support lifecycle worksheet, filled worksheet example, support lifecycle overview, outcome prioritization guide, backlog records, backlog review checklist, maintainer triage playbook, response snippets, and closeout checklist stay public-safe and ask for useful redacted context.
71
73
  - `npm run promo:card` regenerates the deterministic social preview card, and `npm run promo:check` verifies current repo-local promo assets against the current fixture evidence before maintainers post or refresh the demo.
72
74
  - `npm run site:check` verifies the static landing page before maintainers post or host it.
75
+ - `npm run pack:contents:check` verifies the npm package surface keeps the support examples manifest files available while excluding repo-only or private-ish paths.
73
76
  - npm publish has a manual workflow fallback, but the normal release path is tag-driven trusted publishing.
74
77
 
75
78
  ## Static Guard
@@ -93,6 +96,7 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
93
96
  - support triage checks are wired into `npm test`.
94
97
  - promo freshness checks are wired into `npm test`.
95
98
  - site checks are wired into `npm test`.
99
+ - package contents checks are wired into `npm test` and `npm run pack:dry`.
96
100
 
97
101
  `npm test` runs this check after the TypeScript build and unit tests.
98
102
 
package/docs/RELEASE.md CHANGED
@@ -21,6 +21,7 @@ npm.cmd run support:check
21
21
  npm.cmd run promo:card:check
22
22
  npm.cmd run promo:check
23
23
  npm.cmd run site:check
24
+ npm.cmd run pack:contents:check
24
25
  npm.cmd run pack:dry
25
26
  git diff --check
26
27
  ```
@@ -89,6 +90,7 @@ npx.cmd -y memento-mori-jester@latest config validate --config jester-security.c
89
90
  npm.cmd run consumer:quickstart:check -- --package memento-mori-jester@latest
90
91
  npm.cmd run reports:check -- --package memento-mori-jester@latest
91
92
  npm.cmd run support:check
93
+ npm.cmd run pack:contents:check
92
94
  ```
93
95
 
94
96
  ## 4. MCP Copy-Paste
@@ -0,0 +1,45 @@
1
+ # Memento Mori Jester v0.1.103
2
+
3
+ ## Summary
4
+
5
+ This release adds a checked package contents smoke so maintainers can prove the npm package surface still ships the support examples index, quickstart, lifecycle map, blank worksheet, and filled synthetic example while keeping repo-local/private-ish files out.
6
+
7
+ ## Changes
8
+
9
+ - Added `scripts/check-package-contents.mjs`.
10
+ - Added `npm run pack:contents:check`.
11
+ - Updated `npm run pack:dry` so the normal dry-pack path also verifies package contents.
12
+ - Wired the package contents check into `npm test` and `npm run production:check`.
13
+ - Updated README, release docs, production-readiness docs, roadmap, and changelog.
14
+
15
+ ## Public Interface Changes
16
+
17
+ - No CLI, MCP, config schema, rule, scoring, GitHub Action, or release automation changes.
18
+ - New maintainer script:
19
+ - `npm run pack:contents:check`
20
+
21
+ ## Release Validation
22
+
23
+ ```powershell
24
+ npm.cmd test
25
+ npm.cmd run demo:svg:check
26
+ npm.cmd run promo:card:check
27
+ npm.cmd run promo:check
28
+ npm.cmd run support:check
29
+ npm.cmd run production:check
30
+ npm.cmd run pack:contents:check
31
+ npm.cmd run pack:dry
32
+ git diff --check
33
+ node .\dist\cli.js doctor
34
+ node .\dist\cli.js summary --kind command "git reset --hard"
35
+ git diff | node .\dist\cli.js diff --fail-on block --subject "v0.1.103 package contents support manifest smoke"
36
+ ```
37
+
38
+ ## Post-Publish Smoke
39
+
40
+ ```powershell
41
+ npm.cmd view memento-mori-jester version --silent
42
+ npx.cmd -y memento-mori-jester@latest doctor
43
+ npx.cmd -y memento-mori-jester@latest summary --kind command "git reset --hard"
44
+ npm.cmd run pack:contents:check
45
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memento-mori-jester",
3
- "version": "0.1.102",
3
+ "version": "0.1.103",
4
4
  "description": "A local court-jester sidecar for AI coding agents: review plans, commands, diffs, and final claims before they get too pleased with themselves.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -40,7 +40,7 @@
40
40
  "build": "tsc -p tsconfig.json",
41
41
  "start": "node dist/server.js",
42
42
  "start:mcp": "node dist/server.js",
43
- "test": "npm run build && node scripts/run-tests.mjs && npm run fixtures:check && npm run fixtures:report && npm run framework:tuning:check && npm run framework:tuning:doctor && npm run ci:adoption:check && npm run consumer:quickstart:check && npm run reports:check && npm run support:check && npm run promo:check && npm run site:check && npm run production:check",
43
+ "test": "npm run build && node scripts/run-tests.mjs && npm run fixtures:check && npm run fixtures:report && npm run framework:tuning:check && npm run framework:tuning:doctor && npm run ci:adoption:check && npm run consumer:quickstart:check && npm run reports:check && npm run support:check && npm run promo:check && npm run site:check && npm run pack:contents:check && npm run production:check",
44
44
  "doctor": "node dist/cli.js doctor",
45
45
  "demo:svg": "node scripts/render-demo-svg.mjs",
46
46
  "demo:svg:check": "node scripts/render-demo-svg.mjs --check",
@@ -57,7 +57,8 @@
57
57
  "promo:check": "node scripts/check-promo-freshness.mjs",
58
58
  "site:check": "node scripts/check-site.mjs",
59
59
  "production:check": "node scripts/check-production-readiness.mjs",
60
- "pack:dry": "npm pack --dry-run",
60
+ "pack:contents:check": "node scripts/check-package-contents.mjs",
61
+ "pack:dry": "npm pack --dry-run && npm run pack:contents:check",
61
62
  "prepare": "npm run build",
62
63
  "prepublishOnly": "npm test && npm run pack:dry"
63
64
  },
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { spawnSync } from "node:child_process";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
8
+ const root = join(scriptDir, "..");
9
+ const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm";
10
+ const npmExecPath = process.env.npm_execpath;
11
+ const failures = [];
12
+ const packageJson = readJson("package.json");
13
+
14
+ const requiredPackageFiles = [
15
+ "dist/cli.js",
16
+ "dist/core.js",
17
+ "docs/RELEASE.md",
18
+ `docs/RELEASE_NOTES_v${packageJson.version}.md`,
19
+ "examples/support/support-examples-index.md",
20
+ "examples/support/support-examples-index.json",
21
+ "examples/support/support-examples-quickstart.md",
22
+ "examples/support/support-examples-quickstart.json",
23
+ "examples/support/support-lifecycle-map.md",
24
+ "examples/support/support-lifecycle-map.json",
25
+ "examples/support/support-lifecycle-worksheet.md",
26
+ "examples/support/support-lifecycle-worksheet.json",
27
+ "examples/support/support-lifecycle-filled-example.md",
28
+ "examples/support/support-lifecycle-filled-example.json",
29
+ "README.md",
30
+ "CHANGELOG.md",
31
+ "ROADMAP.md",
32
+ "SECURITY.md",
33
+ "LICENSE"
34
+ ];
35
+
36
+ const requiredSupportFiles = [
37
+ "examples/support/support-examples-index.md",
38
+ "examples/support/support-examples-index.json",
39
+ "examples/support/support-examples-quickstart.md",
40
+ "examples/support/support-examples-quickstart.json",
41
+ "examples/support/support-lifecycle-map.md",
42
+ "examples/support/support-lifecycle-map.json",
43
+ "examples/support/support-lifecycle-worksheet.md",
44
+ "examples/support/support-lifecycle-worksheet.json",
45
+ "examples/support/support-lifecycle-filled-example.md",
46
+ "examples/support/support-lifecycle-filled-example.json"
47
+ ];
48
+
49
+ const forbiddenPackagePathRules = [
50
+ { name: "repo-local promo assets", pattern: /^promo\// },
51
+ { name: "repo-local site assets", pattern: /^site\// },
52
+ { name: "GitHub workflow or issue-template files", pattern: /^\.github\// },
53
+ { name: "git metadata", pattern: /^\.git(?:\/|$)/ },
54
+ { name: "dependency or generated caches", pattern: /(^|\/)(?:node_modules|coverage|tmp|temp|\.next|dist-debug)(?:\/|$)/ },
55
+ { name: "private or secret-named directories", pattern: /(^|\/)(?:private|secrets?|internal)(?:\/|$)/i },
56
+ { name: "environment or credential files", pattern: /(^|\/)(?:\.env(?:\..*)?|\.npmrc|npm-debug\.log|yarn-error\.log|pnpm-debug\.log|.*\.(?:pem|p12|key))$/i }
57
+ ];
58
+
59
+ const unsafeContentPatterns = [
60
+ { name: "private key block", pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----/ },
61
+ { name: "OpenAI-looking secret key", pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\b/ },
62
+ { name: "Anthropic-looking secret key", pattern: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/ },
63
+ { name: "GitHub-looking token", pattern: /\bgh[pousr]_[A-Za-z0-9_]{20,}\b/ },
64
+ { name: "AWS access key id", pattern: /\bAKIA[0-9A-Z]{16}\b/ },
65
+ { name: "Slack-looking token", pattern: /\bxox[baprs]-[A-Za-z0-9-]{20,}\b/ },
66
+ { name: "absolute Unix home path", pattern: /(?:^|[\s"'`])\/(?:Users|home)\/[A-Za-z0-9._-]+/ },
67
+ { name: "absolute Windows user path", pattern: /[A-Za-z]:\\Users\\[A-Za-z0-9._-]+\\/ }
68
+ ];
69
+
70
+ const pack = dryRunPack();
71
+ const files = new Set(pack.files.map((file) => normalizePath(file.path)));
72
+
73
+ if (pack.name !== packageJson.name) {
74
+ failures.push(`Dry-run package name should be ${packageJson.name}. Saw ${pack.name}.`);
75
+ }
76
+
77
+ if (pack.version !== packageJson.version) {
78
+ failures.push(`Dry-run package version should be ${packageJson.version}. Saw ${pack.version}.`);
79
+ }
80
+
81
+ for (const file of requiredPackageFiles) {
82
+ if (!files.has(file)) {
83
+ failures.push(`Package dry run should include ${file}.`);
84
+ }
85
+ }
86
+
87
+ for (const file of pack.files) {
88
+ const path = normalizePath(file.path);
89
+ for (const rule of forbiddenPackagePathRules) {
90
+ if (rule.pattern.test(path)) {
91
+ failures.push(`Package dry run should exclude ${rule.name}: ${path}.`);
92
+ }
93
+ }
94
+ }
95
+
96
+ for (const path of requiredSupportFiles) {
97
+ requireFile(path);
98
+ if (!existsSync(join(root, path))) {
99
+ continue;
100
+ }
101
+
102
+ const content = read(path);
103
+ for (const unsafe of unsafeContentPatterns) {
104
+ if (unsafe.pattern.test(content)) {
105
+ failures.push(`${path} appears to contain ${unsafe.name}; package support examples must stay public-safe.`);
106
+ }
107
+ }
108
+ }
109
+
110
+ if (failures.length > 0) {
111
+ console.error("Package contents check failed:");
112
+ for (const failure of failures) {
113
+ console.error(`- ${failure}`);
114
+ }
115
+ process.exit(1);
116
+ }
117
+
118
+ console.log("Package contents check passed.");
119
+ console.log(`PASS package ${pack.name}@${pack.version}`);
120
+ console.log(`PASS support examples included: ${requiredSupportFiles.length} files`);
121
+ console.log("PASS promo, site, GitHub workflow, cache, private, and credential-shaped files excluded");
122
+
123
+ function dryRunPack() {
124
+ const output = runNpm(["pack", "--dry-run", "--json", "--ignore-scripts"]);
125
+ const parsed = parsePackJson(output);
126
+ if (!Array.isArray(parsed) || parsed.length !== 1 || typeof parsed[0] !== "object") {
127
+ fail("npm pack --dry-run --json should return one package entry.");
128
+ }
129
+
130
+ const [pack] = parsed;
131
+ if (!Array.isArray(pack.files)) {
132
+ fail("npm pack --dry-run --json output should include a files array.");
133
+ }
134
+
135
+ return pack;
136
+ }
137
+
138
+ function parsePackJson(output) {
139
+ const trimmed = output.trim();
140
+ if (!trimmed) {
141
+ fail("npm pack --dry-run --json returned no output.");
142
+ }
143
+
144
+ try {
145
+ return JSON.parse(trimmed);
146
+ } catch {
147
+ const start = trimmed.indexOf("[");
148
+ const end = trimmed.lastIndexOf("]");
149
+ if (start >= 0 && end > start) {
150
+ return JSON.parse(trimmed.slice(start, end + 1));
151
+ }
152
+ fail(`Could not parse npm pack JSON output:\n${trimmed}`);
153
+ }
154
+ }
155
+
156
+ function read(path) {
157
+ return readFileSync(join(root, path), "utf8");
158
+ }
159
+
160
+ function readJson(path) {
161
+ return JSON.parse(read(path));
162
+ }
163
+
164
+ function requireFile(path) {
165
+ if (!existsSync(join(root, path))) {
166
+ failures.push(`${path} is missing.`);
167
+ }
168
+ }
169
+
170
+ function normalizePath(path) {
171
+ return path.replaceAll("\\", "/");
172
+ }
173
+
174
+ function runNpm(commandArgs) {
175
+ if (npmExecPath) {
176
+ return run(process.execPath, [npmExecPath, ...commandArgs]);
177
+ }
178
+
179
+ return run(npmCommand, commandArgs);
180
+ }
181
+
182
+ function run(command, commandArgs) {
183
+ const result = spawnSync(command, commandArgs, {
184
+ cwd: root,
185
+ encoding: "utf8",
186
+ maxBuffer: 20 * 1024 * 1024,
187
+ env: {
188
+ ...process.env,
189
+ npm_config_audit: "false",
190
+ npm_config_fund: "false"
191
+ }
192
+ });
193
+
194
+ if (result.error) {
195
+ throw result.error;
196
+ }
197
+
198
+ if (result.status !== 0) {
199
+ const detail = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
200
+ fail(`${command} ${commandArgs.join(" ")} failed${detail ? `:\n${detail}` : "."}`);
201
+ }
202
+
203
+ return result.stdout;
204
+ }
205
+
206
+ function fail(message) {
207
+ throw new Error(message);
208
+ }
@@ -72,6 +72,7 @@ for (const path of [
72
72
  "scripts/doctor-framework-tuning.mjs",
73
73
  "scripts/check-ci-adoption.mjs",
74
74
  "scripts/check-consumer-quickstart.mjs",
75
+ "scripts/check-package-contents.mjs",
75
76
  "scripts/check-report-gallery.mjs",
76
77
  "scripts/check-support-triage.mjs",
77
78
  "scripts/check-fixtures.mjs",
@@ -157,6 +158,7 @@ requireText("README.md", /support-lifecycle\.md/, "support lifecycle overview li
157
158
  requireText("README.md", /outcome-prioritization\.md/, "support outcome prioritization link");
158
159
  requireText("README.md", /backlog-review\.md/, "support backlog review link");
159
160
  requireText("README.md", /backlog-records\.md/, "support backlog records link");
161
+ requireText("README.md", /pack:contents:check/, "package contents check guidance");
160
162
  requireText("README.md", /report gallery feedback/i, "report gallery feedback guidance");
161
163
  requireText("README.md", /License: PolyForm Noncommercial/, "the noncommercial license badge");
162
164
  requireText("docs/PRODUCTION_READINESS.md", /npm package/i, "npm package readiness");
@@ -189,6 +191,8 @@ requireText("docs/PRODUCTION_READINESS.md", /filled worksheet example/i, "filled
189
191
  requireText("docs/PRODUCTION_READINESS.md", /outcome prioritization guide/i, "support outcome prioritization readiness");
190
192
  requireText("docs/PRODUCTION_READINESS.md", /backlog review/i, "support backlog review readiness");
191
193
  requireText("docs/PRODUCTION_READINESS.md", /backlog records/i, "support backlog records readiness");
194
+ requireText("docs/PRODUCTION_READINESS.md", /pack:contents:check/, "package contents check readiness");
195
+ requireText("docs/PRODUCTION_READINESS.md", /support examples manifest/i, "support examples manifest package readiness");
192
196
  requireText("docs/PRODUCTION_READINESS.md", /quiet-pass/, "quiet-pass fixture readiness");
193
197
  requireText("docs/CLI.md", /jester doctor --json/, "doctor JSON CLI docs");
194
198
  requireText("docs/CLI.md", /quiet-pass fixture/, "quiet-pass fixture CLI docs");
@@ -434,6 +438,12 @@ requireText("scripts/check-ci-adoption.mjs", /framework:tuning:doctor/, "adoptio
434
438
  requireText("scripts/check-consumer-quickstart.mjs", /consumer-quickstart/, "consumer quickstart checker target");
435
439
  requireText("scripts/check-consumer-quickstart.mjs", /memento-mori-jester@latest/, "consumer quickstart registry verification option");
436
440
  requireText("scripts/check-consumer-quickstart.mjs", /framework:tuning:doctor/, "consumer quickstart tuning doctor guard");
441
+ requireText("scripts/check-package-contents.mjs", /support-examples-index\.md/, "package contents support examples index guard");
442
+ requireText("scripts/check-package-contents.mjs", /support-examples-quickstart\.md/, "package contents support examples quickstart guard");
443
+ requireText("scripts/check-package-contents.mjs", /support-lifecycle-map\.md/, "package contents support lifecycle map guard");
444
+ requireText("scripts/check-package-contents.mjs", /support-lifecycle-worksheet\.md/, "package contents support lifecycle worksheet guard");
445
+ requireText("scripts/check-package-contents.mjs", /support-lifecycle-filled-example\.md/, "package contents filled worksheet example guard");
446
+ requireText("scripts/check-package-contents.mjs", /promo|site|private|credential/, "package contents forbidden file guard");
437
447
  requireText("scripts/check-report-gallery.mjs", /report-gallery\.json/, "report gallery checker target");
438
448
  requireText("scripts/check-report-gallery.mjs", /memento-mori-jester@latest/, "report gallery registry verification option");
439
449
  requireText("scripts/check-report-gallery.mjs", /destructive-command-summary/, "report gallery summary guard");
@@ -460,6 +470,8 @@ requireText("package.json", /"ci:adoption:check": "node scripts\/check-ci-adopti
460
470
  requireText("package.json", /"consumer:quickstart:check": "node scripts\/check-consumer-quickstart\.mjs"/, "consumer quickstart check script");
461
471
  requireText("package.json", /"reports:check": "node scripts\/check-report-gallery\.mjs"/, "report gallery check script");
462
472
  requireText("package.json", /"support:check": "node scripts\/check-support-triage\.mjs"/, "support triage check script");
473
+ requireText("package.json", /"pack:contents:check": "node scripts\/check-package-contents\.mjs"/, "package contents check script");
474
+ requireText("package.json", /"pack:dry": "npm pack --dry-run && npm run pack:contents:check"/, "package dry run contents guard");
463
475
  requireText("package.json", /"promo:card": "node scripts\/render-social-card\.mjs"/, "social card render script");
464
476
  requireText("package.json", /"promo:card:check": "node scripts\/render-social-card\.mjs --check"/, "social card stale check script");
465
477
  requireText("package.json", /"promo:check": "node scripts\/check-promo-freshness\.mjs"/, "promo freshness check script");
@@ -474,6 +486,7 @@ requireText("package.json", /npm run reports:check/, "report gallery check in np
474
486
  requireText("package.json", /npm run support:check/, "support triage check in npm test");
475
487
  requireText("package.json", /npm run promo:check/, "promo freshness check in npm test");
476
488
  requireText("package.json", /npm run site:check/, "site check in npm test");
489
+ requireText("package.json", /npm run pack:contents:check/, "package contents check in npm test");
477
490
  requireText("scripts/check-promo-freshness.mjs", /--require-package-version/, "optional strict package-version promo check");
478
491
  requireText("scripts/check-promo-freshness.mjs", /social-card\.svg/, "social-card freshness check");
479
492
  requireText("scripts/check-site.mjs", /site\/index\.html/, "site index check");