Skip to content

Add randomized README demos - #46

Merged
yoavf merged 6 commits into
mainfrom
agent/add-readme-demos
Aug 17, 2026
Merged

Add randomized README demos#46
yoavf merged 6 commits into
mainfrom
agent/add-readme-demos

Conversation

@yoavf

@yoavf yoavf commented Aug 17, 2026

Copy link
Copy Markdown
Owner

What changed

  • Adds four real JST demo GIFs and their VHS source tapes.
  • Embeds https://jst.sh/demo.gif at the top of the README.
  • Adds the tiny Cloudflare Worker source at workers/demo-gif.js; it randomly chooses a GIF and responds with a no-store redirect.

Why

GitHub README content cannot run JavaScript. The scoped Cloudflare Worker route, jst.sh/demo.gif, supplies the random selection while the normal site and the GIF assets remain static GitHub Pages content.

Validation

  • npm run test:demo (33 passing)
  • vhs validate docs/demos/*.tape
  • git diff --check

The deployed worker is intentionally restricted to that exact route. GitHub's image proxy may cache a selected GIF between fresh fetches.

Greptile Summary

The PR adds four recorded terminal demos, embeds a randomized demo in the README, and introduces a small redirecting Cloudflare Worker with unit coverage.

  • Adds four GIFs and their VHS source tapes under docs/demos/.
  • Adds the randomized jst.sh/demo.gif embed to the README.
  • Redirects each request to one of the statically hosted demo assets with Cache-Control: no-store.
  • Tests the available selections, redirect target, status, and cache policy.

Confidence Score: 4/5

The PR appears safe to merge, with only a non-blocking portability issue in the zip demo’s regeneration source.

The randomized redirect and static asset mapping are internally consistent, while the zip demo tape’s undeclared dependency on macOS mkfile makes that checked-in artifact difficult to reproduce on other development environments.

Files Needing Attention: docs/demos/zip-folder.tape

Important Files Changed

Filename Overview
workers/demo-gif.js Implements a constant allowlisted random GIF selection and a non-cacheable redirect; no code-level defect was identified.
site/demo-gif.test.js Covers every configured demo filename and verifies the redirect status, location, and cache policy.
README.md Adds the randomized demo embed and a link to the complete static demo collection.
docs/demos/zip-folder.tape Adds the archive demo source, but its fixture setup is not reproducible outside macOS because it depends on mkfile.
docs/demos/changed-today.tape Adds a self-contained source recording for the recently changed files demonstration.
docs/demos/clear-port-8080.tape Adds a source recording that starts a local server, confirms termination, and checks that the port is free.
docs/demos/remove-ds-store.tape Adds a source recording that safely declines the destructive confirmation prompt.

Reviews (1): Last reviewed commit: "Remove faulty largest-files demo" | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 17, 2026

Copy link
Copy Markdown

Deploying jst with  Cloudflare Pages  Cloudflare Pages

Latest commit: 02cb0e6
Status: ✅  Deploy successful!
Preview URL: https://9f165d1c.jst-5mg.pages.dev
Branch Preview URL: https://agent-add-readme-demos.jst-5mg.pages.dev

View logs

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

The macOS CLI preview for this PR is ready. With GitHub CLI authenticated, copy this one command to download and run it:

preview_dir="$(mktemp -d)" && gh run download 32019075924 --repo yoavf/jst --name jst-pr-preview-macos-universal --dir "$preview_dir" && chmod +x "$preview_dir/jst" && "$preview_dir/jst" --dry list files in the current directory

Replace the example arguments after jst to test another command. The artifact is retained for 7 days.

View the preview build

@yoavf
yoavf marked this pull request as ready for review August 17, 2026 10:14
@yoavf
yoavf merged commit 08387e3 into main Aug 17, 2026
6 checks passed
@yoavf
yoavf deleted the agent/add-readme-demos branch August 17, 2026 10:14
Hide
Type `unset NO_COLOR; export COLUMNS=80; export PS1=$'\n❯ '`
Enter
Type "mkdir -p /tmp/jst-demo-zip/folder/node_modules /tmp/jst-demo-zip/folder/src; cd /tmp/jst-demo-zip; mkfile 1m folder/src/app.js; mkfile 2m folder/node_modules/bundle.js"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 macOS-only demo fixture setup

The tape creates its fixture exclusively with the macOS-specific mkfile utility, so contributors regenerating the GIF on other platforms receive mkfile: command not found and produce an empty or misleading archive demonstration. Use a portable fixture command or explicitly declare the recording environment.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Randomize README demo GIF via scoped Cloudflare Worker redirect

✨ Enhancement 📝 Documentation 🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Embed a randomized terminal demo GIF at the top of the README.
• Add four recorded jst demo GIFs plus their VHS source tapes under docs/demos/.
• Implement and test a no-store Worker redirect at jst.sh/demo.gif to pick a demo.
Diagram

graph TD
A["README.md"] --> B["jst.sh/demo.gif (Worker)"] --> C["jst.sh/demos/<gif> (static)"] --> D[("docs/demos/*.gif")]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Serve GIF bytes directly from the Worker (no redirect)
  • ➕ May reduce the chance that intermediate caches pin a single redirected GIF
  • ➕ Allows setting response headers on the actual image payload
  • ➖ Worker must fetch/stream the GIF (higher egress + complexity)
  • ➖ More failure modes (origin fetch, partial content/range requests) than a simple redirect
2. Rotate a committed demo.gif via CI on a schedule
  • ➕ No runtime infrastructure beyond GitHub Pages/static hosting
  • ➕ Deterministic rotation cadence (e.g., daily)
  • ➖ Not truly randomized per request
  • ➖ Adds repo churn and CI write permissions; can generate noisy history
3. Use a third-party dynamic image endpoint (e.g., badge-style services)
  • ➕ Potentially zero custom infrastructure to maintain
  • ➖ Less control over caching and asset hosting
  • ➖ External dependency risk and possible styling constraints

Recommendation: Keep the current redirect-based Worker. It minimizes Worker bandwidth/complexity by keeping GIFs static, while still enabling per-request random selection. If cache stickiness becomes a real issue, consider upgrading to “serve bytes directly” as the next step.

Files changed (11) +190 / -0

Tests (1) +18 / -0
demo-gif.test.jsAdd tests for demo GIF selection and no-store redirect +18/-0

Add tests for demo GIF selection and no-store redirect

• Adds unit tests to ensure the selector can address all recorded demos and that the redirect response sets 'Cache-Control: no-store' with the expected Location.

site/demo-gif.test.js

Documentation (9) +146 / -0
README.mdEmbed randomized demo GIF and link to demo gallery +7/-0

Embed randomized demo GIF and link to demo gallery

• Adds a centered image pointing at 'https://jst.sh/demo.gif' and explains that the demo is randomly selected. Links readers to 'docs/demos/' to view all demos.

README.md

changed-today.gifAdd recorded demo GIF: “changed today” +0/-0

Add recorded demo GIF: “changed today”

• Introduces a new terminal demo GIF showing a real 'jst' run.

docs/demos/changed-today.gif

changed-today.tapeAdd VHS source tape for “changed today” demo +32/-0

Add VHS source tape for “changed today” demo

• Adds the VHS script used to record 'changed-today.gif', including terminal settings and scripted commands.

docs/demos/changed-today.tape

clear-port-8080.gifAdd recorded demo GIF: clear port 8080 +0/-0

Add recorded demo GIF: clear port 8080

• Introduces a new terminal demo GIF demonstrating freeing port 8080 via 'jst'.

docs/demos/clear-port-8080.gif

clear-port-8080.tapeAdd VHS source tape for “clear port 8080” demo +38/-0

Add VHS source tape for “clear port 8080” demo

• Adds the VHS script used to record 'clear-port-8080.gif', including starting a server on 8080 and verifying it is stopped.

docs/demos/clear-port-8080.tape

remove-ds-store.gifAdd recorded demo GIF: remove .DS_Store files +0/-0

Add recorded demo GIF: remove .DS_Store files

• Introduces a new terminal demo GIF demonstrating removing '.DS_Store' files with 'jst'.

docs/demos/remove-ds-store.gif

remove-ds-store.tapeAdd VHS source tape for “remove .DS_Store” demo +34/-0

Add VHS source tape for “remove .DS_Store” demo

• Adds the VHS script used to record 'remove-ds-store.gif', including creating sample '.DS_Store' files and running the command.

docs/demos/remove-ds-store.tape

zip-folder.gifAdd recorded demo GIF: zip folder excluding node_modules +0/-0

Add recorded demo GIF: zip folder excluding node_modules

• Introduces a new terminal demo GIF showing 'jst' creating an archive while excluding 'node_modules'.

docs/demos/zip-folder.gif

zip-folder.tapeAdd VHS source tape for “zip folder” demo +35/-0

Add VHS source tape for “zip folder” demo

• Adds the VHS script used to record 'zip-folder.gif', including creating sample folder contents and inspecting the resulting zip.

docs/demos/zip-folder.tape

Other (1) +26 / -0
demo-gif.jsImplement Worker that randomly redirects to a demo GIF +26/-0

Implement Worker that randomly redirects to a demo GIF

• Adds a minimal Worker that selects a demo filename from a fixed list and returns a 302 redirect to 'https://jst.sh/demos/<gif>' with 'Cache-Control: no-store'. Exposes helper functions for deterministic testing.

workers/demo-gif.js

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Undefined redirect target 🐞 Bug ≡ Correctness
Description
demoFileAt uses a raw modulo result as an array index, so negative/NaN/non-integer inputs (or a
future empty DEMO_FILES) return undefined and demoRedirect will emit Location:
https://jst.sh/demos/undefined. That produces broken redirects and makes the exported helpers unsafe
for reuse beyond the current Math.floor(Math.random()) callsite.
Code

workers/demo-gif.js[R8-10]

+export function demoFileAt(index) {
+  return DEMO_FILES[index % DEMO_FILES.length];
+}
Evidence
demoFileAt indexes the array with index % DEMO_FILES.length and demoRedirect interpolates that
return value directly into the Location header, so any undefined selection becomes a malformed
redirect URL.

workers/demo-gif.js[8-19]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`demoFileAt(index)` can return `undefined` for invalid indices (negative, NaN, non-integer) or if the list is ever emptied, and `demoRedirect` will then generate a broken `Location` header.

### Issue Context
These helpers are exported and already imported by unit tests, so they are part of a reusable API surface.

### Fix Focus Areas
- workers/demo-gif.js[1-20]

### Suggested change
- Guard against an empty `DEMO_FILES`.
- Coerce `index` to a finite integer and normalize negatives before indexing.
- Optionally throw (or default to 0) when `index` is invalid so bad calls fail loudly instead of redirecting to `/undefined`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. JS tests not in CI 🐞 Bug ⚙ Maintainability
Description
This PR adds a Node test file for the demo-gif Worker, but the GitHub Actions workflows shown do not
run any Node/npm test command, so these new tests won’t execute in CI and regressions to the worker
behavior can merge undetected.
Code

site/demo-gif.test.js[R1-3]

+import assert from "node:assert/strict";
+import test from "node:test";
+import { demoFileAt, demoRedirect } from "../workers/demo-gif.js";
Evidence
The test file is newly added and runnable via the existing test:demo script, but the main CI
workflow only runs cargo commands and contains no Node/npm execution, so these tests won’t run in CI
as-is.

site/demo-gif.test.js[1-18]
package.json[5-9]
.github/workflows/ci.yml[16-30]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The newly-added Node tests under `site/*.test.js` are not exercised by existing GitHub Actions workflows.

### Issue Context
`package.json` defines `test:demo` as `node --test site/*.test.js`, but `.github/workflows/ci.yml` only runs Rust checks.

### Fix Focus Areas
- site/demo-gif.test.js[1-18]
- package.json[5-9]
- .github/workflows/ci.yml[16-30]

### Suggested change
- Add a CI job/steps to install Node (actions/setup-node), run `npm ci`, then `npm run test:demo`.
- Optionally cache npm to keep CI fast.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. No method/path guarding 🐞 Bug ☼ Reliability
Description
The Worker fetch handler ignores the incoming Request, so it returns the same 302 redirect for any
HTTP method and for any path the Worker is routed to. This increases blast radius if the route is
ever broadened/misconfigured, because unrelated requests would start redirecting to demo GIFs.
Code

workers/demo-gif.js[R22-25]

+export default {
+  fetch() {
+    return demoRedirect(Math.floor(Math.random() * DEMO_FILES.length));
+  },
Evidence
The exported default fetch() has no request parameter and performs no checks before returning a
redirect, so behavior is identical for all requests that reach the Worker.

workers/demo-gif.js[22-25]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Worker responds with a demo redirect unconditionally; it does not validate HTTP method or pathname.

### Issue Context
Even if deployment is intended to be scoped to `/demo.gif`, adding an in-code check is a cheap defense-in-depth measure against accidental route changes.

### Fix Focus Areas
- workers/demo-gif.js[22-26]

### Suggested change
- Accept `request` in `fetch(request)`.
- If `request.method` is not `GET`/`HEAD`, return `405`.
- If `new URL(request.url).pathname` is not `/demo.gif`, return `404` (or similar).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context
Review mode: ⚖️ Balanced: This adds a small, scoped worker plus README/demo assets; although it touches multiple files, the logic is limited to one route and is not dense enough to justify redundant review passes.

Grey Divider

Tip of the day
💡 Did you know, you can route each action level your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread workers/demo-gif.js
Comment on lines +8 to +10
export function demoFileAt(index) {
return DEMO_FILES[index % DEMO_FILES.length];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Undefined redirect target 🐞 Bug ≡ Correctness

demoFileAt uses a raw modulo result as an array index, so negative/NaN/non-integer inputs (or a
future empty DEMO_FILES) return undefined and demoRedirect will emit Location:
https://jst.sh/demos/undefined. That produces broken redirects and makes the exported helpers unsafe
for reuse beyond the current Math.floor(Math.random()) callsite.
Agent Prompt
### Issue description
`demoFileAt(index)` can return `undefined` for invalid indices (negative, NaN, non-integer) or if the list is ever emptied, and `demoRedirect` will then generate a broken `Location` header.

### Issue Context
These helpers are exported and already imported by unit tests, so they are part of a reusable API surface.

### Fix Focus Areas
- workers/demo-gif.js[1-20]

### Suggested change
- Guard against an empty `DEMO_FILES`.
- Coerce `index` to a finite integer and normalize negatives before indexing.
- Optionally throw (or default to 0) when `index` is invalid so bad calls fail loudly instead of redirecting to `/undefined`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread workers/demo-gif.js
Comment on lines +22 to +25
export default {
fetch() {
return demoRedirect(Math.floor(Math.random() * DEMO_FILES.length));
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informational

2. No method/path guarding 🐞 Bug ☼ Reliability

The Worker fetch handler ignores the incoming Request, so it returns the same 302 redirect for any
HTTP method and for any path the Worker is routed to. This increases blast radius if the route is
ever broadened/misconfigured, because unrelated requests would start redirecting to demo GIFs.
Agent Prompt
### Issue description
The Worker responds with a demo redirect unconditionally; it does not validate HTTP method or pathname.

### Issue Context
Even if deployment is intended to be scoped to `/demo.gif`, adding an in-code check is a cheap defense-in-depth measure against accidental route changes.

### Fix Focus Areas
- workers/demo-gif.js[22-26]

### Suggested change
- Accept `request` in `fetch(request)`.
- If `request.method` is not `GET`/`HEAD`, return `405`.
- If `new URL(request.url).pathname` is not `/demo.gif`, return `404` (or similar).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread site/demo-gif.test.js
Comment on lines +1 to +3
import assert from "node:assert/strict";
import test from "node:test";
import { demoFileAt, demoRedirect } from "../workers/demo-gif.js";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Js tests not in ci 🐞 Bug ⚙ Maintainability

This PR adds a Node test file for the demo-gif Worker, but the GitHub Actions workflows shown do not
run any Node/npm test command, so these new tests won’t execute in CI and regressions to the worker
behavior can merge undetected.
Agent Prompt
### Issue description
The newly-added Node tests under `site/*.test.js` are not exercised by existing GitHub Actions workflows.

### Issue Context
`package.json` defines `test:demo` as `node --test site/*.test.js`, but `.github/workflows/ci.yml` only runs Rust checks.

### Fix Focus Areas
- site/demo-gif.test.js[1-18]
- package.json[5-9]
- .github/workflows/ci.yml[16-30]

### Suggested change
- Add a CI job/steps to install Node (actions/setup-node), run `npm ci`, then `npm run test:demo`.
- Optionally cache npm to keep CI fast.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant