Cut the 0.8.59 changelog section, bump workspace/npm/README versions, refresh Cargo.lock and generated web facts, and sync the embedded TUI changelog slice. Also fixes the short codew shim to prefer its sibling codewhale dispatcher before PATH so fresh installs do not delegate to an older global binary.
codewhale-web
Community site for CodeWhale — lives at codewhale.net.
Next.js 15 (App Router) + Tailwind, deployed to Cloudflare Workers via @opennextjs/cloudflare. Curated "Today's Dispatch" content is regenerated every 6 hours by a Cloudflare Cron Trigger that calls deepseek-v4-flash to summarise recent repo activity, and stored in Workers KV.
Local dev
cd web
npm install
cp .env.example .env.local # fill in the keys you have
npm run dev # http://localhost:3000
Required env (only for the curator + private-repo rate limits):
| Variable | What | Required? |
|---|---|---|
DEEPSEEK_API_KEY |
DeepSeek platform key (sk-...) |
only for /api/cron?task=curate |
GITHUB_TOKEN |
Fine-grained PAT, public-repo read scope | optional (raises rate limit) |
GITHUB_REPO |
Defaults to Hmbown/CodeWhale |
optional |
CRON_SECRET |
Shared secret for manual cron invocation | optional |
The site renders fine without any of them — Today's Dispatch falls back to a static editorial; the GitHub feed shows "feed not yet loaded".
Deploy to Cloudflare
You already own codewhale.net on Cloudflare and have a Workers Paid plan. The deploy is two steps:
-
Provision KV namespaces once:
npx wrangler kv namespace create CURATED_KV npx wrangler kv namespace create NEXT_INC_CACHE_KVCopy the printed
idvalues into the matchingwrangler.jsoncbindings (replace eachREPLACE_WITH_KV_ID). -
Set secrets and deploy:
npx wrangler secret put DEEPSEEK_API_KEY npx wrangler secret put GITHUB_TOKEN # optional npx wrangler secret put CRON_SECRET # optional, for manual /api/cron?task=curate hits npm run deploy # builds with OpenNext + uploads -
Point the domain: in the Cloudflare dashboard, add a Worker route for
codewhale.net/*→ the deployed Worker (currently nameddeepseek-tui-webunless the Worker is renamed during deploy).
The first cron run happens within 6 hours; you can also kick it manually:
curl -H "x-cron-secret: $CRON_SECRET" "https://codewhale.net/api/cron?task=curate"
What's where
web/
├── app/
│ ├── layout.tsx root layout, font loading
│ ├── page.tsx home — hero, dispatch, stats, how-it-works, join
│ ├── globals.css design system: paper grain, hairlines, type, seal
│ ├── install/page.tsx per-OS install with auto-detection
│ ├── docs/page.tsx modes / tools / approval / config / mcp / providers
│ ├── feed/page.tsx live mirror of issues + PRs
│ ├── roadmap/page.tsx shipped / underway / considered / ruled out
│ ├── contribute/page.tsx how to PR + house rules + dev loop
│ └── api/
│ ├── cron/route.ts manual cron trigger: GitHub → DeepSeek → KV
│ └── github/feed/route.ts cached JSON endpoint
├── components/
│ ├── nav.tsx sticky header w/ date strip + CJK accents
│ ├── footer.tsx dense 5-column footer
│ ├── seal.tsx red Chinese-seal mark used as section anchor
│ ├── ticker.tsx animated live activity strip
│ ├── stat-grid.tsx tabular repo stats row
│ ├── feed-card.tsx one issue/PR card
│ └── install-tabs.tsx client component, OS auto-detect + copy
├── lib/
│ ├── types.ts shared types
│ ├── github.ts REST client + relative-time formatter
│ ├── deepseek.ts v4-flash chat client + curate() prompt
│ └── kv.ts Cloudflare KV access via OpenNext bindings
├── wrangler.jsonc CF Worker config + cron + KV binding
├── open-next.config.ts OpenNext adapter config
└── tailwind.config.ts design tokens
Aesthetic
"Yamen tech": Qing memorial document × WeChat news feed × Bloomberg terminal.
- Palette: cream paper
#FAF6EE, ink#0A2540, cinnabar red#C8102E, aged gold, jade green, cobalt blue. - Type: Fraunces (display), IBM Plex Sans (body), JetBrains Mono (UI/code), Noto Serif SC (decorative CJK anchors).
- Structure: hairline 1px dividers, multi-column grids, big tabular numbers, surgical use of red for "hot" markers, decorative Chinese-seal squares as section anchors.
If you want to retune the palette, edit :root in app/globals.css and the colors block in tailwind.config.ts.