This repository has been archived on 2026-07-17. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
codespace/plan.md
T

6.3 KiB

Plan

Roadmap for the next phases of the codespace web IDE.

Now: shadcn/ui dialog and dropdown migration

The frontend still uses window.prompt, window.confirm, and an absolute-positioned <div> for the file-tree context menu. Replace these with shadcn/ui components backed by Radix UI primitives. This gives us:

  • Consistent visual style for all popups
  • Better keyboard navigation and accessibility
  • The right-click context menu in the file tree becomes a real DropdownMenu instead of an in-place div

Concrete steps

  1. Add Radix UI primitives: @radix-ui/react-dialog, @radix-ui/react-alert-dialog, @radix-ui/react-dropdown-menu.
  2. Add shadcn-style wrappers under web/src/components/ui/:
    • dialog.tsx (Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter)
    • alert-dialog.tsx (AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel)
    • dropdown-menu.tsx (DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator)
    • input.tsx (used inside Dialogs for prompts)
  3. Migrate the existing callers:
    • WorkspaceSelector.tsx: replace window.prompt for new-workspace with a Dialog containing an Input. Replace window.confirm for delete with an AlertDialog.
    • FileExplorerPanel.tsx: replace all window.prompt (new file, new folder, rename) with a generic Dialog + Input component parameterized by title and callback. Replace window.confirm (delete) with an AlertDialog. Replace the absolute-positioned context menu with DropdownMenu.
  4. Do not change backend behavior.

Next: opencode ACP panel and integration

opencode acp exposes the editor as an Agent Client Protocol server. The current opencode process is started in the background but the user has no way to interact with it. The next phase adds a first-class ACP client panel in the web IDE.

Status: Completed (commits: ACP backend feat(backend): add opencode ACP ..., ACP frontend feat(web): add ACP chat panel ..., bug fix fix(acp): parse session/update content as ContentBlock, not string).

Why

The terminal currently runs bash (the shell subsystem). The opencode process is started via the toolbar and is meant to be controlled by an ACP client — the same protocol that editors like Zed use to talk to coding agents. Without an ACP panel, the opencode process is invisible: it has a PID and a status indicator, but no way to send it prompts or read responses.

Scope

  1. Backend: switch the opencode process to ACP mode

    • Default opencodeCommand stays opencode; new process.args field defaults to ["acp"] so the launched command is opencode acp. Configurable via configs/config.yaml and the CODESPACE_OPENCODE_ARGS env var.
    • The internal/process package still captures stdout/stderr and exposes stdin via the WebSocket. ACP over stdio sits on top in the new internal/acp package — no transport changes to the existing process WS route.
  2. Backend: ACP-aware HTTP API

    • Implemented as four HTTP routes per ACP method. The frontend does not need to know JSON-RPC.
    • Routes:
      • GET /api/workspaces/:id/acp/status — observational: {workspaceId, ready, sessionId, running, pid, error}. Does NOT start the process.
      • GET /api/workspaces/:id/acp/history — accumulated {sessionId, messages: [{role, text, time}]}, oldest first. In-memory only.
      • POST /api/workspaces/:id/acp/prompt — body {content: string}. Returns {sessionId, stopReason, text}. Starts the process + session on demand (synchronous, 5-min default timeout).
      • POST /api/workspaces/:id/acp/cancel — best-effort interrupt.
  3. Frontend: ACP panel

    • Implemented as web/src/components/acp/AcpPanel.tsx with subcomponents MessageBubble, MarkdownView, ThinkingIndicator. Renders markdown with code-block highlighting (react-markdown + react-syntax-highlighter Prism oneDark), with auto-scroll, error toast fade, and a "thinking…" indicator while in flight.
    • Hooks: useAcpStatus (3s poll), useAcpHistory (5s poll), useAcpPrompt (mutation), useAcpCancel (mutation).
  4. Frontend: integration with the workspace shell

    • Bottom panel converted to a tabbed area: Terminal / Agent (decided on Tabs + Sibling tab, not replace, not split). Tab state lives in workspaceUiStore.bottomTab.
    • StatusBar shows agent: ready / initializing… / <error> pill when the ACP session is initialized; hides when not.
    • The existing process/* routes and raw process WebSocket remain untouched (the new acp routes are additive).

Concrete tasks — all done

  1. Switched opencode default to opencode acp via process.args.
  2. Added internal/acp package: NDJSON transport + JSON-RPC 2.0 client (NDJSON framing with split-line buffering, request/response correlation, notification dispatch, per-workspace Client + Service).
  3. Added internal/api/acp_handler.go with the four routes.
  4. Added web/src/lib/api/acp.ts with the four hooks.
  5. Added web/src/components/acp/AcpPanel.tsx + subcomponents.
  6. Added react-markdown + react-syntax-highlighter + remark-gfm to web/package.json.
  7. Wired the ACP panel into WorkspaceShell.tsx as a tabbed bottom panel.
  8. Documented the ACP routes in README.md (section + env var + example curl).

Tests

  • internal/acp/client_test.go covers NDJSON split-lines, request/response correlation, notification dispatch, and agent-initiated request handling for fs/* (real dispatch) and terminal/* (MethodNotFound).
  • E2E smoke test against the live opencode acp binary: created a workspace, sent a prompt, received text: "Hi there!" non-empty, history has 4 messages (1 user + 3 agent chunks), 0 invalid session/update log entries.

Out of scope (deferred to v2)

  • Streaming responses over WebSocket (v1 is single round-trip per prompt).
  • Tool-call approval UI.
  • Multiple agents / agent switching.
  • Authentication.
  • Cross-workspace agent memory.
  • ACP session persistence across opencode restarts (history is in-memory and cleared on process restart — acceptable for v1).
  • terminal/* agent tool calls (return MethodNotFound -32601; the agent will fail those tool calls gracefully).