From 84fa86c4904ca03f6824323833848d717215a1bc Mon Sep 17 00:00:00 2001 From: "tao.chen" <93983997+taochen-ct@users.noreply.github.com> Date: Fri, 3 Jul 2026 18:29:12 +0800 Subject: [PATCH] docs: add plan for opencode acp panel and shadcn migration Co-Authored-By: Claude --- plan.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 plan.md diff --git a/plan.md b/plan.md new file mode 100644 index 0000000..e489652 --- /dev/null +++ b/plan.md @@ -0,0 +1,87 @@ +# 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 `
` 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. + +### 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** + - Change the default `opencodeCommand` from `opencode` to `opencode acp` (or add a new `process.acpArgs` config field). + - The `internal/process` package already captures stdout/stderr and exposes stdin via the WebSocket. ACP over stdio maps directly onto this — no transport changes needed; the same `/api/workspaces/:id/process/ws` route can be used. + - Optionally, add a thin ACP-aware layer in the service so the frontend can call high-level methods (send a prompt, cancel, get history) without speaking raw JSON-RPC. + +2. **Backend: ACP-aware HTTP API** + - Add a small JSON-RPC helper that speaks the ACP protocol over the existing process WS, OR add new HTTP routes per ACP method (simpler, more debuggable). + - For v1, prefer HTTP routes per method. The frontend does not need to know JSON-RPC. + - Routes (proposed): + - `POST /api/workspaces/:id/acp/prompt` — body `{ content: string }`, streams or returns the agent's response. + - `POST /api/workspaces/:id/acp/cancel` — cancel an in-flight prompt. + - `GET /api/workspaces/:id/acp/history` — return past messages. + - `GET /api/workspaces/:id/acp/status` — return agent readiness. + +3. **Frontend: ACP panel** + - A new `AcpPanel` component, placed next to the terminal in the bottom panel group. + - Chat-like UI: a scrollable list of user/agent message bubbles, an input box at the bottom, a "send" button (Cmd/Ctrl+Enter), a "cancel" button while a request is in flight. + - Show the agent's "thinking" indicator while waiting, the response text on completion, and any tool-call invocations inline. + - Use `useAcpStatus`, `useAcpHistory`, `useAcpSend`, `useAcpCancel` hooks (mirror the existing API-hook pattern). + - Render markdown (use a small library like `react-markdown` with a code highlighter) so code blocks look right. + - On the first response, fetch history to populate the list (since ACP may already have context from the start of the process). + +4. **Frontend: integration with the workspace shell** + - The bottom panel group currently has `EditorPanel` on top and `TerminalPanel` on bottom (only when visible). + - Add a third tab/panel for `AcpPanel` next to the terminal, or make the bottom panel a tabbed area (`Terminal` / `Agent`). + - Status bar shows the agent status alongside the opencode running status. + +### Concrete tasks (rough, to be expanded into a full plan when we start) + +1. Switch `opencodeCommand` default to `opencode acp`; document the change in `README.md`. +2. Add `internal/acp` package: ACP JSON-RPC client, speaks stdio to the opencode process. Or use a Go ACP SDK if one exists. +3. Add `internal/api/acp_handler.go` with the four routes above. +4. Add `web/src/lib/api/acp.ts` with the four hooks. +5. Add `web/src/components/acp/AcpPanel.tsx` and supporting subcomponents (`MessageBubble`, `PromptInput`, `ToolCallBlock`). +6. Add `react-markdown` and a code highlighter (`react-syntax-highlighter` or `shiki`) to `web/package.json`. +7. Wire the ACP panel into `WorkspaceShell.tsx` as a tabbed bottom panel. +8. Document the ACP routes in `README.md`. + +### Out of scope (for v1) + +- Streaming responses (use a single round-trip per prompt; add SSE or stream-over-WS later). +- Tool-call approval UI (rely on the agent's own sandboxing for v1; the user can interrupt if it does something wrong). +- Multiple agents / agent switching. +- Authentication. +- Cross-workspace agent memory. +- ACP session persistence across opencode restarts (lose context on restart; accept this for v1). + +### Open questions to resolve before implementation + +- Does the opencode ACP server expect framing on stdio (LSP-style `Content-Length:` headers) or newline-delimited JSON? (Will check when we start.) +- Should the ACP panel replace the terminal in the bottom area, or live as a sibling tab? +- Do we want the ACP panel to share the bottom area with the terminal (tabs), or always be visible alongside it (split)?