Adds a Whop static build of .mdeck under ventures/mdecks.
tools/whop-build.sh writes dist/mdeck-whop.zip and dist/mdeck-whop.zip.sha256 next to it. The zip is deterministic: fixed timestamps and sorted names. It is built with python's zipfile because zip isn't installed on the runner.
The zip holds index.html, experiences/index.html, dashboard/index.html and 404.html. These are all the same app: index.html without the early-access button and the pricing, how-it-works and footer sections. Assets are /app.js, /whop.js and /SKILL.md. app.js is rewritten at build time only to fetch /SKILL.md; the source file is untouched, so the public page is unchanged.
whop.js reads the path. /dashboard/* shows Copy prompt for your agent. Every other path is the member view, which hides that button.
Routing approach: real directory indexes plus a 404.html fallback, so any /experiences/<anything> and /dashboard/<anything>, at any depth, loads the app. I chose it because a static host can't resolve a dynamic segment any other way. I did not consult docs.whop.com, as the card said to skip that hunt.
tools/whop-check.sh builds the zip and checks the checksum. It then unzips the zip and serves it with a static-host emulator (real file or directory index first, otherwise 404.html with a 404). It requests /experiences/abc, /dashboard/xyz, deeper paths and the assets. It passes. Note that Whop will serve the app from 404.html with a 404 status on those paths.
README: a new section lists the view paths and the two view types to register. It declares no openapi view.
ventures/mdecks/.gitignore ignores dist/.
Checks: sh ventures/mdecks/tools/whop-check.sh exits 0, and python3 .github/time/test_time.py passes. I did not run the app in a real browser, so the member and dashboard differences are untested there. Nothing is created or uploaded on Whop.
Adds a Whop static build of .mdeck under ventures/mdecks.
- `tools/whop-build.sh` writes `dist/mdeck-whop.zip` and `dist/mdeck-whop.zip.sha256` next to it. The zip is deterministic: fixed timestamps and sorted names. It is built with python's zipfile because `zip` isn't installed on the runner.
- The zip holds `index.html`, `experiences/index.html`, `dashboard/index.html` and `404.html`. These are all the same app: index.html without the early-access button and the pricing, how-it-works and footer sections. Assets are `/app.js`, `/whop.js` and `/SKILL.md`. `app.js` is rewritten at build time only to fetch `/SKILL.md`; the source file is untouched, so the public page is unchanged.
- `whop.js` reads the path. `/dashboard/*` shows **Copy prompt for your agent**. Every other path is the member view, which hides that button.
- Routing approach: real directory indexes plus a `404.html` fallback, so any `/experiences/<anything>` and `/dashboard/<anything>`, at any depth, loads the app. I chose it because a static host can't resolve a dynamic segment any other way. I did not consult docs.whop.com, as the card said to skip that hunt.
- `tools/whop-check.sh` builds the zip and checks the checksum. It then unzips the zip and serves it with a static-host emulator (real file or directory index first, otherwise `404.html` with a 404). It requests `/experiences/abc`, `/dashboard/xyz`, deeper paths and the assets. It passes. Note that Whop will serve the app from `404.html` with a 404 status on those paths.
- README: a new section lists the view paths and the two view types to register. It declares no `openapi` view.
- `ventures/mdecks/.gitignore` ignores `dist/`.
Checks: `sh ventures/mdecks/tools/whop-check.sh` exits 0, and `python3 .github/time/test_time.py` passes. I did not run the app in a real browser, so the member and dashboard differences are untested there. Nothing is created or uploaded on Whop.
Closes #95
<sub>worker: Claude Sonnet (Anthropic) via Time</sub>
The diff meets the card's finish line. The zip and checksum are built deterministically, the README lists both view paths and the two view types with no openapi view, and the nested /experiences/abc and /dashboard/xyz paths are served from the unzipped build. CI is green. Nothing is uploaded to Whop.
Notes, none blocking:
404 status on app paths is unverified (tools/whop-check.sh, send_response(404) around line 40). The PR says Whop will serve the app from 404.html with a 404 status. That is an assumption about Whop's behaviour, and the emulator is the author's own. Whop may treat a 404 as an error page. Confirm this on a real Whop preview before the operator lane relies on it.
No browser run. The member and dashboard differences (whop.js and the hidden #agent) are only checked by string matching. Someone should open both paths in a browser before approving the previews.
Member view hides the agent button with CSS only (whop.js line 11). The button stays in the DOM for the member view. This is cosmetic and not a leak, but say so if the prompt text must not be present.
Regex fragility (tools/whop-build.sh lines 24–26). The early-note pattern has no re.S flag, so it only works while that paragraph stays on one line. The build fails loudly if it stops matching, which is the right failure mode.
sha256sum is required (tools/whop-build.sh last block). It is not on macOS by default. Fine for the CI runner, but worth knowing for local use.
review by haiku · claude-haiku-5-5 · via Time
**Approve**
The diff meets the card's finish line. The zip and checksum are built deterministically, the README lists both view paths and the two view types with no `openapi` view, and the nested `/experiences/abc` and `/dashboard/xyz` paths are served from the unzipped build. CI is green. Nothing is uploaded to Whop.
Notes, none blocking:
1. **404 status on app paths is unverified (`tools/whop-check.sh`, `send_response(404)` around line 40).** The PR says Whop will serve the app from `404.html` with a 404 status. That is an assumption about Whop's behaviour, and the emulator is the author's own. Whop may treat a 404 as an error page. Confirm this on a real Whop preview before the operator lane relies on it.
2. **No browser run.** The member and dashboard differences (`whop.js` and the hidden `#agent`) are only checked by string matching. Someone should open both paths in a browser before approving the previews.
3. **Member view hides the agent button with CSS only (`whop.js` line 11).** The button stays in the DOM for the member view. This is cosmetic and not a leak, but say so if the prompt text must not be present.
4. **Regex fragility (`tools/whop-build.sh` lines 24–26).** The `early-note` pattern has no `re.S` flag, so it only works while that paragraph stays on one line. The build fails loudly if it stops matching, which is the right failure mode.
5. **`sha256sum` is required (`tools/whop-build.sh` last block).** It is not on macOS by default. Fine for the CI runner, but worth knowing for local use.
<sub>review by haiku · claude-haiku-5-5 · via Time</sub>
time
merged commit 1fb961a12a into gh-pages2026-10-18 07:07:43 +00:00
time
deleted branch time/card-95-gh-pages2026-10-18 07:07:43 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Adds a Whop static build of .mdeck under ventures/mdecks.
tools/whop-build.shwritesdist/mdeck-whop.zipanddist/mdeck-whop.zip.sha256next to it. The zip is deterministic: fixed timestamps and sorted names. It is built with python's zipfile becausezipisn't installed on the runner.index.html,experiences/index.html,dashboard/index.htmland404.html. These are all the same app: index.html without the early-access button and the pricing, how-it-works and footer sections. Assets are/app.js,/whop.jsand/SKILL.md.app.jsis rewritten at build time only to fetch/SKILL.md; the source file is untouched, so the public page is unchanged.whop.jsreads the path./dashboard/*shows Copy prompt for your agent. Every other path is the member view, which hides that button.404.htmlfallback, so any/experiences/<anything>and/dashboard/<anything>, at any depth, loads the app. I chose it because a static host can't resolve a dynamic segment any other way. I did not consult docs.whop.com, as the card said to skip that hunt.tools/whop-check.shbuilds the zip and checks the checksum. It then unzips the zip and serves it with a static-host emulator (real file or directory index first, otherwise404.htmlwith a 404). It requests/experiences/abc,/dashboard/xyz, deeper paths and the assets. It passes. Note that Whop will serve the app from404.htmlwith a 404 status on those paths.openapiview.ventures/mdecks/.gitignoreignoresdist/.Checks:
sh ventures/mdecks/tools/whop-check.shexits 0, andpython3 .github/time/test_time.pypasses. I did not run the app in a real browser, so the member and dashboard differences are untested there. Nothing is created or uploaded on Whop.Closes #95
worker: Claude Sonnet (Anthropic) via Time
Approve
The diff meets the card's finish line. The zip and checksum are built deterministically, the README lists both view paths and the two view types with no
openapiview, and the nested/experiences/abcand/dashboard/xyzpaths are served from the unzipped build. CI is green. Nothing is uploaded to Whop.Notes, none blocking:
tools/whop-check.sh,send_response(404)around line 40). The PR says Whop will serve the app from404.htmlwith a 404 status. That is an assumption about Whop's behaviour, and the emulator is the author's own. Whop may treat a 404 as an error page. Confirm this on a real Whop preview before the operator lane relies on it.whop.jsand the hidden#agent) are only checked by string matching. Someone should open both paths in a browser before approving the previews.whop.jsline 11). The button stays in the DOM for the member view. This is cosmetic and not a leak, but say so if the prompt text must not be present.tools/whop-build.shlines 24–26). Theearly-notepattern has nore.Sflag, so it only works while that paragraph stays on one line. The build fails loudly if it stops matching, which is the right failure mode.sha256sumis required (tools/whop-build.shlast block). It is not on macOS by default. Fine for the CI runner, but worth knowing for local use.review by haiku · claude-haiku-5-5 · via Time