Skip to content

Commit d1bad5d

Browse files
Prepare the status page for a public repository (#1)
Remove the Cloudflare account id from the Wrangler config, ignore local secret files, and document the monitored sites and how to run the Worker. Checks now release unused response bodies, unknown paths no longer trigger a probe, and CI runs the tests and a dry-run bundle. Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Gáborjáni-Szabó Ádám <Programcode@users.noreply.github.com>
1 parent 68fa4de commit d1bad5d

10 files changed

Lines changed: 1965 additions & 20 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
check:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: actions/setup-node@v4
16+
with:
17+
node-version: 22
18+
cache: npm
19+
- run: npm ci
20+
- run: npm test
21+
- run: npm run lint
22+
- run: npm run build

‎.gitignore‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1-
node_modules
2-
.wrangler
1+
node_modules/
2+
.wrangler/
3+
.dev.vars
4+
.dev.vars.*
5+
.env
6+
.env.*
7+
!.env.example
8+
dist/
9+
coverage/
10+
*.log
11+
.DS_Store
312
*.png
13+
!docs/status.png

‎LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Adam
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.

‎README.md‎

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,68 @@
11
# Pi-Stack status
22

3-
A Cloudflare Worker that checks every public Pi-Stack site every 5 minutes and serves a status page with 24 hours of history.
3+
A Cloudflare Worker that checks every public [Pi-Stack](https://pi-stack.org) site every five minutes and serves a status page with 24 hours of history.
44

5-
- `src/index.js` holds the site list, the cron check and the page.
6-
- Results live in one KV key (`STATE` binding), written once per run, which keeps it inside the free tier's 1,000 writes a day.
7-
- `/api/status` returns the latest results as JSON.
5+
![The live Pi-Stack status page at status.pi-stack.org](docs/status.png)
86

9-
Deploy with `npx wrangler deploy` and a `CLOUDFLARE_API_TOKEN` that can edit Workers on the Pi-Stack account.
7+
The page is [status.pi-stack.org](https://status.pi-stack.org). The same results are available as JSON at [`/api/status`](https://status.pi-stack.org/api/status).
8+
9+
## Monitored services
10+
11+
The Worker checks these sites, in this order. The short descriptions come from each site's public homepage.
12+
13+
| Service | URL | Public description |
14+
| --- | --- | --- |
15+
| Pi-Stack | https://pi-stack.org/ | AI products built on Claude, led by DebateLab |
16+
| DebateLab | https://debate.pi-stack.org/ | AI debate practice for students and competitive debaters |
17+
| Athel | https://athel.pi-stack.org/ | Interactive story set in an underwater city |
18+
| Escucha | https://escucha.pi-stack.org/ | Confidential channel for a school community |
19+
| ProtoPi | https://proto.pi-stack.org/ | Prototype deployment and review system |
20+
| YubiNotes | https://notes.pi-stack.org/ | YubiKey-only notes |
21+
| Chorely | https://chorely.pi-stack.org/ | Device-local demo of family chores, tokens, and rewards |
22+
| Wordle | https://wordle.pi-stack.org/ | Configurable word-guessing game with offline play |
23+
24+
ProtoPi and YubiNotes answer with a login redirect. A redirect still counts as up, because the site itself responded.
25+
26+
## How it works
27+
28+
A [Cron Trigger](https://developers.cloudflare.com/workers/configuration/cron-triggers/) runs every five minutes (`*/5 * * * *`). Each run requests the eight sites from Cloudflare's network. Redirects are not followed, and each request gives up after 10 seconds. A status below 400 is stored as up. A 4xx or 5xx response, a timeout, or a network error is stored as down.
29+
30+
The run writes one Workers KV key, `state`, through the `STATE` binding. That key holds the latest result for each site and 288 samples, which is 24 hours at one sample every five minutes. One write per run is 288 writes a day, under the Workers Free plan limit of [1,000 KV writes a day](https://developers.cloudflare.com/kv/platform/limits/).
31+
32+
The page turns those samples into 48 bars, one per half hour. Green means every check in the block passed, amber means some failed, red means all of them failed, and grey means the block has no sample yet. The HTML refreshes once a minute. Page and API responses are cached for 30 seconds.
33+
34+
`/api/status` returns `checkedAt` and one object per site: `name`, `host`, `url`, `ok`, `code`, `ms`, and `uptime`. `uptime` is the percentage of stored samples, or `null` before the first check. The bar series is only on the HTML page.
35+
36+
If the KV key is missing, the first request to `/` or `/api/status` runs the checks itself and stores them. Any other path, and any method other than GET or HEAD, does not.
37+
38+
## Tech stack
39+
40+
- [Cloudflare Workers](https://developers.cloudflare.com/workers/) for the cron job and the HTTP server
41+
- [Workers KV](https://developers.cloudflare.com/kv/) for the 24-hour history
42+
- [Wrangler](https://developers.cloudflare.com/workers/wrangler/) for local development and deploys
43+
- `src/index.js`, with no frontend framework and no build step beyond Wrangler's bundle
44+
45+
## Quick start
46+
47+
Requires Node.js 22 or newer.
48+
49+
```bash
50+
npm install
51+
npm test
52+
npm run dev
53+
```
54+
55+
`npm test` checks the Worker without calling the real sites. `npm run dev` starts a local Worker with a local KV store, so the page waits for a check before it has history. `npm run lint` syntax-checks the source. `npm run build` bundles the Worker with `wrangler deploy --dry-run` and does not deploy it.
56+
57+
GitHub Actions runs the test, lint, and build scripts on every push and pull request.
58+
59+
To deploy a copy:
60+
61+
1. Run `npx wrangler login`, or export `CLOUDFLARE_API_TOKEN` with permission to edit Workers on the target account.
62+
2. If that login can see more than one account, export `CLOUDFLARE_ACCOUNT_ID`. The account id is not in `wrangler.jsonc`.
63+
3. Create a namespace with `npx wrangler kv namespace create STATE` and put its id in `kv_namespaces`. The id already in the file is the production namespace for status.pi-stack.org. It belongs to that account. A fork needs its own.
64+
4. Run `npm run deploy`.
65+
66+
## License
67+
68+
[MIT](LICENSE).

‎docs/status.png‎

266 KB
Loading

0 commit comments

Comments
 (0)