demo-this-pr 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Carlos Miret
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,289 @@
1
+ <p align="center">
2
+ <img src="./assets/demo-this-pr-logo.svg" alt="DEMO THIS PR animated wordmark" width="920">
3
+ </p>
4
+
5
+ # demo-this-pr
6
+
7
+ `demo-this-pr` records the current local change before you open a pull request. Run one command from a working tree, get an isolated Chromium demo, a local MP4 with cursor/highlight overlays, captured test output, and a review report that explains what changed.
8
+
9
+ It is not an AI detector. It is a PR-quality tool for avoiding vague descriptions, missing demos, and unverifiable testing claims.
10
+
11
+ ## One Command
12
+
13
+ Run this from the repository that has local or unpushed changes:
14
+
15
+ ```bash
16
+ demo-this-pr
17
+ ```
18
+
19
+ Or point it at a repository from anywhere:
20
+
21
+ ```bash
22
+ demo-this-pr --cwd /path/to/repository
23
+ # or
24
+ demo-this-pr /path/to/repository
25
+ ```
26
+
27
+ The command will:
28
+
29
+ - detect branch changes, including uncommitted files;
30
+ - start the repository dev server when a `dev` script exists;
31
+ - otherwise use a reachable local app on a common localhost port;
32
+ - open isolated Playwright Chromium, never the user's normal Chrome profile;
33
+ - record a slow local MP4 with captions, cursor movement, and highlighted elements;
34
+ - run inferred safe test commands from `package.json`;
35
+ - open a local report so the user can press play immediately;
36
+ - write artifacts into a unique directory under `.demo-this-pr/runs/`.
37
+
38
+ Each execution gets its own run directory, for example:
39
+
40
+ ```text
41
+ .demo-this-pr/runs/20260515-164322-381-my-feature/
42
+ ```
43
+
44
+ The run label comes from the current branch, then `package.json` `name`, then the folder name. Non-meaningful Git labels such as `HEAD` or `unknown` are not used in generated directory names. Artifacts from previous runs are not overwritten unless you explicitly pass `--output`.
45
+
46
+ ## Installation
47
+
48
+ During local development of this tool:
49
+
50
+ ```bash
51
+ npm install
52
+ npm run build
53
+ npm link
54
+ ```
55
+
56
+ After publishing to npm, the intended installation paths are:
57
+
58
+ ```bash
59
+ npm install -g demo-this-pr
60
+ ```
61
+
62
+ or per repository:
63
+
64
+ ```bash
65
+ npm install --save-dev demo-this-pr
66
+ npx demo-this-pr
67
+ ```
68
+
69
+ For CI or agent runners, prefer a pinned package version and a deterministic
70
+ artifact directory:
71
+
72
+ ```bash
73
+ npx demo-this-pr@0.1.0 ci
74
+ ```
75
+
76
+ The command exits non-zero when Git context or a reachable local app is missing.
77
+ CI systems can archive `.demo-this-pr/ci/` as a build artifact after the command
78
+ finishes.
79
+
80
+ ## Publishing From A Private Repository
81
+
82
+ The source repository can remain private. The lowest-friction public distribution path is a public npm package named `demo-this-pr` that ships only the compiled CLI, assets, README, package metadata, and license.
83
+
84
+ Recommended package surface:
85
+
86
+ - npm package: `demo-this-pr`.
87
+ - CLI binary: `demo-this-pr`.
88
+ - Optional short alias: `demo-pr`.
89
+ - Public files: `dist/`, `assets/`, `README.md`, `package.json`, and `LICENSE`.
90
+ - Private files: source history, local `.demo-this-pr/` runs, generated videos, and internal planning notes.
91
+
92
+ When the repository is private, avoid public npm metadata that points to private GitHub issues or a private README URL. Add `repository`, `bugs`, and `homepage` later if there is a public docs site, public landing page, or public mirror.
93
+
94
+ Pre-publish checks:
95
+
96
+ ```bash
97
+ npm run publish:check
98
+ npm publish
99
+ ```
100
+
101
+ `npm run publish:check` builds the TypeScript output, runs tests, and verifies
102
+ the package contents with `npm pack --dry-run`.
103
+
104
+ ## Requirements
105
+
106
+ Runtime requirements:
107
+
108
+ - Node.js `>=20`.
109
+ - Git CLI available in `PATH`.
110
+ - A Git working tree; uncommitted files are supported.
111
+ - Run the command from inside the repository that contains the changes, or pass `--cwd <repo>` / `[repo]`. The automatic flow exits if Git context is unavailable instead of generating a generic report.
112
+ - A local web application reachable by HTTP.
113
+ - Playwright Chromium installed for the machine running the tool.
114
+
115
+ Target project requirements:
116
+
117
+ - Best case: a `package.json` with a `dev` script that prints a localhost URL.
118
+ - Supported package managers for auto-start: npm, pnpm, Yarn, and Bun.
119
+ - Supported app URLs for fallback detection include common localhost ports: `3000`, `3001`, `5173`, `4173`, `4321`, `8080`, and `8000`.
120
+ - Optional test scripts: `test:ci`, `test`, `typecheck`, and `lint`.
121
+
122
+ If Chromium is missing, install it once:
123
+
124
+ ```bash
125
+ npx playwright install chromium
126
+ ```
127
+
128
+ ## Technical Stack
129
+
130
+ `demo-this-pr` is a Node.js CLI implemented in TypeScript.
131
+
132
+ Core stack:
133
+
134
+ - TypeScript with ESM output.
135
+ - Node.js `child_process` for dev-server and test-command orchestration.
136
+ - Git CLI for branch, base, commit, and working-tree metadata.
137
+ - Commander for CLI parsing.
138
+ - Playwright for isolated Chromium automation, local video capture, screenshots, and report playback.
139
+ - `ffmpeg-static` for WebM-to-MP4 conversion.
140
+ - `picocolors` for terminal output.
141
+ - Vitest for unit tests.
142
+
143
+ Runtime architecture:
144
+
145
+ - `src/auto.ts` detects repository context, starts or discovers the local app, infers tests, and builds the default demo plan.
146
+ - `src/playwright.ts` records the Chromium demo, renders overlays, captures screenshots, and converts video to MP4.
147
+ - `src/prKit.ts` writes the review kit.
148
+ - `src/report.ts` renders Markdown and HTML reports.
149
+ - `src/viewer.ts` opens the generated HTML report in isolated Chromium and exits when the viewer closes.
150
+
151
+ No LLM or external API is required.
152
+
153
+ ## Output
154
+
155
+ A normal run writes:
156
+
157
+ ```text
158
+ .demo-this-pr/runs/<run-id>/
159
+ PR_REVIEW.md
160
+ PR_REVIEW.html
161
+ MCP_PLAYWRIGHT.md
162
+ mcp-playwright-demo.js
163
+ demo-plan.json
164
+ pr-demo.spec.ts
165
+ playwright.config.ts
166
+ assets/
167
+ demo-this-pr.mp4
168
+ demo-this-pr.webm
169
+ screenshots/
170
+ mcp-screenshots/
171
+ test-results/
172
+ ```
173
+
174
+ The generated video is local review evidence. `.demo-this-pr/` is ignored by git and the MP4 is not uploaded automatically.
175
+
176
+ ## Common Commands
177
+
178
+ Generate and open the report:
179
+
180
+ ```bash
181
+ demo-this-pr
182
+ ```
183
+
184
+ Generate without opening the report viewer:
185
+
186
+ ```bash
187
+ demo-this-pr --no-open
188
+ ```
189
+
190
+ Run without a visible browser window:
191
+
192
+ ```bash
193
+ demo-this-pr --headless
194
+ ```
195
+
196
+ Write to an explicit directory:
197
+
198
+ ```bash
199
+ demo-this-pr --output .demo-this-pr/manual-checkout-demo
200
+ ```
201
+
202
+ Generate in CI without a visible browser or report viewer:
203
+
204
+ ```bash
205
+ demo-this-pr ci
206
+ ```
207
+
208
+ Jenkins example:
209
+
210
+ ```groovy
211
+ stage('PR demo') {
212
+ steps {
213
+ sh 'npm ci'
214
+ sh 'npx demo-this-pr@0.1.0 ci'
215
+ }
216
+ post {
217
+ always {
218
+ archiveArtifacts artifacts: '.demo-this-pr/ci/**', allowEmptyArchive: true
219
+ }
220
+ }
221
+ }
222
+ ```
223
+
224
+ `demo-this-pr ci` starts the repository `dev` script when one exists. If the
225
+ application needs a non-standard start command, start it in the pipeline and run
226
+ the explicit `demo` command with `--url`.
227
+
228
+ Use an explicit flow:
229
+
230
+ ```bash
231
+ demo-this-pr demo \
232
+ --url http://localhost:3000 \
233
+ --feature "Project creation flow" \
234
+ --why "Users can create projects without leaving the dashboard" \
235
+ --change "Project creation now happens inline" \
236
+ --tech "Next.js server actions and React form state" \
237
+ --step "goto:/dashboard" \
238
+ --step "click:text=New project" \
239
+ --step "fill:input[name=name]:Demo Project" \
240
+ --step "click:text=Create" \
241
+ --step "expect:Demo Project" \
242
+ --test "npm test"
243
+ ```
244
+
245
+ ## Demo Step DSL
246
+
247
+ ```text
248
+ goto:/path
249
+ click:text=Button label
250
+ fill:input[name=email]:user@example.com
251
+ press:input[name=q]:Enter
252
+ expect:Expected text on screen
253
+ screenshot:after-action
254
+ wait:500
255
+ ```
256
+
257
+ For richer demos, generate a JSON plan:
258
+
259
+ ```bash
260
+ demo-this-pr init-demo --output demo-this-pr.demo.json
261
+ ```
262
+
263
+ Then run:
264
+
265
+ ```bash
266
+ demo-this-pr demo --demo-plan demo-this-pr.demo.json
267
+ ```
268
+
269
+ ## Playwright MCP
270
+
271
+ Every run also writes an MCP-first browser verification guide:
272
+
273
+ ```text
274
+ MCP_PLAYWRIGHT.md
275
+ mcp-playwright-demo.js
276
+ ```
277
+
278
+ Agents with Playwright MCP can load `mcp-playwright-demo.js` through `mcp__playwright__.browser_run_code_unsafe`, run the same browser flow, capture screenshots, and close the MCP tab afterwards.
279
+
280
+ ## Development
281
+
282
+ ```bash
283
+ npm install
284
+ npm run build
285
+ npm test
286
+ npm run check
287
+ ```
288
+
289
+ The repository includes a root `AGENTS.md` with the local browser-testing policy and implementation standards for future agents.
@@ -0,0 +1,41 @@
1
+ <svg width="1200" height="330" viewBox="0 0 1200 330" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
2
+ <title id="title">DEMO THIS PR animated wordmark</title>
3
+ <desc id="desc">Animated terminal-style wordmark reading DEMO THIS PR.</desc>
4
+ <defs>
5
+ <linearGradient id="bg" x1="0" y1="0" x2="1200" y2="330" gradientUnits="userSpaceOnUse">
6
+ <stop offset="0" stop-color="#0B0F14"/>
7
+ <stop offset="0.58" stop-color="#111820"/>
8
+ <stop offset="1" stop-color="#171D24"/>
9
+ </linearGradient>
10
+ <linearGradient id="ink" x1="90" y1="0" x2="1090" y2="0" gradientUnits="userSpaceOnUse">
11
+ <stop offset="0" stop-color="#F8FAFC"/>
12
+ <stop offset="0.55" stop-color="#E7EEF7"/>
13
+ <stop offset="1" stop-color="#B9C7D7"/>
14
+ </linearGradient>
15
+ <filter id="shadow" x="-10%" y="-40%" width="120%" height="190%">
16
+ <feDropShadow dx="8" dy="8" stdDeviation="0" flood-color="#748094" flood-opacity="0.42"/>
17
+ <feDropShadow dx="13" dy="13" stdDeviation="0" flood-color="#334155" flood-opacity="0.5"/>
18
+ <feDropShadow dx="0" dy="22" stdDeviation="18" flood-color="#000000" flood-opacity="0.4"/>
19
+ </filter>
20
+ </defs>
21
+
22
+ <rect x="32" y="34" width="1136" height="262" rx="18" fill="url(#bg)"/>
23
+ <rect x="32" y="34" width="1136" height="262" rx="18" stroke="#2B3542" stroke-width="2"/>
24
+
25
+ <text x="78" y="82" fill="#91A4BA" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace" font-size="17" font-weight="800" letter-spacing="4">LOCAL PR DEMOS · PLAYWRIGHT MP4 · REVIEW EVIDENCE</text>
26
+
27
+ <g filter="url(#shadow)" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace" font-size="104" font-weight="950" letter-spacing="0" fill="url(#ink)">
28
+ <g><text x="78" y="202">D</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -11;0 0" dur="2.8s" begin="0s" repeatCount="indefinite"/></g>
29
+ <g><text x="145" y="202">E</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -9;0 0" dur="2.8s" begin="0.08s" repeatCount="indefinite"/></g>
30
+ <g><text x="212" y="202">M</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -13;0 0" dur="2.8s" begin="0.16s" repeatCount="indefinite"/></g>
31
+ <g><text x="296" y="202">O</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -10;0 0" dur="2.8s" begin="0.24s" repeatCount="indefinite"/></g>
32
+ <g><text x="410" y="202">T</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -8;0 0" dur="2.8s" begin="0.32s" repeatCount="indefinite"/></g>
33
+ <g><text x="477" y="202">H</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -12;0 0" dur="2.8s" begin="0.4s" repeatCount="indefinite"/></g>
34
+ <g><text x="544" y="202">I</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -9;0 0" dur="2.8s" begin="0.48s" repeatCount="indefinite"/></g>
35
+ <g><text x="611" y="202">S</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -13;0 0" dur="2.8s" begin="0.56s" repeatCount="indefinite"/></g>
36
+ <g><text x="728" y="202">P</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -10;0 0" dur="2.8s" begin="0.64s" repeatCount="indefinite"/></g>
37
+ <g><text x="795" y="202">R</text><animateTransform attributeName="transform" type="translate" values="0 0;0 -12;0 0" dur="2.8s" begin="0.72s" repeatCount="indefinite"/></g>
38
+ </g>
39
+
40
+ <text x="78" y="264" fill="#91A4BA" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace" font-size="17" font-weight="800" letter-spacing="2">SHOW THE CHANGE BEFORE THE PULL REQUEST</text>
41
+ </svg>
package/dist/auto.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import type { GitFileChange, PrKitOptions } from "./types.js";
2
+ export interface AutoDemoResult {
3
+ options: PrKitOptions;
4
+ cleanup(): Promise<void>;
5
+ notes: string[];
6
+ }
7
+ export declare function resolveAutoDemo(cwd: string, overrides: {
8
+ headless: boolean;
9
+ output?: string;
10
+ open: boolean;
11
+ }): Promise<AutoDemoResult>;
12
+ export declare function titleForAutoRun(input: {
13
+ gitAvailable?: boolean;
14
+ branch: string;
15
+ commits: string[];
16
+ changedFiles: GitFileChange[];
17
+ }): string;