feat: resume sessions, auto-expand projects, deployment - #10
Conversation
- Add extra_hosts: host-gateway so container can resolve host.docker.internal - Set allowedHosts: true in Vite config so Tailscale serve proxy isn't blocked Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add resumeSessionId to SpawnOptions and Session types - Server builds --resume <id> CLI args when resuming a session - Validate resumeSessionId format (alphanumeric only) on server - Dashboard checks live sessions before spawning — switches to existing session if one already has that claudeSessionId - Extract shared spawnSession helper with symmetric busy guards - Project sessions in sidebar are clickable buttons that trigger resume Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On page load, the project tree auto-expands the project whose Claude session matches the currently active live session. Users can still manually toggle collapse. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Validate resumeSessionId format in createSession (defense-in-depth) - Validate workingDirectory exists and is a directory before spawning - CORS defaults to localhost:5173 in dev, disabled in prod (same origin) - Add comment explaining TS_CERT_DOMAIN is Tailscale-interpolated Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Clean up Map insertion patterns in projects and terminal routes - Fix validation error message to match actual allowed chars - Extract ProjectItemProps interface for consistency Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| server: { | ||
| host: "0.0.0.0", | ||
| allowedHosts: ["aterrylu-macbook-pro"], | ||
| allowedHosts: true, |
There was a problem hiding this comment.
🟢 Suggestion
Problem: allowedHosts: true disables Vite's host header validation entirely, which opens the dev server to DNS rebinding attacks from any page the developer has open.
Why it matters: Low risk in most dev setups, but if the MacBook is reachable on a broader network (e.g. via Tailscale), a malicious site could rebind to the local Vite port and exfiltrate API responses or terminal output.
Suggested fix: Enumerate the specific hosts you need rather than allowing all:
allowedHosts: ["localhost", "aterrylu-macbook-pro", ".ts.net"],
nox-0x
left a comment
There was a problem hiding this comment.
Clean, well-structured PR. The spawnSession refactor nicely eliminates the duplicate busy-guard/fetch logic, and the input validation for resumeSessionId at both the route and session layer is solid defense-in-depth. One non-blocking issue to be aware of: res.json() in spawnSession (store.ts) is not wrapped in a try/catch — if the server ever returns a 2xx with a non-JSON body, the unhandled rejection leaves the UI stuck in "spawning..."/"resuming..." permanently (the busy guard then blocks all future spawns). Worth a quick try/catch around that call with a "failed to parse response" fallback. The allowedHosts: true in vite.config.ts is flagged inline — enumerated hosts are safer especially with Tailscale in the mix. LGTM otherwise, ship it.
Summary
--resumePTYautonomosnode on the tailnetup(dev/prod),down,checkresumeSessionIdvalidated as alphanumeric on serverspawnSessionhelper with symmetric busy guards (prevents concurrent spawn/resume)Test plan
make up— verify server + dashboard start, Tailscale sidecar connects+to spawn session — terminal appears and respondsmake up MODE=prod— dashboard served from built files on :3000🤖 Generated with Claude Code