Skip to content

feat(web): read-only workspace activity pages - #407

Merged
Waishnav merged 12 commits into
mainfrom
feat/workspace-web
Oct 26, 2026
Merged

Waishnav merged 12 commits into
mainfrom
feat/workspace-web

Conversation

@Waishnav

@Waishnav Waishnav commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

DevSpace now journals every workspace's turns (#341), but there was no way to look at them. This adds read-only pages, served by the DevSpace server under /web, for looking back at what happened in a workspace. The host is still the orchestrator; these pages never drive work.

There are three views. /web/ lists open and recent workspaces with root, mode, branch, status, turn count and last activity. /web/w/<workspace_id> has a header with the same details the open_workspace card shows (root, mode, branch, loaded and available instruction files, skills), the turn list on the left (latest first), and the selected turn on the right. /web/w/<workspace_id>/turns/<n> shows that turn's diff from checkpoint N-1 to checkpoint N as a file tree plus diffs, then the tool calls made during the turn. Each call shows its arguments, a result summary, duration and error state, and expands. The interaction model follows t3code's diff panel. On narrow screens the turn list becomes a "Latest turn / Turn N" selector. The diff rows reuse the card's rendering: ReviewDiffFile and its CSS moved into a shared src/ui/review-diff.tsx / review-diff.css that both the card and the pages import, so nothing is forked. The pages have their own Vite entry (vite.web.config.ts, pnpm build:web → dist/web), so the card's vite.config.ts is untouched. Workspace details come from a new WorkspaceRegistry.describeWorkspace, which reads instructions and skills without touching or reactivating the session (getWorkspace does both).

Auth. These pages expose local code, so nothing under /web except the login form and the static bundle is reachable without the owner's credential, including through a public tunnel. I reused the existing owner token instead of adding a credential. /web/login takes the owner password and creates a random session (only its hash is kept in memory, 12-hour lifetime, cleared on restart and by sign-out). The session goes in an HttpOnly; SameSite=Strict; Path=/web cookie, marked Secure when the request arrived over HTTPS. Login and logout are the only state-changing forms, and they accept a post only when Sec-Fetch-Site (or Origin on older browsers) says same-origin. Ten failed logins in 15 minutes lock the form, because the owner password may be user-chosen. No CORS headers are sent. Responses carry no-store, frame-ancestors 'none' and a self-only CSP. The app-wide allowed-hosts check already covers /web, and a test covers DNS-rebinding hosts. A cookie session beats putting the bearer token in the browser: script on the page can't read it, other sites can't send it, and it never ends up in URLs or history. devspace serve now prints workspace pages: <publicBaseUrl>/web/.

QA used the replay harness (#404) with a new two-turn scenario, workspace-turns: open_workspace, apply_patch, show_changes, apply_patch, exec_command, show_changes. It ran with --serve --no-browser against this branch, and I drove the pages with agent-browser. The harness generates the owner token per run, so on a local, unpushed copy of the harness (qa/workspace-web) I made serve mode print the server URL and owner token. That change and the scenario are not on test/replay-qa. QA caught one real bug: with Referrer-Policy: no-referrer, Chrome sends Origin: null on form posts, so login was rejected as cross-origin. The fix is to trust Sec-Fetch-Site and use Referrer-Policy: same-origin. Unauthenticated /web/api/workspaces returns 401 and /web/ redirects (303) to login. The 390px viewport has no horizontal scroll (scrollWidth 390). The console stayed clean.

Login login
Workspaces workspaces
Workspace, latest turn latest
Turn 1 (tree + 2 files) turn 1
Turn 2, expanded tool call turn 2
Dark dark
390px, dark mobile
390px workspaces mobile list

Not included: live updates (reload to see new turns), subagent events (the hook is in #341), and pruning of old turns or pinned refs. The Smoke check fails on every PR because of the koffi release (#403).

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 24 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 8 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ca032dfe-e72d-44fd-9b08-5a82fc6dab19
Commits

Reviewing files that changed from the base of the PR and between 531d3f9 and fddf8f8.

Files selected for processing: 26
  • package.json
  • src/cli.ts
  • src/db/migrations.ts
  • src/db/schema.ts
  • src/oauth-store.test.ts
  • src/review-checkpoints.test.ts
  • src/review-checkpoints.ts
  • src/server.test.ts
  • src/server.ts
  • src/ui/review-diff.css
  • src/ui/review-diff.tsx
  • src/ui/review-payload.tsx
  • src/ui/web/diff-tree.test.ts
  • src/ui/web/diff-tree.ts
  • src/ui/web/index.html
  • src/ui/web/main.tsx
  • src/ui/web/web.css
  • src/ui/workspace-app.css
  • src/workspace-activity-journal.test.ts
  • src/workspace-activity-journal.ts
  • src/workspace-activity-store.ts
  • src/workspace-activity.ts
  • src/workspace-web.test.ts
  • src/workspace-web.ts
  • src/workspaces.ts
  • vite.web.config.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Waishnav and others added 5 commits October 26, 2026 02:43
…t touching prose

Basic/Bearer now match only in Authorization headers (or a long standalone
Bearer token), so text like "Basic functionality" survives. Commands and
outputs also redact ALL_CAPS secret env assignments, credential CLI flags and
user:pass@ URLs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Waishnav

Copy link
Copy Markdown
Owner Author

Verified on the combined v1.1 branch

I built a local rehearsal branch with every v1.1 PR merged in order (#403, the small fixes, #404–#406, #408, the subagent stack #379–#384, #410, #409, #399, #341 with its migration renumbered to 14, and this PR). On it, pnpm typecheck, pnpm test (212 pass, 1 skip), pnpm build and pnpm test:package-install pass, and all 9 replay scenarios pass.

These pages, driven with agent-browser on that branch:

  • Login works, and the API returns 401 before login and after sign-out.
  • The workspace page shows 2 turns with 3 calls each.
  • Turn 2 labels README.md as Edited, which comes from fix(review): report file status from git instead of line counts #408's file-status fix through the shared diff code.
  • Turn 1 shows farewell.ts added and greet.ts edited with word-level highlighting.
  • At 390px in dark mode there is no horizontal scroll, and there are 0 page errors.

combined-web-workspace.png
combined-web-turn1-dark-390.png

Waishnav pushed a commit that referenced this pull request Oct 25, 2026
@Waishnav

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Waishnav
Waishnav changed the base branch from feat/workspace-activity to main October 26, 2026 17:33
@Waishnav
Waishnav merged commit 372fcda into main Oct 26, 2026
1 of 4 checks passed
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.

1 participant