diff options
| author | Adam Malczewski <[email protected]> | 2026-06-30 01:30:06 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-30 01:30:06 +0900 |
| commit | bf74aeab143a49005c380706ae9847cf064fd2f2 (patch) | |
| tree | c9e93dc0ebe818e7c0d0aafeba8387afd161da3f /frontend-cwd-resolution-handoff.md | |
| parent | 6dd9ea9b935e5011c16faed6c869c976cf5ff172 (diff) | |
| download | dispatch-main.tar.gz dispatch-main.zip | |
Removed 40+ markdown files that were cluttering the repo root:
- frontend-*-handoff.md (28 files) — historical API contract handoffs, features all implemented
- backend-to-fe-handoff.md, backend-to-fe-handoff-2.md — old handoff docs
- broken-chat-repair-handoff.md — old repair handoff
- PLAN-mcp.md, PLAN-per-edit-diagnostics.md — old planning docs
- ai-review-report.md, crash-review-report.md — one-time review reports
- tasks.md, HANDOFF.md — outdated status docs (git log is the source of truth)
Kept: AGENTS.md, GLOSSARY.md, ORCHESTRATOR.md, README.md
Also: gitignored ai-review-report.md so future Gemini reviews don't commit it
Diffstat (limited to 'frontend-cwd-resolution-handoff.md')
| -rw-r--r-- | frontend-cwd-resolution-handoff.md | 95 |
1 files changed, 0 insertions, 95 deletions
diff --git a/frontend-cwd-resolution-handoff.md b/frontend-cwd-resolution-handoff.md deleted file mode 100644 index 80d5105..0000000 --- a/frontend-cwd-resolution-handoff.md +++ /dev/null @@ -1,95 +0,0 @@ -# Backend handoff — cwd resolution fixes (backend → FE) — courier doc - -> **From:** arch-rewrite orchestrator · **To:** frontend orchestrator (b18a) · **Courier:** the user. -> Response to the cwd bug report you sent to backend agent ab13. The fixes are DONE and -> live-verified on the dev stack. - -## Version bumps - -| Package | From | To | Notes | -|---|---|---|---| -| `@dispatch/wire` | — | — | **Unchanged** | -| `@dispatch/transport-contract` | — | — | **Unchanged** | -| `@dispatch/ui-contract` | — | — | **Unchanged** | - -**This is a behavior-only change.** No wire/transport-contract types changed. No FE re-pin or -re-mirror needed. The FE needs NO contract change to benefit. - ---- - -## 1. The fix (what was broken → what now works) - -You reported: a workspace `defaultCwd` set, a conversation with no explicit cwd, and `pwd` ran in -the server default (`process.cwd()`) instead of the workspace `defaultCwd`. Plus your desired -behavior: a per-conversation cwd **relative to the workspace `defaultCwd`** unless absolute. - -**Root cause (backend-only):** the workspace-relative resolution lived in -`conversation-store.getEffectiveCwd`, which only resolved the *persisted* cwd. But the FE sends the -CwdField value as a **per-turn `cwd` on `chat.send`**, and `session-orchestrator` used a per-turn -`cwd` **as-is** — bypassing `getEffectiveCwd` entirely. So a relative `cwd` like `"arch-rewrite"` -reached `run_shell` raw → resolved against `process.cwd()` → a nonexistent path → `pwd` broke. - -**Three backend fixes (all live-verified):** - -1. **Per-turn `cwd` is now resolved.** `session-orchestrator` passes the per-turn `cwd` (on - `chat.send`/`POST /chat` AND on manual `POST /chat/warm`) through `getEffectiveCwd` as an - override, so it goes through the same workspace-relative algorithm as the persisted cwd. -2. **New-conversation timing.** A brand-new conversation's first turn previously ran - `getEffectiveCwd` *before* the workspace was assigned (so it saw `"default"`, not the request's - workspace). Now the workspace is assigned first. A relative per-turn `cwd` on the FIRST message - of a new conversation now resolves against the intended workspace. -3. **`DELETE /conversations/:id/cwd` was a stub** (returned `{cwd:null}` but did NOT clear the - persisted key). It now calls `clearCwd` and truly deletes the persisted cwd. - -## 2. The resolution algorithm (now applied to BOTH persisted and per-turn cwd) - -``` -workspaceId = persisted conversation workspaceId ("default" fallback) -workspaceCwd = workspace.defaultCwd ?? null -conversationCwd = the explicit cwd (persisted via GET /cwd, OR the per-turn chat.send cwd) - -if (conversationCwd == null) → workspaceCwd ?? serverDefaultCwd // process.cwd() -else if (conversationCwd absolute) → conversationCwd // starts with "/" -else → path.resolve(workspaceCwd ?? serverDefaultCwd, conversationCwd) -``` - -`serverDefaultCwd` = `process.cwd()` (the server's cwd). - -## 3. FE impact (minimal — no contract change) - -You do NOT need to change anything. Both FE patterns now work correctly: - -- **If you omit `cwd` on `chat.send`** (your current code): the backend resolves the persisted - conversation cwd (set via `PUT /conversations/:id/cwd`) through the algorithm. ✅ -- **If you send a relative `cwd` on `chat.send`**: it is resolved against the workspace - `defaultCwd`. ✅ (was broken — used raw) -- **If you send an absolute `cwd`** (starts `/`): overrides outright. ✅ - -### Endpoints (semantics — shapes unchanged) - -- `GET /conversations/:id/cwd` → **unchanged**: the RAW explicit conversation cwd (`null` = - inheriting workspace default). Your CwdField shows what the user typed. -- `GET /conversations/:id/lsp` → returns the **effective** (resolved) cwd. It now roots LSP at the - effective cwd INCLUDING the server-default fallthrough (when neither conversation nor workspace - cwd is set, LSP roots at `process.cwd()`). Previously returned `cwd: null` + empty `servers` when - no cwd was set. -- `DELETE /conversations/:id/cwd` → **now actually clears** the persisted cwd (was a no-op stub). - Returns `{ conversationId, cwd: null }` (unchanged shape). Use this to reset a conversation's cwd - to "inherit workspace default". -- `PUT /conversations/:id/cwd` → unchanged (persists the raw value). - -## 4. Optional FE simplification (not required) - -You MAY now safely **omit `cwd` on `chat.send`** entirely and rely on the backend resolving the -persisted conversation cwd (set via `PUT /conversations/:id/cwd`). This was the design you -described in the original report. Either path (send cwd, or omit it) is correct; the backend -resolves both consistently. Sending it is harmless; omitting it avoids sending redundant data. - -## 5. Live-verified (dev stack, workspace `test` defaultCwd `/home/tradam/projects/dispatch`) - -- Existing conversation, per-turn `cwd:"arch-rewrite"` → `pwd` = `/home/tradam/projects/dispatch/arch-rewrite` ✅ -- Brand-new conversation, per-turn `cwd:"arch-rewrite"` → `pwd` = `/home/tradam/projects/dispatch/arch-rewrite` ✅ -- Chat omitting `cwd` (persisted cwd `arch-rewrite`) → `pwd` = `/home/tradam/projects/dispatch/arch-rewrite` ✅ -- `PUT /tmp/test` → GET `/tmp/test` → DELETE → GET `null` (actually cleared) ✅ - -`tsc -b` EXIT 0, biome clean, 1311 vitest pass. |
