memento-mori-jester 0.1.85 → 0.1.87

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,17 @@ All notable changes to Memento Mori Jester are tracked here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.1.87
8
+
9
+ - Fixed `npm run consumer:quickstart:check -- --package memento-mori-jester@latest` so registry package specs install through `npm install --save-dev <spec>` in the temporary consumer project.
10
+ - Verified both local packed-package and published-package consumer quickstart smoke modes after the v0.1.86 release.
11
+
12
+ ## 0.1.86
13
+
14
+ - Added `examples/consumer-quickstart`, a minimal installed-project fixture for proving the first `doctor`, `summary`, and framework tuning commands from a consumer repo.
15
+ - Added `npm run consumer:quickstart:check`, which installs the package into a temporary project and runs the quickstart/adoption commands from that project.
16
+ - Updated README, GitHub Actions docs, CI examples, release docs, production-readiness docs, roadmap, and release notes for the consumer quickstart smoke path.
17
+
7
18
  ## 0.1.85
8
19
 
9
20
  - Added `examples/ci/adoption-smoke.yml`, a read-only GitHub Actions recipe for checking `doctor`, `summary`, and packaged framework tuning cookbook commands in real repos.
package/README.md CHANGED
@@ -70,6 +70,8 @@ The generated workflow uploads SARIF for code scanning and adds a readable Jeste
70
70
 
71
71
  For a first read-only CI smoke, copy [examples/ci/adoption-smoke.yml](examples/ci/adoption-smoke.yml). It runs `doctor`, `summary --kind command "git reset --hard"`, and the published package's `framework:tuning:doctor` without requiring code-scanning permissions.
72
72
 
73
+ Maintainers can prove that fresh-project path with [examples/consumer-quickstart](examples/consumer-quickstart) and `npm run consumer:quickstart:check`, which installs the package into a temporary project and runs the same quickstart commands from there.
74
+
73
75
  Expected vibe:
74
76
 
75
77
  ```text
@@ -439,6 +441,7 @@ More setup examples:
439
441
  - [Review Fixtures](examples/fixtures)
440
442
  - [Framework CI Examples](examples/ci)
441
443
  - [Adoption Smoke CI](examples/ci/adoption-smoke.yml)
444
+ - [Consumer Quickstart Smoke](examples/consumer-quickstart)
442
445
  - [Security Policy](SECURITY.md)
443
446
  - [Maintainer Triage](docs/MAINTAINER_TRIAGE.md)
444
447
  - [Changelog](CHANGELOG.md)
@@ -457,6 +460,7 @@ Preset example packs:
457
460
  Framework CI examples:
458
461
 
459
462
  - [Adoption Smoke CI](examples/ci/adoption-smoke.yml)
463
+ - [Consumer Quickstart Smoke](examples/consumer-quickstart)
460
464
  - [Next.js CI](examples/ci/nextjs.yml)
461
465
  - [Vite React CI](examples/ci/vite-react.yml)
462
466
  - [Express API CI](examples/ci/express-api.yml)
@@ -524,6 +528,7 @@ Release checklist:
524
528
 
525
529
  ```powershell
526
530
  npm.cmd test
531
+ npm.cmd run consumer:quickstart:check
527
532
  npm.cmd run promo:check
528
533
  npm.cmd run production:check
529
534
  npm.cmd run pack:dry
package/ROADMAP.md CHANGED
@@ -6,6 +6,8 @@ Memento Mori Jester is usable today as a CLI, MCP server, GitHub Action, and git
6
6
 
7
7
  ## Recently Shipped
8
8
 
9
+ - Consumer quickstart registry-mode fix in v0.1.87, proving the same smoke against `memento-mori-jester@latest` after publish.
10
+ - Consumer quickstart smoke in v0.1.86, proving the first installed-project commands from a minimal repo before release.
9
11
  - Adoption smoke CI example in v0.1.85, giving real repos a read-only workflow for `doctor`, `summary`, and packaged framework tuning checks.
10
12
  - Framework tuning doctor in v0.1.84, proving cookbook recipes execute through the built CLI with generated preset configs before release.
11
13
  - Framework tuning cookbook in v0.1.83, adding checked copy-paste recipes and a machine-readable JSON map for stack-shaped noisy-rule reports.
@@ -35,6 +35,8 @@ npm run framework:tuning:doctor
35
35
 
36
36
  The workflow downloads the published npm tarball into a temporary directory before running the framework tuning checks, so it verifies package contents rather than relying on this repository checkout.
37
37
 
38
+ Maintainers can run `npm run consumer:quickstart:check` to prove the same commands from a minimal installed project fixture in [examples/consumer-quickstart](../examples/consumer-quickstart). After a release, `npm run consumer:quickstart:check -- --package memento-mori-jester@latest` verifies the public registry package through that fixture.
39
+
38
40
  ## Composite Action
39
41
 
40
42
  This repo can be used directly as a GitHub Action:
@@ -27,6 +27,7 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
27
27
  - SARIF output and GitHub step summaries remain separate so users can enable readable summaries without new GitHub write permissions.
28
28
  - Example workflows in `examples/` and `examples/ci/` stay aligned with the action shape.
29
29
  - `examples/ci/adoption-smoke.yml` gives new repos a read-only smoke workflow for `doctor`, `summary`, and packaged framework tuning checks before code scanning is enabled.
30
+ - `examples/consumer-quickstart` gives maintainers a minimal installed-project fixture for proving those same first commands from a clean consumer project.
30
31
 
31
32
  ## MCP And Agent Setup
32
33
 
@@ -61,6 +62,7 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
61
62
  - `npm run fixtures:report` shows fixture coverage by rule, rule family, preset slice, kind, verdict, quiet-pass rule boundaries, and feasible pass-case gaps so maintainers can pick the next fixture target; `npm run fixtures:report -- --markdown` produces a paste-ready maintainer snapshot.
62
63
  - `npm run framework:tuning:check` keeps the framework tuning guide, cookbook JSON, cookbook README, and fixture IDs aligned.
63
64
  - `npm run framework:tuning:doctor` runs the cookbook tune commands through the built CLI with temporary preset configs, so package consumers do not inherit stale recipes.
65
+ - `npm run consumer:quickstart:check` installs the package into a temporary minimal project and runs `doctor`, `summary`, and packaged framework tuning checks from that consumer side.
64
66
  - `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.
65
67
  - `npm run site:check` verifies the static landing page before maintainers post or host it.
66
68
  - npm publish has a manual workflow fallback, but the normal release path is tag-driven trusted publishing.
@@ -81,6 +83,7 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
81
83
  - framework tuning cookbook checks are wired into `npm test`.
82
84
  - framework tuning cookbook doctor checks are wired into `npm test`.
83
85
  - CI adoption example checks are wired into `npm test`.
86
+ - consumer quickstart smoke checks are wired into `npm test`.
84
87
  - promo freshness checks are wired into `npm test`.
85
88
  - site checks are wired into `npm test`.
86
89
 
package/docs/RELEASE.md CHANGED
@@ -15,6 +15,7 @@ npm.cmd run fixtures:report -- --markdown
15
15
  npm.cmd run framework:tuning:check
16
16
  npm.cmd run framework:tuning:doctor
17
17
  npm.cmd run ci:adoption:check
18
+ npm.cmd run consumer:quickstart:check
18
19
  npm.cmd run promo:card:check
19
20
  npm.cmd run promo:check
20
21
  npm.cmd run site:check
@@ -27,7 +28,7 @@ Move the current changelog bullets into a matching version section and add `docs
27
28
  ## 2. Tag And Push
28
29
 
29
30
  ```powershell
30
- git add package.json package-lock.json CHANGELOG.md docs/RELEASE_NOTES_v0.1.x.md docs/PRODUCTION_READINESS.md docs/MAINTAINER_TRIAGE.md docs/FRAMEWORK_TUNING.md docs/GITHUB_ACTIONS.md examples/ci examples/tuning scripts/check-ci-adoption.mjs scripts/check-framework-tuning.mjs scripts/doctor-framework-tuning.mjs SECURITY.md .github/ISSUE_TEMPLATE
31
+ git add package.json package-lock.json CHANGELOG.md docs/RELEASE_NOTES_v0.1.x.md docs/PRODUCTION_READINESS.md docs/MAINTAINER_TRIAGE.md docs/FRAMEWORK_TUNING.md docs/GITHUB_ACTIONS.md examples/ci examples/consumer-quickstart examples/tuning scripts/check-ci-adoption.mjs scripts/check-consumer-quickstart.mjs scripts/check-framework-tuning.mjs scripts/doctor-framework-tuning.mjs SECURITY.md .github/ISSUE_TEMPLATE
31
32
  git commit -m "Release v0.1.x"
32
33
  git tag -a v0.1.x -m "Memento Mori Jester v0.1.x"
33
34
  git push origin main
@@ -83,6 +84,7 @@ npx.cmd -y memento-mori-jester@latest config init --preset ai --path jester-ai.c
83
84
  npx.cmd -y memento-mori-jester@latest config validate --config jester-ai.config.json
84
85
  npx.cmd -y memento-mori-jester@latest config init --preset security --path jester-security.config.json
85
86
  npx.cmd -y memento-mori-jester@latest config validate --config jester-security.config.json
87
+ npm.cmd run consumer:quickstart:check -- --package memento-mori-jester@latest
86
88
  ```
87
89
 
88
90
  ## 4. MCP Copy-Paste
@@ -0,0 +1,64 @@
1
+ # Memento Mori Jester v0.1.86
2
+
3
+ ## Summary
4
+
5
+ This release adds a minimal consumer-project smoke path. The adoption CI example already proves copied workflow commands from GitHub Actions; this release proves the same first commands after installing the package into a clean temporary project.
6
+
7
+ ## What Changed
8
+
9
+ - Added `examples/consumer-quickstart/package.json`.
10
+ - Added `examples/consumer-quickstart/README.md`.
11
+ - Added `scripts/check-consumer-quickstart.mjs`.
12
+ - Added `npm run consumer:quickstart:check`.
13
+ - Wired the consumer quickstart checker into `npm test` and production-readiness checks.
14
+ - Updated README, GitHub Actions docs, CI example docs, release docs, production-readiness docs, roadmap, and changelog.
15
+
16
+ ## Public Interface
17
+
18
+ - No CLI command changes.
19
+ - No MCP tool changes.
20
+ - No config schema changes.
21
+ - No review rule, scoring, matching, or verdict behavior changes.
22
+ - No GitHub Action input changes.
23
+ - New maintainer/package script: `npm run consumer:quickstart:check`.
24
+ - New checked example fixture: `examples/consumer-quickstart`.
25
+
26
+ ## Release Validation
27
+
28
+ ```powershell
29
+ npm.cmd test
30
+ npm.cmd run demo:svg:check
31
+ npm.cmd run promo:card:check
32
+ npm.cmd run promo:check
33
+ npm.cmd run framework:tuning:check
34
+ npm.cmd run framework:tuning:doctor
35
+ npm.cmd run ci:adoption:check
36
+ npm.cmd run consumer:quickstart:check
37
+ npm.cmd run fixtures:report
38
+ npm.cmd run fixtures:report -- --json
39
+ npm.cmd run fixtures:report -- --markdown
40
+ npm.cmd run site:check
41
+ npm.cmd run pack:dry
42
+ git diff --check
43
+ node .\dist\cli.js summary --kind command "git reset --hard"
44
+ node .\dist\cli.js tune coverage --no-config
45
+ git diff | node .\dist\cli.js diff --fail-on block --subject "v0.1.86 consumer quickstart smoke"
46
+ ```
47
+
48
+ Expected:
49
+
50
+ - `consumer:quickstart:check` installs the package into a temporary minimal project,
51
+ - `jester:doctor` passes from that project,
52
+ - `jester:summary` blocks `git reset --hard` from that project,
53
+ - packaged `framework:tuning:check` and `framework:tuning:doctor` pass from the installed dependency,
54
+ - fixture report still shows `Fixtures: 222`,
55
+ - GitHub Release and npm Publish complete from the `v0.1.86` tag.
56
+
57
+ After publish:
58
+
59
+ ```powershell
60
+ npm.cmd view memento-mori-jester version --silent
61
+ npx.cmd -y memento-mori-jester@latest doctor
62
+ npx.cmd -y memento-mori-jester@latest summary --kind command "git reset --hard"
63
+ npm.cmd run consumer:quickstart:check -- --package memento-mori-jester@latest
64
+ ```
@@ -0,0 +1,44 @@
1
+ # Memento Mori Jester v0.1.87
2
+
3
+ ## Summary
4
+
5
+ This patch fixes the new consumer quickstart check's registry-package mode. The v0.1.86 local packed-package smoke passed, but the post-publish `--package memento-mori-jester@latest` smoke exposed that full npm specs were being written as dependency versions.
6
+
7
+ ## What Changed
8
+
9
+ - Updated `scripts/check-consumer-quickstart.mjs` to install package specs with `npm install --save-dev <spec>`.
10
+ - Kept the same minimal consumer fixture and command checks.
11
+ - Updated changelog, roadmap, and release notes for the patch.
12
+
13
+ ## Public Interface
14
+
15
+ - No CLI command changes.
16
+ - No MCP tool changes.
17
+ - No config schema changes.
18
+ - No review rule, scoring, matching, or verdict behavior changes.
19
+ - No GitHub Action input changes.
20
+ - Maintainer script behavior fix only: `npm run consumer:quickstart:check -- --package memento-mori-jester@latest` now works.
21
+
22
+ ## Release Validation
23
+
24
+ ```powershell
25
+ npm.cmd test
26
+ npm.cmd run consumer:quickstart:check
27
+ npm.cmd run consumer:quickstart:check -- --package memento-mori-jester@latest
28
+ npm.cmd run pack:dry
29
+ git diff --check
30
+ git diff | node .\dist\cli.js diff --fail-on block --subject "v0.1.87 consumer quickstart registry smoke"
31
+ ```
32
+
33
+ Expected:
34
+
35
+ - local packed-package consumer quickstart smoke passes,
36
+ - registry-spec consumer quickstart smoke passes,
37
+ - GitHub Release and npm Publish complete from the `v0.1.87` tag.
38
+
39
+ After publish:
40
+
41
+ ```powershell
42
+ npm.cmd view memento-mori-jester version --silent
43
+ npm.cmd run consumer:quickstart:check -- --package memento-mori-jester@latest
44
+ ```
@@ -19,9 +19,12 @@ If you want a first CI smoke before enabling code scanning, copy [Adoption Smoke
19
19
  - `npx -y memento-mori-jester@latest summary --kind command "git reset --hard"`
20
20
  - `npm run framework:tuning:check` and `npm run framework:tuning:doctor` from the published package tarball
21
21
 
22
+ Maintainers can prove those commands from a minimal installed project with [Consumer Quickstart Smoke](../consumer-quickstart) and `npm run consumer:quickstart:check`.
23
+
22
24
  ## Workflows
23
25
 
24
26
  - [Adoption Smoke](adoption-smoke.yml): read-only setup check for doctor, summary, and framework tuning cookbook commands.
27
+ - [Consumer Quickstart Smoke](../consumer-quickstart): minimal installed-project fixture for the adoption commands.
25
28
  - [Next.js](nextjs.yml): app-router, middleware, redirects, public env, and browser-rendered UI.
26
29
  - [Vite React](vite-react.yml): browser storage, public config, redirects, and unsafe HTML surfaces.
27
30
  - [Express API](express-api.yml): CORS, auth bypasses, raw SQL, webhooks, and migrations.
@@ -0,0 +1,30 @@
1
+ # Consumer Quickstart Smoke
2
+
3
+ This tiny project proves the first commands a real repo copies still work after installing Memento Mori Jester from npm.
4
+
5
+ ```powershell
6
+ npm install --save-dev memento-mori-jester
7
+ npm run jester:doctor
8
+ npm run jester:summary
9
+ npm run jester:framework-tuning:check
10
+ npm run jester:framework-tuning:doctor
11
+ ```
12
+
13
+ The package scripts map to the same public commands used by [Adoption Smoke CI](../ci/adoption-smoke.yml) at `examples/ci/adoption-smoke.yml`:
14
+
15
+ - `jester doctor`
16
+ - `jester summary --kind command "git reset --hard"`
17
+ - `npm run framework:tuning:check --prefix node_modules/memento-mori-jester`
18
+ - `npm run framework:tuning:doctor --prefix node_modules/memento-mori-jester`
19
+
20
+ Maintainers can run the checked version from the repo root:
21
+
22
+ ```powershell
23
+ npm run consumer:quickstart:check
24
+ ```
25
+
26
+ After publishing, the same checker can verify the public registry package:
27
+
28
+ ```powershell
29
+ npm run consumer:quickstart:check -- --package memento-mori-jester@latest
30
+ ```
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "memento-mori-jester-consumer-quickstart",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "description": "Minimal consumer project used to smoke-test Memento Mori Jester quickstart commands.",
6
+ "scripts": {
7
+ "jester:doctor": "jester doctor",
8
+ "jester:summary": "jester summary --kind command \"git reset --hard\"",
9
+ "jester:framework-tuning:check": "npm run framework:tuning:check --prefix node_modules/memento-mori-jester",
10
+ "jester:framework-tuning:doctor": "npm run framework:tuning:doctor --prefix node_modules/memento-mori-jester"
11
+ }
12
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memento-mori-jester",
3
- "version": "0.1.85",
3
+ "version": "0.1.87",
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 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 promo:check && npm run site: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",
@@ -49,6 +49,7 @@
49
49
  "framework:tuning:check": "node scripts/check-framework-tuning.mjs",
50
50
  "framework:tuning:doctor": "node scripts/doctor-framework-tuning.mjs",
51
51
  "ci:adoption:check": "node scripts/check-ci-adoption.mjs",
52
+ "consumer:quickstart:check": "node scripts/check-consumer-quickstart.mjs",
52
53
  "promo:card": "node scripts/render-social-card.mjs",
53
54
  "promo:card:check": "node scripts/render-social-card.mjs --check",
54
55
  "promo:check": "node scripts/check-promo-freshness.mjs",
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env node
2
+ import { cpSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { dirname, isAbsolute, join, resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { spawnSync } from "node:child_process";
7
+
8
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
9
+ const root = join(scriptDir, "..");
10
+ const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm";
11
+ const npmExecPath = process.env.npm_execpath;
12
+ const fixtureDir = join(root, "examples", "consumer-quickstart");
13
+ const fixturePackagePath = join(fixtureDir, "package.json");
14
+ const fixtureReadmePath = join(fixtureDir, "README.md");
15
+ const args = process.argv.slice(2);
16
+
17
+ process.on("uncaughtException", (error) => {
18
+ console.error("Consumer quickstart check failed:");
19
+ console.error(`- ${error instanceof Error ? error.message : String(error)}`);
20
+ process.exit(1);
21
+ });
22
+
23
+ let requestedPackageSpec = null;
24
+ let keepTemp = false;
25
+
26
+ for (let index = 0; index < args.length; index += 1) {
27
+ const arg = args[index];
28
+ if (arg === "--package" || arg === "--package-spec") {
29
+ requestedPackageSpec = args[index + 1];
30
+ index += 1;
31
+ } else if (arg === "--registry-latest") {
32
+ requestedPackageSpec = "memento-mori-jester@latest";
33
+ } else if (arg === "--keep-temp") {
34
+ keepTemp = true;
35
+ } else {
36
+ fail(`Unknown option: ${arg}`);
37
+ }
38
+ }
39
+
40
+ if (requestedPackageSpec === "") {
41
+ fail("--package requires a non-empty npm package spec.");
42
+ }
43
+
44
+ const unsafeContentPatterns = [
45
+ { name: "private key block", pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----/ },
46
+ { name: "OpenAI-looking secret key", pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\b/ },
47
+ { name: "Anthropic-looking secret key", pattern: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/ },
48
+ { name: "GitHub-looking token", pattern: /\bgh[pousr]_[A-Za-z0-9_]{20,}\b/ },
49
+ { name: "AWS access key id", pattern: /\bAKIA[0-9A-Z]{16}\b/ },
50
+ { name: "Slack-looking token", pattern: /\bxox[baprs]-[A-Za-z0-9-]{20,}\b/ },
51
+ { name: "absolute Unix home path", pattern: /(?:^|[\s"'`])\/(?:Users|home)\/[A-Za-z0-9._-]+/ },
52
+ { name: "absolute Windows user path", pattern: /[A-Za-z]:\\Users\\[A-Za-z0-9._-]+\\/ }
53
+ ];
54
+
55
+ checkFixtureFiles();
56
+
57
+ const tempRoot = mkdtempSync(join(tmpdir(), "jester-consumer-quickstart-"));
58
+ let packageSpec = requestedPackageSpec;
59
+ let packageLabel = requestedPackageSpec ?? "local packed package";
60
+
61
+ try {
62
+ if (!packageSpec) {
63
+ packageSpec = packLocalPackage(tempRoot);
64
+ }
65
+
66
+ const consumerDir = join(tempRoot, "consumer-project");
67
+ cpSync(fixtureDir, consumerDir, { recursive: true });
68
+ installPackageSpec(consumerDir, packageSpec);
69
+
70
+ const doctor = runNpm(["run", "jester:doctor"], { cwd: consumerDir });
71
+ requireOutput(doctor, /PASS package-version/, "doctor package-version pass");
72
+ requireOutput(doctor, /The fool is fit for court\./, "doctor success footer");
73
+
74
+ const summary = runNpm(["run", "jester:summary"], { cwd: consumerDir });
75
+ requireOutput(summary, /Verdict: BLOCK/, "summary block verdict");
76
+ requireOutput(summary, /destructive-git-history/, "destructive git rule hit");
77
+
78
+ const tuningCheck = runNpm(["run", "jester:framework-tuning:check"], { cwd: consumerDir });
79
+ requireOutput(tuningCheck, /Framework tuning check passed for 5 recipes\./, "framework tuning cookbook check success");
80
+
81
+ const tuningDoctor = runNpm(["run", "jester:framework-tuning:doctor"], { cwd: consumerDir });
82
+ requireOutput(tuningDoctor, /Framework tuning doctor/, "framework tuning doctor heading");
83
+ requireOutput(tuningDoctor, /Checked 5 recipe\(s\), 10 executable tune command\(s\), and 34 fixture rule reference\(s\)\./, "framework tuning doctor totals");
84
+
85
+ console.log("Consumer quickstart check");
86
+ console.log(`PASS installed ${packageLabel}`);
87
+ console.log("PASS npm run jester:doctor");
88
+ console.log("PASS npm run jester:summary");
89
+ console.log("PASS npm run jester:framework-tuning:check");
90
+ console.log("PASS npm run jester:framework-tuning:doctor");
91
+ } finally {
92
+ if (keepTemp) {
93
+ console.log(`Kept temp project at ${tempRoot}`);
94
+ } else {
95
+ rmSync(tempRoot, { recursive: true, force: true });
96
+ }
97
+ }
98
+
99
+ function checkFixtureFiles() {
100
+ if (!existsSync(fixturePackagePath)) {
101
+ fail("examples/consumer-quickstart/package.json is missing.");
102
+ }
103
+
104
+ if (!existsSync(fixtureReadmePath)) {
105
+ fail("examples/consumer-quickstart/README.md is missing.");
106
+ }
107
+
108
+ const fixturePackageRaw = readFileSync(fixturePackagePath, "utf8");
109
+ const fixtureReadme = readFileSync(fixtureReadmePath, "utf8");
110
+ const fixturePackage = JSON.parse(fixturePackageRaw);
111
+
112
+ for (const [path, content] of [
113
+ ["examples/consumer-quickstart/package.json", fixturePackageRaw],
114
+ ["examples/consumer-quickstart/README.md", fixtureReadme]
115
+ ]) {
116
+ for (const unsafe of unsafeContentPatterns) {
117
+ if (unsafe.pattern.test(content)) {
118
+ fail(`${path} appears to contain ${unsafe.name}; consumer examples should stay public and redacted.`);
119
+ }
120
+ }
121
+ }
122
+
123
+ const expectedScripts = {
124
+ "jester:doctor": "jester doctor",
125
+ "jester:summary": "jester summary --kind command \"git reset --hard\"",
126
+ "jester:framework-tuning:check": "npm run framework:tuning:check --prefix node_modules/memento-mori-jester",
127
+ "jester:framework-tuning:doctor": "npm run framework:tuning:doctor --prefix node_modules/memento-mori-jester"
128
+ };
129
+
130
+ if (fixturePackage.private !== true) {
131
+ fail("examples/consumer-quickstart/package.json should stay private.");
132
+ }
133
+
134
+ for (const [scriptName, scriptCommand] of Object.entries(expectedScripts)) {
135
+ if (fixturePackage.scripts?.[scriptName] !== scriptCommand) {
136
+ fail(`examples/consumer-quickstart/package.json script ${scriptName} should be "${scriptCommand}".`);
137
+ }
138
+ }
139
+
140
+ for (const expected of [
141
+ "npm install --save-dev memento-mori-jester",
142
+ "npm run jester:doctor",
143
+ "npm run jester:summary",
144
+ "npm run jester:framework-tuning:check",
145
+ "npm run jester:framework-tuning:doctor",
146
+ "examples/ci/adoption-smoke.yml",
147
+ "npm run consumer:quickstart:check"
148
+ ]) {
149
+ if (!fixtureReadme.includes(expected)) {
150
+ fail(`examples/consumer-quickstart/README.md should include ${expected}.`);
151
+ }
152
+ }
153
+ }
154
+
155
+ function packLocalPackage(destination) {
156
+ const cliPath = join(root, "dist", "cli.js");
157
+ if (!existsSync(cliPath)) {
158
+ fail(`${cliPath} is missing. Run npm run build before npm run consumer:quickstart:check.`);
159
+ }
160
+
161
+ const output = runNpm(["pack", "--ignore-scripts", "--pack-destination", destination, "--silent"], { cwd: root });
162
+ const filename = output.trim().split(/\r?\n/).filter(Boolean).at(-1);
163
+ if (!filename) {
164
+ fail("npm pack did not return a tarball filename.");
165
+ }
166
+
167
+ return isAbsolute(filename) ? filename : resolve(destination, filename);
168
+ }
169
+
170
+ function installPackageSpec(consumerDir, spec) {
171
+ const packagePath = join(consumerDir, "package.json");
172
+ const packageJson = JSON.parse(readFileSync(packagePath, "utf8"));
173
+ delete packageJson.devDependencies;
174
+ writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}\n`);
175
+
176
+ runNpm(["install", "--save-dev", spec, "--ignore-scripts", "--no-audit", "--no-fund"], { cwd: consumerDir });
177
+ }
178
+
179
+ function runNpm(commandArgs, options = {}) {
180
+ if (npmExecPath) {
181
+ return run(process.execPath, [npmExecPath, ...commandArgs], options);
182
+ }
183
+
184
+ return run(npmCommand, commandArgs, options);
185
+ }
186
+
187
+ function run(command, commandArgs, options = {}) {
188
+ const result = spawnSync(command, commandArgs, {
189
+ cwd: options.cwd ?? root,
190
+ encoding: "utf8",
191
+ maxBuffer: 20 * 1024 * 1024,
192
+ env: {
193
+ ...process.env,
194
+ npm_config_audit: "false",
195
+ npm_config_fund: "false"
196
+ }
197
+ });
198
+
199
+ if (result.error) {
200
+ throw result.error;
201
+ }
202
+
203
+ if (result.status !== 0) {
204
+ const detail = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
205
+ fail(`${command} ${commandArgs.join(" ")} failed${detail ? `:\n${detail}` : "."}`);
206
+ }
207
+
208
+ return result.stdout;
209
+ }
210
+
211
+ function requireOutput(output, pattern, description) {
212
+ if (!pattern.test(output)) {
213
+ fail(`Expected ${description}. Output was:\n${output}`);
214
+ }
215
+ }
216
+
217
+ function fail(message) {
218
+ throw new Error(message);
219
+ }
@@ -71,6 +71,7 @@ for (const path of [
71
71
  "scripts/check-framework-tuning.mjs",
72
72
  "scripts/doctor-framework-tuning.mjs",
73
73
  "scripts/check-ci-adoption.mjs",
74
+ "scripts/check-consumer-quickstart.mjs",
74
75
  "scripts/check-fixtures.mjs",
75
76
  "scripts/report-fixtures.mjs",
76
77
  ".github/ISSUE_TEMPLATE/bug_report.yml",
@@ -84,6 +85,8 @@ for (const path of [
84
85
  "examples/github-code-scanning.yml",
85
86
  "examples/ci/README.md",
86
87
  "examples/ci/adoption-smoke.yml",
88
+ "examples/consumer-quickstart/README.md",
89
+ "examples/consumer-quickstart/package.json",
87
90
  "examples/presets/README.md",
88
91
  "examples/tuning/README.md",
89
92
  "examples/tuning/framework-tuning-cookbook.json",
@@ -109,6 +112,7 @@ requireText("README.md", /fixtures:report -- --markdown/, "Markdown fixture repo
109
112
  requireText("README.md", /FRAMEWORK_TUNING\.md/, "framework tuning guide link");
110
113
  requireText("README.md", /examples\/tuning/, "framework tuning cookbook link");
111
114
  requireText("README.md", /adoption-smoke\.yml/, "adoption smoke CI link");
115
+ requireText("README.md", /consumer-quickstart/, "consumer quickstart smoke link");
112
116
  requireText("README.md", /License: PolyForm Noncommercial/, "the noncommercial license badge");
113
117
  requireText("docs/PRODUCTION_READINESS.md", /npm package/i, "npm package readiness");
114
118
  requireText("docs/PRODUCTION_READINESS.md", /GitHub Action/i, "GitHub Action readiness");
@@ -125,6 +129,7 @@ requireText("docs/PRODUCTION_READINESS.md", /fixtures:report -- --markdown/, "Ma
125
129
  requireText("docs/PRODUCTION_READINESS.md", /framework:tuning:check/, "framework tuning cookbook readiness");
126
130
  requireText("docs/PRODUCTION_READINESS.md", /framework:tuning:doctor/, "framework tuning cookbook doctor readiness");
127
131
  requireText("docs/PRODUCTION_READINESS.md", /adoption-smoke\.yml/, "adoption smoke CI readiness");
132
+ requireText("docs/PRODUCTION_READINESS.md", /consumer:quickstart:check/, "consumer quickstart smoke readiness");
128
133
  requireText("docs/PRODUCTION_READINESS.md", /quiet-pass/, "quiet-pass fixture readiness");
129
134
  requireText("docs/CLI.md", /jester doctor --json/, "doctor JSON CLI docs");
130
135
  requireText("docs/CLI.md", /quiet-pass fixture/, "quiet-pass fixture CLI docs");
@@ -140,6 +145,7 @@ requireText("docs/FRAMEWORK_TUNING.md", /framework:tuning:doctor/, "framework tu
140
145
  requireText("docs/GITHUB_ACTIONS.md", /adoption-smoke\.yml/, "adoption smoke GitHub Actions docs");
141
146
  requireText("docs/GITHUB_ACTIONS.md", /summary --kind command "git reset --hard"/, "adoption summary smoke docs");
142
147
  requireText("docs/GITHUB_ACTIONS.md", /framework:tuning:doctor/, "adoption framework tuning doctor docs");
148
+ requireText("docs/GITHUB_ACTIONS.md", /consumer:quickstart:check/, "consumer quickstart GitHub Actions docs");
143
149
  requireText("docs/MAINTAINER_TRIAGE.md", /doctor --json/, "doctor JSON triage prompt");
144
150
  requireText("docs/MAINTAINER_TRIAGE.md", /tune <rule-id> --json/, "tune JSON triage prompt");
145
151
  requireText("docs/MAINTAINER_TRIAGE.md", /preset-review-cases\.json/, "fixture suite link");
@@ -151,9 +157,13 @@ requireText("examples/fixtures/README.md", /fixtures:check/, "fixture authoring
151
157
  requireText("examples/fixtures/README.md", /fixtures:report/, "fixture coverage report guidance");
152
158
  requireText("examples/fixtures/README.md", /fixtures:report -- --markdown/, "Markdown fixture report guidance");
153
159
  requireText("examples/ci/README.md", /adoption-smoke\.yml/, "adoption smoke CI index link");
160
+ requireText("examples/ci/README.md", /consumer-quickstart/, "consumer quickstart CI index link");
154
161
  requireText("examples/ci/adoption-smoke.yml", /npx -y memento-mori-jester@latest doctor/, "adoption smoke doctor command");
155
162
  requireText("examples/ci/adoption-smoke.yml", /summary --kind command "git reset --hard"/, "adoption smoke summary command");
156
163
  requireText("examples/ci/adoption-smoke.yml", /framework:tuning:doctor/, "adoption smoke tuning doctor command");
164
+ requireText("examples/consumer-quickstart/README.md", /npm run consumer:quickstart:check/, "consumer quickstart check command");
165
+ requireText("examples/consumer-quickstart/package.json", /jester:summary/, "consumer quickstart summary script");
166
+ requireText("examples/consumer-quickstart/package.json", /framework:tuning:doctor/, "consumer quickstart tuning doctor script");
157
167
  requireText("examples/tuning/README.md", /framework-tuning-cookbook\.json/, "framework tuning cookbook JSON link");
158
168
  requireText("examples/tuning/README.md", /framework:tuning:doctor/, "framework tuning doctor guidance");
159
169
  requireText("examples/tuning/README.md", /jester tune <rule-id> --json|jester tune [a-z0-9-]+ --json/, "framework tuning command guidance");
@@ -178,11 +188,15 @@ forbidText("scripts/doctor-framework-tuning.mjs", /src\/config\.ts|src\/types\.t
178
188
  requireText("scripts/check-ci-adoption.mjs", /adoption-smoke\.yml/, "adoption smoke checker target");
179
189
  requireText("scripts/check-ci-adoption.mjs", /pull_request_target/, "adoption smoke unsafe trigger guard");
180
190
  requireText("scripts/check-ci-adoption.mjs", /framework:tuning:doctor/, "adoption smoke tuning doctor guard");
191
+ requireText("scripts/check-consumer-quickstart.mjs", /consumer-quickstart/, "consumer quickstart checker target");
192
+ requireText("scripts/check-consumer-quickstart.mjs", /memento-mori-jester@latest/, "consumer quickstart registry verification option");
193
+ requireText("scripts/check-consumer-quickstart.mjs", /framework:tuning:doctor/, "consumer quickstart tuning doctor guard");
181
194
  requireText("package.json", /"fixtures:check": "node scripts\/check-fixtures\.mjs"/, "fixture authoring check script");
182
195
  requireText("package.json", /"fixtures:report": "node scripts\/report-fixtures\.mjs"/, "fixture coverage report script");
183
196
  requireText("package.json", /"framework:tuning:check": "node scripts\/check-framework-tuning\.mjs"/, "framework tuning cookbook check script");
184
197
  requireText("package.json", /"framework:tuning:doctor": "node scripts\/doctor-framework-tuning\.mjs"/, "framework tuning cookbook doctor script");
185
198
  requireText("package.json", /"ci:adoption:check": "node scripts\/check-ci-adoption\.mjs"/, "CI adoption check script");
199
+ requireText("package.json", /"consumer:quickstart:check": "node scripts\/check-consumer-quickstart\.mjs"/, "consumer quickstart check script");
186
200
  requireText("package.json", /"promo:card": "node scripts\/render-social-card\.mjs"/, "social card render script");
187
201
  requireText("package.json", /"promo:card:check": "node scripts\/render-social-card\.mjs --check"/, "social card stale check script");
188
202
  requireText("package.json", /"promo:check": "node scripts\/check-promo-freshness\.mjs"/, "promo freshness check script");
@@ -192,6 +206,7 @@ requireText("package.json", /npm run fixtures:report/, "fixture coverage report
192
206
  requireText("package.json", /npm run framework:tuning:check/, "framework tuning cookbook check in npm test");
193
207
  requireText("package.json", /npm run framework:tuning:doctor/, "framework tuning cookbook doctor in npm test");
194
208
  requireText("package.json", /npm run ci:adoption:check/, "CI adoption check in npm test");
209
+ requireText("package.json", /npm run consumer:quickstart:check/, "consumer quickstart check in npm test");
195
210
  requireText("package.json", /npm run promo:check/, "promo freshness check in npm test");
196
211
  requireText("package.json", /npm run site:check/, "site check in npm test");
197
212
  requireText("scripts/check-promo-freshness.mjs", /--require-package-version/, "optional strict package-version promo check");