memento-mori-jester 0.1.84 → 0.1.86
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 +12 -0
- package/README.md +9 -0
- package/ROADMAP.md +2 -0
- package/docs/GITHUB_ACTIONS.md +17 -0
- package/docs/PRODUCTION_READINESS.md +5 -0
- package/docs/RELEASE.md +4 -1
- package/docs/RELEASE_NOTES_v0.1.85.md +54 -0
- package/docs/RELEASE_NOTES_v0.1.86.md +64 -0
- package/examples/ci/README.md +11 -0
- package/examples/ci/adoption-smoke.yml +42 -0
- package/examples/consumer-quickstart/README.md +30 -0
- package/examples/consumer-quickstart/package.json +12 -0
- package/package.json +4 -2
- package/scripts/check-ci-adoption.mjs +89 -0
- package/scripts/check-consumer-quickstart.mjs +221 -0
- package/scripts/check-production-readiness.mjs +31 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ All notable changes to Memento Mori Jester are tracked here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.1.86
|
|
8
|
+
|
|
9
|
+
- Added `examples/consumer-quickstart`, a minimal installed-project fixture for proving the first `doctor`, `summary`, and framework tuning commands from a consumer repo.
|
|
10
|
+
- Added `npm run consumer:quickstart:check`, which installs the package into a temporary project and runs the quickstart/adoption commands from that project.
|
|
11
|
+
- Updated README, GitHub Actions docs, CI examples, release docs, production-readiness docs, roadmap, and release notes for the consumer quickstart smoke path.
|
|
12
|
+
|
|
13
|
+
## 0.1.85
|
|
14
|
+
|
|
15
|
+
- 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.
|
|
16
|
+
- Added `npm run ci:adoption:check` to keep the adoption smoke workflow and docs aligned with current commands and safety expectations.
|
|
17
|
+
- Updated README, GitHub Actions docs, CI examples, release docs, production-readiness docs, roadmap, and release notes for the new adoption path.
|
|
18
|
+
|
|
7
19
|
## 0.1.84
|
|
8
20
|
|
|
9
21
|
- Added `npm run framework:tuning:doctor`, a consumer-style smoke check that generates temporary preset configs and runs every cookbook `jester tune <rule-id> --json` command through the built CLI.
|
package/README.md
CHANGED
|
@@ -68,6 +68,10 @@ npx -y memento-mori-jester@latest github-action --write
|
|
|
68
68
|
|
|
69
69
|
The generated workflow uploads SARIF for code scanning and adds a readable Jester summary to the GitHub Actions run.
|
|
70
70
|
|
|
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
|
+
|
|
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
|
+
|
|
71
75
|
Expected vibe:
|
|
72
76
|
|
|
73
77
|
```text
|
|
@@ -436,6 +440,8 @@ More setup examples:
|
|
|
436
440
|
- [Preset Example Packs](examples/presets)
|
|
437
441
|
- [Review Fixtures](examples/fixtures)
|
|
438
442
|
- [Framework CI Examples](examples/ci)
|
|
443
|
+
- [Adoption Smoke CI](examples/ci/adoption-smoke.yml)
|
|
444
|
+
- [Consumer Quickstart Smoke](examples/consumer-quickstart)
|
|
439
445
|
- [Security Policy](SECURITY.md)
|
|
440
446
|
- [Maintainer Triage](docs/MAINTAINER_TRIAGE.md)
|
|
441
447
|
- [Changelog](CHANGELOG.md)
|
|
@@ -453,6 +459,8 @@ Preset example packs:
|
|
|
453
459
|
|
|
454
460
|
Framework CI examples:
|
|
455
461
|
|
|
462
|
+
- [Adoption Smoke CI](examples/ci/adoption-smoke.yml)
|
|
463
|
+
- [Consumer Quickstart Smoke](examples/consumer-quickstart)
|
|
456
464
|
- [Next.js CI](examples/ci/nextjs.yml)
|
|
457
465
|
- [Vite React CI](examples/ci/vite-react.yml)
|
|
458
466
|
- [Express API CI](examples/ci/express-api.yml)
|
|
@@ -520,6 +528,7 @@ Release checklist:
|
|
|
520
528
|
|
|
521
529
|
```powershell
|
|
522
530
|
npm.cmd test
|
|
531
|
+
npm.cmd run consumer:quickstart:check
|
|
523
532
|
npm.cmd run promo:check
|
|
524
533
|
npm.cmd run production:check
|
|
525
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 smoke in v0.1.86, proving the first installed-project commands from a minimal repo before release.
|
|
10
|
+
- Adoption smoke CI example in v0.1.85, giving real repos a read-only workflow for `doctor`, `summary`, and packaged framework tuning checks.
|
|
9
11
|
- Framework tuning doctor in v0.1.84, proving cookbook recipes execute through the built CLI with generated preset configs before release.
|
|
10
12
|
- Framework tuning cookbook in v0.1.83, adding checked copy-paste recipes and a machine-readable JSON map for stack-shaped noisy-rule reports.
|
|
11
13
|
- Framework tuning examples and quiet-pass fixture curation in v0.1.82, adding six safe real-world examples plus a guide for framework-shaped noisy-rule reports.
|
package/docs/GITHUB_ACTIONS.md
CHANGED
|
@@ -20,6 +20,23 @@ The generated workflow reviews pull request diffs, writes `jester.sarif`, upload
|
|
|
20
20
|
|
|
21
21
|
This repository dogfoods that generated workflow in [.github/workflows/memento-mori.yml](../.github/workflows/memento-mori.yml).
|
|
22
22
|
|
|
23
|
+
## Adoption Smoke Workflow
|
|
24
|
+
|
|
25
|
+
Use [examples/ci/adoption-smoke.yml](../examples/ci/adoption-smoke.yml) when you want a first read-only CI check before enabling SARIF/code scanning.
|
|
26
|
+
|
|
27
|
+
It runs:
|
|
28
|
+
|
|
29
|
+
```powershell
|
|
30
|
+
npx -y memento-mori-jester@latest doctor
|
|
31
|
+
npx -y memento-mori-jester@latest summary --kind command "git reset --hard"
|
|
32
|
+
npm run framework:tuning:check
|
|
33
|
+
npm run framework:tuning:doctor
|
|
34
|
+
```
|
|
35
|
+
|
|
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
|
+
|
|
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
|
+
|
|
23
40
|
## Composite Action
|
|
24
41
|
|
|
25
42
|
This repo can be used directly as a GitHub Action:
|
|
@@ -26,6 +26,8 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
|
|
|
26
26
|
- Action inputs cover `fail-on`, `subject`, `config`, `no-config`, `format`, `output-file`, and `summary`.
|
|
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
|
+
- `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.
|
|
29
31
|
|
|
30
32
|
## MCP And Agent Setup
|
|
31
33
|
|
|
@@ -60,6 +62,7 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
|
|
|
60
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.
|
|
61
63
|
- `npm run framework:tuning:check` keeps the framework tuning guide, cookbook JSON, cookbook README, and fixture IDs aligned.
|
|
62
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.
|
|
63
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.
|
|
64
67
|
- `npm run site:check` verifies the static landing page before maintainers post or host it.
|
|
65
68
|
- npm publish has a manual workflow fallback, but the normal release path is tag-driven trusted publishing.
|
|
@@ -79,6 +82,8 @@ This checklist defines what "production grade" means for Memento Mori Jester rig
|
|
|
79
82
|
- fixture coverage reports are wired into `npm test`.
|
|
80
83
|
- framework tuning cookbook checks are wired into `npm test`.
|
|
81
84
|
- framework tuning cookbook doctor checks are wired into `npm test`.
|
|
85
|
+
- CI adoption example checks are wired into `npm test`.
|
|
86
|
+
- consumer quickstart smoke checks are wired into `npm test`.
|
|
82
87
|
- promo freshness checks are wired into `npm test`.
|
|
83
88
|
- site checks are wired into `npm test`.
|
|
84
89
|
|
package/docs/RELEASE.md
CHANGED
|
@@ -14,6 +14,8 @@ npm.cmd run fixtures:report -- --json
|
|
|
14
14
|
npm.cmd run fixtures:report -- --markdown
|
|
15
15
|
npm.cmd run framework:tuning:check
|
|
16
16
|
npm.cmd run framework:tuning:doctor
|
|
17
|
+
npm.cmd run ci:adoption:check
|
|
18
|
+
npm.cmd run consumer:quickstart:check
|
|
17
19
|
npm.cmd run promo:card:check
|
|
18
20
|
npm.cmd run promo:check
|
|
19
21
|
npm.cmd run site:check
|
|
@@ -26,7 +28,7 @@ Move the current changelog bullets into a matching version section and add `docs
|
|
|
26
28
|
## 2. Tag And Push
|
|
27
29
|
|
|
28
30
|
```powershell
|
|
29
|
-
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 examples/tuning 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
|
|
30
32
|
git commit -m "Release v0.1.x"
|
|
31
33
|
git tag -a v0.1.x -m "Memento Mori Jester v0.1.x"
|
|
32
34
|
git push origin main
|
|
@@ -82,6 +84,7 @@ npx.cmd -y memento-mori-jester@latest config init --preset ai --path jester-ai.c
|
|
|
82
84
|
npx.cmd -y memento-mori-jester@latest config validate --config jester-ai.config.json
|
|
83
85
|
npx.cmd -y memento-mori-jester@latest config init --preset security --path jester-security.config.json
|
|
84
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
|
|
85
88
|
```
|
|
86
89
|
|
|
87
90
|
## 4. MCP Copy-Paste
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Memento Mori Jester v0.1.85
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
This release adds a narrow adoption smoke workflow for real repos. It gives teams a read-only GitHub Actions recipe that checks the package health, proves a summary review path, and verifies the published framework tuning cookbook scripts before they enable heavier code-scanning workflows.
|
|
6
|
+
|
|
7
|
+
## What Changed
|
|
8
|
+
|
|
9
|
+
- Added `examples/ci/adoption-smoke.yml`.
|
|
10
|
+
- Added `scripts/check-ci-adoption.mjs`.
|
|
11
|
+
- Added `npm run ci:adoption:check`.
|
|
12
|
+
- Wired the adoption checker into `npm test` and production-readiness checks.
|
|
13
|
+
- Updated README, GitHub Actions docs, CI example docs, release docs, production-readiness docs, roadmap, and changelog.
|
|
14
|
+
|
|
15
|
+
## Public Interface
|
|
16
|
+
|
|
17
|
+
- No CLI command changes.
|
|
18
|
+
- No MCP tool changes.
|
|
19
|
+
- No config schema changes.
|
|
20
|
+
- No review rule, scoring, matching, or verdict behavior changes.
|
|
21
|
+
- No GitHub Action input changes.
|
|
22
|
+
- New maintainer/package script: `npm run ci:adoption:check`.
|
|
23
|
+
- New checked example workflow: `examples/ci/adoption-smoke.yml`.
|
|
24
|
+
|
|
25
|
+
## Release Validation
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
npm.cmd test
|
|
29
|
+
npm.cmd run demo:svg:check
|
|
30
|
+
npm.cmd run promo:card:check
|
|
31
|
+
npm.cmd run promo:check
|
|
32
|
+
npm.cmd run framework:tuning:check
|
|
33
|
+
npm.cmd run framework:tuning:doctor
|
|
34
|
+
npm.cmd run ci:adoption:check
|
|
35
|
+
npm.cmd run fixtures:report
|
|
36
|
+
npm.cmd run fixtures:report -- --json
|
|
37
|
+
npm.cmd run fixtures:report -- --markdown
|
|
38
|
+
npm.cmd run site:check
|
|
39
|
+
npm.cmd run pack:dry
|
|
40
|
+
git diff --check
|
|
41
|
+
node .\dist\cli.js summary --kind command "git reset --hard"
|
|
42
|
+
node .\dist\cli.js tune coverage --no-config
|
|
43
|
+
git diff | node .\dist\cli.js diff --fail-on block --subject "v0.1.85 adoption smoke CI"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Expected:
|
|
47
|
+
|
|
48
|
+
- `ci:adoption:check` passes for `examples/ci/adoption-smoke.yml`,
|
|
49
|
+
- `framework:tuning:doctor` still runs 10 executable tune commands,
|
|
50
|
+
- fixture report still shows `Fixtures: 222`,
|
|
51
|
+
- no thin rule coverage,
|
|
52
|
+
- no preset/kind gaps,
|
|
53
|
+
- no rules without quiet-pass coverage,
|
|
54
|
+
- GitHub Release and npm Publish complete from the `v0.1.85` tag.
|
|
@@ -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
|
+
```
|
package/examples/ci/README.md
CHANGED
|
@@ -13,8 +13,18 @@ npx -y memento-mori-jester@latest bootstrap --preset web
|
|
|
13
13
|
|
|
14
14
|
Then copy the workflow that best matches your stack into `.github/workflows/memento-mori.yml`.
|
|
15
15
|
|
|
16
|
+
If you want a first CI smoke before enabling code scanning, copy [Adoption Smoke](adoption-smoke.yml). It runs:
|
|
17
|
+
|
|
18
|
+
- `npx -y memento-mori-jester@latest doctor`
|
|
19
|
+
- `npx -y memento-mori-jester@latest summary --kind command "git reset --hard"`
|
|
20
|
+
- `npm run framework:tuning:check` and `npm run framework:tuning:doctor` from the published package tarball
|
|
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
|
+
|
|
16
24
|
## Workflows
|
|
17
25
|
|
|
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.
|
|
18
28
|
- [Next.js](nextjs.yml): app-router, middleware, redirects, public env, and browser-rendered UI.
|
|
19
29
|
- [Vite React](vite-react.yml): browser storage, public config, redirects, and unsafe HTML surfaces.
|
|
20
30
|
- [Express API](express-api.yml): CORS, auth bypasses, raw SQL, webhooks, and migrations.
|
|
@@ -25,5 +35,6 @@ Then copy the workflow that best matches your stack into `.github/workflows/meme
|
|
|
25
35
|
## Notes
|
|
26
36
|
|
|
27
37
|
- Workflows upload SARIF and add a readable Actions job summary.
|
|
38
|
+
- The adoption smoke workflow is read-only and does not upload SARIF.
|
|
28
39
|
- Most stacks fail CI only on `BLOCK`.
|
|
29
40
|
- The Terraform/Kubernetes example uses `fail-on: caution` because infra repos often want lower tolerance for risky changes.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Memento Mori Jester Adoption Smoke
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
adoption-smoke:
|
|
13
|
+
name: Adoption smoke
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
timeout-minutes: 10
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout
|
|
19
|
+
uses: actions/checkout@v6
|
|
20
|
+
|
|
21
|
+
- name: Setup Node
|
|
22
|
+
uses: actions/setup-node@v6
|
|
23
|
+
with:
|
|
24
|
+
node-version: 24
|
|
25
|
+
|
|
26
|
+
- name: Jester doctor
|
|
27
|
+
run: npx -y memento-mori-jester@latest doctor
|
|
28
|
+
|
|
29
|
+
- name: Command summary smoke
|
|
30
|
+
run: npx -y memento-mori-jester@latest summary --kind command "git reset --hard"
|
|
31
|
+
|
|
32
|
+
- name: Framework tuning cookbook smoke
|
|
33
|
+
shell: bash
|
|
34
|
+
run: |
|
|
35
|
+
set -euo pipefail
|
|
36
|
+
workdir="$(mktemp -d)"
|
|
37
|
+
trap 'rm -rf "$workdir"' EXIT
|
|
38
|
+
npm pack memento-mori-jester@latest --pack-destination "$workdir" --silent
|
|
39
|
+
tar -xzf "$workdir"/memento-mori-jester-*.tgz -C "$workdir"
|
|
40
|
+
npm install --omit=dev --ignore-scripts --prefix "$workdir/package"
|
|
41
|
+
npm run framework:tuning:check --prefix "$workdir/package"
|
|
42
|
+
npm run framework:tuning:doctor --prefix "$workdir/package"
|
|
@@ -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.
|
|
3
|
+
"version": "0.1.86",
|
|
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 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",
|
|
@@ -48,6 +48,8 @@
|
|
|
48
48
|
"fixtures:report": "node scripts/report-fixtures.mjs",
|
|
49
49
|
"framework:tuning:check": "node scripts/check-framework-tuning.mjs",
|
|
50
50
|
"framework:tuning:doctor": "node scripts/doctor-framework-tuning.mjs",
|
|
51
|
+
"ci:adoption:check": "node scripts/check-ci-adoption.mjs",
|
|
52
|
+
"consumer:quickstart:check": "node scripts/check-consumer-quickstart.mjs",
|
|
51
53
|
"promo:card": "node scripts/render-social-card.mjs",
|
|
52
54
|
"promo:card:check": "node scripts/render-social-card.mjs --check",
|
|
53
55
|
"promo:check": "node scripts/check-promo-freshness.mjs",
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
const failures = [];
|
|
7
|
+
const workflowPath = "examples/ci/adoption-smoke.yml";
|
|
8
|
+
const workflow = read(workflowPath);
|
|
9
|
+
const examplesReadme = read("examples/ci/README.md");
|
|
10
|
+
const githubActionsDocs = read("docs/GITHUB_ACTIONS.md");
|
|
11
|
+
const readme = read("README.md");
|
|
12
|
+
|
|
13
|
+
const unsafeContentPatterns = [
|
|
14
|
+
{ name: "private key block", pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----/ },
|
|
15
|
+
{ name: "OpenAI-looking secret key", pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\b/ },
|
|
16
|
+
{ name: "Anthropic-looking secret key", pattern: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/ },
|
|
17
|
+
{ name: "GitHub-looking token", pattern: /\bgh[pousr]_[A-Za-z0-9_]{20,}\b/ },
|
|
18
|
+
{ name: "AWS access key id", pattern: /\bAKIA[0-9A-Z]{16}\b/ },
|
|
19
|
+
{ name: "Slack-looking token", pattern: /\bxox[baprs]-[A-Za-z0-9-]{20,}\b/ },
|
|
20
|
+
{ name: "absolute Unix home path", pattern: /(?:^|[\s"'`])\/(?:Users|home)\/[A-Za-z0-9._-]+/ },
|
|
21
|
+
{ name: "absolute Windows user path", pattern: /[A-Za-z]:\\Users\\[A-Za-z0-9._-]+\\/ }
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
function read(path) {
|
|
25
|
+
return readFileSync(join(root, path), "utf8");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function requireText(path, content, pattern, description) {
|
|
29
|
+
if (!pattern.test(content)) {
|
|
30
|
+
failures.push(`${path} should include ${description}.`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function forbidText(path, content, pattern, description) {
|
|
35
|
+
if (pattern.test(content)) {
|
|
36
|
+
failures.push(`${path} should not include ${description}.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (const [path, content] of [
|
|
41
|
+
[workflowPath, workflow],
|
|
42
|
+
["examples/ci/README.md", examplesReadme],
|
|
43
|
+
["docs/GITHUB_ACTIONS.md", githubActionsDocs],
|
|
44
|
+
["README.md", readme]
|
|
45
|
+
]) {
|
|
46
|
+
for (const unsafe of unsafeContentPatterns) {
|
|
47
|
+
if (unsafe.pattern.test(content)) {
|
|
48
|
+
failures.push(`${path} appears to contain ${unsafe.name}; adoption examples should stay public and redacted.`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
requireText(workflowPath, workflow, /^name: Memento Mori Jester Adoption Smoke/m, "the adoption smoke workflow name");
|
|
54
|
+
requireText(workflowPath, workflow, /^\s*pull_request:/m, "a pull_request trigger");
|
|
55
|
+
requireText(workflowPath, workflow, /^\s*workflow_dispatch:/m, "a manual trigger");
|
|
56
|
+
requireText(workflowPath, workflow, /^permissions:\s*\n\s*contents: read/m, "read-only contents permission");
|
|
57
|
+
requireText(workflowPath, workflow, /actions\/checkout@v6/, "checkout@v6");
|
|
58
|
+
requireText(workflowPath, workflow, /actions\/setup-node@v6/, "setup-node@v6");
|
|
59
|
+
requireText(workflowPath, workflow, /node-version:\s*24/, "Node 24");
|
|
60
|
+
requireText(workflowPath, workflow, /npx -y memento-mori-jester@latest doctor/, "the doctor command");
|
|
61
|
+
requireText(workflowPath, workflow, /npx -y memento-mori-jester@latest summary --kind command "git reset --hard"/, "the command summary smoke");
|
|
62
|
+
requireText(workflowPath, workflow, /npm pack memento-mori-jester@latest --pack-destination "\$workdir" --silent/, "the registry package smoke");
|
|
63
|
+
requireText(workflowPath, workflow, /npm run framework:tuning:check --prefix "\$workdir\/package"/, "the framework tuning check command");
|
|
64
|
+
requireText(workflowPath, workflow, /npm run framework:tuning:doctor --prefix "\$workdir\/package"/, "the framework tuning doctor command");
|
|
65
|
+
requireText(workflowPath, workflow, /trap 'rm -rf "\$workdir"' EXIT/, "temporary package cleanup");
|
|
66
|
+
forbidText(workflowPath, workflow, /pull_request_target/, "pull_request_target");
|
|
67
|
+
forbidText(workflowPath, workflow, /security-events:\s*write|contents:\s*write|pull-requests:\s*write|id-token:\s*write/, "write permissions");
|
|
68
|
+
forbidText(workflowPath, workflow, /npm publish|gh release|git push/, "release or publish commands");
|
|
69
|
+
|
|
70
|
+
for (const [path, content] of [
|
|
71
|
+
["examples/ci/README.md", examplesReadme],
|
|
72
|
+
["docs/GITHUB_ACTIONS.md", githubActionsDocs],
|
|
73
|
+
["README.md", readme]
|
|
74
|
+
]) {
|
|
75
|
+
requireText(path, content, /adoption-smoke\.yml/, "the adoption smoke workflow link");
|
|
76
|
+
requireText(path, content, /doctor/, "doctor adoption guidance");
|
|
77
|
+
requireText(path, content, /summary --kind command "git reset --hard"/, "summary smoke guidance");
|
|
78
|
+
requireText(path, content, /framework:tuning:doctor/, "framework tuning doctor guidance");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (failures.length > 0) {
|
|
82
|
+
console.error("CI adoption example check failed:");
|
|
83
|
+
for (const failure of failures) {
|
|
84
|
+
console.error(`- ${failure}`);
|
|
85
|
+
}
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log("CI adoption example check passed for examples/ci/adoption-smoke.yml.");
|
|
@@ -0,0 +1,221 @@
|
|
|
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
|
+
packageJson.devDependencies = {
|
|
174
|
+
"memento-mori-jester": spec
|
|
175
|
+
};
|
|
176
|
+
writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
177
|
+
|
|
178
|
+
runNpm(["install", "--ignore-scripts", "--no-audit", "--no-fund"], { cwd: consumerDir });
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function runNpm(commandArgs, options = {}) {
|
|
182
|
+
if (npmExecPath) {
|
|
183
|
+
return run(process.execPath, [npmExecPath, ...commandArgs], options);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return run(npmCommand, commandArgs, options);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function run(command, commandArgs, options = {}) {
|
|
190
|
+
const result = spawnSync(command, commandArgs, {
|
|
191
|
+
cwd: options.cwd ?? root,
|
|
192
|
+
encoding: "utf8",
|
|
193
|
+
maxBuffer: 20 * 1024 * 1024,
|
|
194
|
+
env: {
|
|
195
|
+
...process.env,
|
|
196
|
+
npm_config_audit: "false",
|
|
197
|
+
npm_config_fund: "false"
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
if (result.error) {
|
|
202
|
+
throw result.error;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (result.status !== 0) {
|
|
206
|
+
const detail = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
|
|
207
|
+
fail(`${command} ${commandArgs.join(" ")} failed${detail ? `:\n${detail}` : "."}`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return result.stdout;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function requireOutput(output, pattern, description) {
|
|
214
|
+
if (!pattern.test(output)) {
|
|
215
|
+
fail(`Expected ${description}. Output was:\n${output}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function fail(message) {
|
|
220
|
+
throw new Error(message);
|
|
221
|
+
}
|
|
@@ -70,6 +70,8 @@ for (const path of [
|
|
|
70
70
|
"scripts/check-site.mjs",
|
|
71
71
|
"scripts/check-framework-tuning.mjs",
|
|
72
72
|
"scripts/doctor-framework-tuning.mjs",
|
|
73
|
+
"scripts/check-ci-adoption.mjs",
|
|
74
|
+
"scripts/check-consumer-quickstart.mjs",
|
|
73
75
|
"scripts/check-fixtures.mjs",
|
|
74
76
|
"scripts/report-fixtures.mjs",
|
|
75
77
|
".github/ISSUE_TEMPLATE/bug_report.yml",
|
|
@@ -82,6 +84,9 @@ for (const path of [
|
|
|
82
84
|
"examples/github-action.yml",
|
|
83
85
|
"examples/github-code-scanning.yml",
|
|
84
86
|
"examples/ci/README.md",
|
|
87
|
+
"examples/ci/adoption-smoke.yml",
|
|
88
|
+
"examples/consumer-quickstart/README.md",
|
|
89
|
+
"examples/consumer-quickstart/package.json",
|
|
85
90
|
"examples/presets/README.md",
|
|
86
91
|
"examples/tuning/README.md",
|
|
87
92
|
"examples/tuning/framework-tuning-cookbook.json",
|
|
@@ -106,6 +111,8 @@ requireText("README.md", /fixtures:report/, "fixture coverage report guidance");
|
|
|
106
111
|
requireText("README.md", /fixtures:report -- --markdown/, "Markdown fixture report guidance");
|
|
107
112
|
requireText("README.md", /FRAMEWORK_TUNING\.md/, "framework tuning guide link");
|
|
108
113
|
requireText("README.md", /examples\/tuning/, "framework tuning cookbook link");
|
|
114
|
+
requireText("README.md", /adoption-smoke\.yml/, "adoption smoke CI link");
|
|
115
|
+
requireText("README.md", /consumer-quickstart/, "consumer quickstart smoke link");
|
|
109
116
|
requireText("README.md", /License: PolyForm Noncommercial/, "the noncommercial license badge");
|
|
110
117
|
requireText("docs/PRODUCTION_READINESS.md", /npm package/i, "npm package readiness");
|
|
111
118
|
requireText("docs/PRODUCTION_READINESS.md", /GitHub Action/i, "GitHub Action readiness");
|
|
@@ -121,6 +128,8 @@ requireText("docs/PRODUCTION_READINESS.md", /fixtures:report/, "fixture coverage
|
|
|
121
128
|
requireText("docs/PRODUCTION_READINESS.md", /fixtures:report -- --markdown/, "Markdown fixture report readiness");
|
|
122
129
|
requireText("docs/PRODUCTION_READINESS.md", /framework:tuning:check/, "framework tuning cookbook readiness");
|
|
123
130
|
requireText("docs/PRODUCTION_READINESS.md", /framework:tuning:doctor/, "framework tuning cookbook doctor readiness");
|
|
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");
|
|
124
133
|
requireText("docs/PRODUCTION_READINESS.md", /quiet-pass/, "quiet-pass fixture readiness");
|
|
125
134
|
requireText("docs/CLI.md", /jester doctor --json/, "doctor JSON CLI docs");
|
|
126
135
|
requireText("docs/CLI.md", /quiet-pass fixture/, "quiet-pass fixture CLI docs");
|
|
@@ -133,6 +142,10 @@ requireText("docs/FRAMEWORK_TUNING.md", /Terraform/, "Terraform framework tuning
|
|
|
133
142
|
requireText("docs/FRAMEWORK_TUNING.md", /jester tune <rule-id> --json/, "framework tuning command guidance");
|
|
134
143
|
requireText("docs/FRAMEWORK_TUNING.md", /framework-tuning-cookbook\.json/, "framework tuning cookbook JSON link");
|
|
135
144
|
requireText("docs/FRAMEWORK_TUNING.md", /framework:tuning:doctor/, "framework tuning doctor guidance");
|
|
145
|
+
requireText("docs/GITHUB_ACTIONS.md", /adoption-smoke\.yml/, "adoption smoke GitHub Actions docs");
|
|
146
|
+
requireText("docs/GITHUB_ACTIONS.md", /summary --kind command "git reset --hard"/, "adoption summary smoke docs");
|
|
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");
|
|
136
149
|
requireText("docs/MAINTAINER_TRIAGE.md", /doctor --json/, "doctor JSON triage prompt");
|
|
137
150
|
requireText("docs/MAINTAINER_TRIAGE.md", /tune <rule-id> --json/, "tune JSON triage prompt");
|
|
138
151
|
requireText("docs/MAINTAINER_TRIAGE.md", /preset-review-cases\.json/, "fixture suite link");
|
|
@@ -143,6 +156,14 @@ requireText("examples/fixtures/README.md", /Adding A Fixture From A Report/, "fi
|
|
|
143
156
|
requireText("examples/fixtures/README.md", /fixtures:check/, "fixture authoring check guidance");
|
|
144
157
|
requireText("examples/fixtures/README.md", /fixtures:report/, "fixture coverage report guidance");
|
|
145
158
|
requireText("examples/fixtures/README.md", /fixtures:report -- --markdown/, "Markdown fixture report guidance");
|
|
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");
|
|
161
|
+
requireText("examples/ci/adoption-smoke.yml", /npx -y memento-mori-jester@latest doctor/, "adoption smoke doctor command");
|
|
162
|
+
requireText("examples/ci/adoption-smoke.yml", /summary --kind command "git reset --hard"/, "adoption smoke summary command");
|
|
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");
|
|
146
167
|
requireText("examples/tuning/README.md", /framework-tuning-cookbook\.json/, "framework tuning cookbook JSON link");
|
|
147
168
|
requireText("examples/tuning/README.md", /framework:tuning:doctor/, "framework tuning doctor guidance");
|
|
148
169
|
requireText("examples/tuning/README.md", /jester tune <rule-id> --json|jester tune [a-z0-9-]+ --json/, "framework tuning command guidance");
|
|
@@ -164,10 +185,18 @@ requireText("scripts/doctor-framework-tuning.mjs", /dist.*cli\.js|cliPath/, "bui
|
|
|
164
185
|
requireText("scripts/doctor-framework-tuning.mjs", /config.*init|config", "init"/, "generated preset config doctor");
|
|
165
186
|
requireText("scripts/doctor-framework-tuning.mjs", /tune.*--json|tune", ruleId, "--json"/, "tune JSON doctor command");
|
|
166
187
|
forbidText("scripts/doctor-framework-tuning.mjs", /src\/config\.ts|src\/types\.ts/, "source-only framework tuning doctor dependencies");
|
|
188
|
+
requireText("scripts/check-ci-adoption.mjs", /adoption-smoke\.yml/, "adoption smoke checker target");
|
|
189
|
+
requireText("scripts/check-ci-adoption.mjs", /pull_request_target/, "adoption smoke unsafe trigger guard");
|
|
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");
|
|
167
194
|
requireText("package.json", /"fixtures:check": "node scripts\/check-fixtures\.mjs"/, "fixture authoring check script");
|
|
168
195
|
requireText("package.json", /"fixtures:report": "node scripts\/report-fixtures\.mjs"/, "fixture coverage report script");
|
|
169
196
|
requireText("package.json", /"framework:tuning:check": "node scripts\/check-framework-tuning\.mjs"/, "framework tuning cookbook check script");
|
|
170
197
|
requireText("package.json", /"framework:tuning:doctor": "node scripts\/doctor-framework-tuning\.mjs"/, "framework tuning cookbook doctor script");
|
|
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");
|
|
171
200
|
requireText("package.json", /"promo:card": "node scripts\/render-social-card\.mjs"/, "social card render script");
|
|
172
201
|
requireText("package.json", /"promo:card:check": "node scripts\/render-social-card\.mjs --check"/, "social card stale check script");
|
|
173
202
|
requireText("package.json", /"promo:check": "node scripts\/check-promo-freshness\.mjs"/, "promo freshness check script");
|
|
@@ -176,6 +205,8 @@ requireText("package.json", /npm run fixtures:check/, "fixture authoring check i
|
|
|
176
205
|
requireText("package.json", /npm run fixtures:report/, "fixture coverage report in npm test");
|
|
177
206
|
requireText("package.json", /npm run framework:tuning:check/, "framework tuning cookbook check in npm test");
|
|
178
207
|
requireText("package.json", /npm run framework:tuning:doctor/, "framework tuning cookbook doctor in npm test");
|
|
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");
|
|
179
210
|
requireText("package.json", /npm run promo:check/, "promo freshness check in npm test");
|
|
180
211
|
requireText("package.json", /npm run site:check/, "site check in npm test");
|
|
181
212
|
requireText("scripts/check-promo-freshness.mjs", /--require-package-version/, "optional strict package-version promo check");
|