diff --git a/README.md b/README.md index 7750366..e371c0f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,13 @@ Run shell commands from natural-language requests: jst find all files bigger than 500 mb in ~/downloads ``` +

+ A randomly selected jst terminal demo +

+ +The demo above is randomly selected on each fresh image request. It is recorded +from a real `jst` run; [see every demo](docs/demos/). + ## Install ### Homebrew diff --git a/docs/demos/changed-today.gif b/docs/demos/changed-today.gif new file mode 100644 index 0000000..097eaf0 Binary files /dev/null and b/docs/demos/changed-today.gif differ diff --git a/docs/demos/changed-today.tape b/docs/demos/changed-today.tape new file mode 100644 index 0000000..ff29338 --- /dev/null +++ b/docs/demos/changed-today.tape @@ -0,0 +1,32 @@ +Output docs/demos/changed-today.gif + +Require jst + +Set Shell "zsh" +Set FontFamily "Monaco" +Set FontSize 18 +Set Width 1120 +Set Height 560 +Set Padding 28 +Set Margin 34 +Set MarginFill "#f3efe6" +Set BorderRadius 14 +Set WindowBar "Colorful" +Set WindowBarSize 38 +Set Theme "Catppuccin Mocha" +Set TypingSpeed 34ms +Set Framerate 30 +Set PlaybackSpeed 1.15 + +Hide +Type `unset NO_COLOR; export COLUMNS=80; export PS1=$'\n❯ '` +Enter +Type "mkdir -p /tmp/jst-demo-changed; cd /tmp/jst-demo-changed; touch draft.md deploy.log; touch -t 202501010000 old-notes.txt" +Enter +Ctrl+L +Show + +Type "jst find every file changed in the last 24 hours" +Enter +Sleep 5s +Sleep 2s diff --git a/docs/demos/clear-port-8080.gif b/docs/demos/clear-port-8080.gif new file mode 100644 index 0000000..842758a Binary files /dev/null and b/docs/demos/clear-port-8080.gif differ diff --git a/docs/demos/clear-port-8080.tape b/docs/demos/clear-port-8080.tape new file mode 100644 index 0000000..9c856c2 --- /dev/null +++ b/docs/demos/clear-port-8080.tape @@ -0,0 +1,38 @@ +Output docs/demos/clear-port-8080.gif + +Require jst + +Set Shell "zsh" +Set FontFamily "Monaco" +Set FontSize 18 +Set Width 1120 +Set Height 720 +Set Padding 28 +Set Margin 34 +Set MarginFill "#f3efe6" +Set BorderRadius 14 +Set WindowBar "Colorful" +Set WindowBarSize 38 +Set Theme "Catppuccin Mocha" +Set TypingSpeed 34ms +Set Framerate 30 +Set PlaybackSpeed 1.15 + +Hide +Type `unset NO_COLOR; export COLUMNS=80; export PS1=$'\n❯ '` +Enter +Type "python3 -m http.server 8080 >/dev/null 2>&1 &" +Enter +Sleep 1s +Ctrl+L +Show + +Type "jst stop whatever is using port 8080" +Enter +Sleep 7s +Type "y" +Enter +Sleep 2s +Type "lsof -nP -iTCP:8080 -sTCP:LISTEN || echo 'port 8080 is free'" +Enter +Sleep 2s diff --git a/docs/demos/remove-ds-store.gif b/docs/demos/remove-ds-store.gif new file mode 100644 index 0000000..b348afe Binary files /dev/null and b/docs/demos/remove-ds-store.gif differ diff --git a/docs/demos/remove-ds-store.tape b/docs/demos/remove-ds-store.tape new file mode 100644 index 0000000..f905ae1 --- /dev/null +++ b/docs/demos/remove-ds-store.tape @@ -0,0 +1,34 @@ +Output docs/demos/remove-ds-store.gif + +Require jst + +Set Shell "zsh" +Set FontFamily "Monaco" +Set FontSize 18 +Set Width 1120 +Set Height 720 +Set Padding 28 +Set Margin 34 +Set MarginFill "#f3efe6" +Set BorderRadius 14 +Set WindowBar "Colorful" +Set WindowBarSize 38 +Set Theme "Catppuccin Mocha" +Set TypingSpeed 34ms +Set Framerate 30 +Set PlaybackSpeed 1.15 + +Hide +Type `unset NO_COLOR; export COLUMNS=80; export PS1=$'\n❯ '` +Enter +Type "mkdir -p /tmp/jst-demo-ds-store/nested; cd /tmp/jst-demo-ds-store; touch .DS_Store nested/.DS_Store" +Enter +Ctrl+L +Show + +Type "jst remove all .DS_Store files below the current directory" +Enter +Sleep 7s +Type "n" +Enter +Sleep 2s diff --git a/docs/demos/zip-folder.gif b/docs/demos/zip-folder.gif new file mode 100644 index 0000000..2ef44c2 Binary files /dev/null and b/docs/demos/zip-folder.gif differ diff --git a/docs/demos/zip-folder.tape b/docs/demos/zip-folder.tape new file mode 100644 index 0000000..bdc0c03 --- /dev/null +++ b/docs/demos/zip-folder.tape @@ -0,0 +1,35 @@ +Output docs/demos/zip-folder.gif + +Require jst + +Set Shell "zsh" +Set FontFamily "Monaco" +Set FontSize 18 +Set Width 1120 +Set Height 620 +Set Padding 28 +Set Margin 34 +Set MarginFill "#f3efe6" +Set BorderRadius 14 +Set WindowBar "Colorful" +Set WindowBarSize 38 +Set Theme "Catppuccin Mocha" +Set TypingSpeed 34ms +Set Framerate 30 +Set PlaybackSpeed 1.15 + +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" +Enter +Ctrl+L +Show + +Type "jst zip this folder without node_modules" +Enter +Sleep 5s +Sleep 2s +Type "unzip -l folder.zip" +Enter +Sleep 2s diff --git a/site/demo-gif.test.js b/site/demo-gif.test.js new file mode 100644 index 0000000..cc4e394 --- /dev/null +++ b/site/demo-gif.test.js @@ -0,0 +1,18 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { demoFileAt, demoRedirect } from "../workers/demo-gif.js"; + +test("the demo endpoint can select every recorded GIF", () => { + assert.equal(demoFileAt(0), "changed-today.gif"); + assert.equal(demoFileAt(1), "clear-port-8080.gif"); + assert.equal(demoFileAt(2), "remove-ds-store.gif"); + assert.equal(demoFileAt(3), "zip-folder.gif"); +}); + +test("the demo endpoint redirects without allowing the selection to be cached", () => { + const response = demoRedirect(3); + + assert.equal(response.status, 302); + assert.equal(response.headers.get("Location"), "https://jst.sh/demos/zip-folder.gif"); + assert.equal(response.headers.get("Cache-Control"), "no-store"); +}); diff --git a/workers/demo-gif.js b/workers/demo-gif.js new file mode 100644 index 0000000..c5c81ca --- /dev/null +++ b/workers/demo-gif.js @@ -0,0 +1,26 @@ +const DEMO_FILES = [ + "changed-today.gif", + "clear-port-8080.gif", + "remove-ds-store.gif", + "zip-folder.gif", +]; + +export function demoFileAt(index) { + return DEMO_FILES[index % DEMO_FILES.length]; +} + +export function demoRedirect(index) { + return new Response(null, { + status: 302, + headers: { + "Cache-Control": "no-store", + Location: `https://jst.sh/demos/${demoFileAt(index)}`, + }, + }); +} + +export default { + fetch() { + return demoRedirect(Math.floor(Math.random() * DEMO_FILES.length)); + }, +};