Skip to content

feat: resume sessions, auto-expand projects, deployment - #10

Merged
aterrylu merged 5 commits into
mainfrom
terry/project-session-view
Mar 9, 2026
Merged

feat: resume sessions, auto-expand projects, deployment#10
aterrylu merged 5 commits into
mainfrom
terry/project-session-view

Conversation

@aterrylu

@aterrylu aterrylu commented Mar 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Resume existing Claude Code sessions from the project browser sidebar — clicking a project session either switches to an existing live session or spawns a new --resume PTY
  • Auto-expand project tree for the project containing the active resumed session on page load
  • Tailscale sidecar deployment — Docker-based sidecar creates a dedicated autonomos node on the tailnet
  • Production serving — Hono serves built dashboard static files with SPA fallback
  • Simplified Makefileup (dev/prod), down, check
  • PTY exit handling — WebSocket close code 4010 notifies clients when PTY exits
  • Sidebar persistence — open/closed state survives page refresh
  • Input validationresumeSessionId validated as alphanumeric on server
  • Shared spawnSession helper with symmetric busy guards (prevents concurrent spawn/resume)

Test plan

  • make up — verify server + dashboard start, Tailscale sidecar connects
  • Click + to spawn session — terminal appears and responds
  • Refresh page — reconnects to same session, sidebar stays open
  • Expand a project — click a session to resume it
  • Click same project session again — switches to existing live session (no new spawn)
  • Refresh after resuming — correct project auto-expands
  • make up MODE=prod — dashboard served from built files on :3000
  • Kill a session — terminal closes, session removed from sidebar

🤖 Generated with Claude Code

aterrylu and others added 5 commits March 8, 2026 13:49
- 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,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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 nox-0x left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@aterrylu
aterrylu merged commit fb3e55d into main Mar 9, 2026
1 check passed
@aterrylu
aterrylu deleted the terry/project-session-view branch March 9, 2026 01:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants