You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds `/fork <new-name>` slash command to clone workspaces during
development, enabling quick exploration of alternative approaches
without losing the current context.
## What Changed
**Command syntax:**
```
/fork new-workspace-name
Optional multiline start message
```
**Clones entire workspace:**
- Git worktree with independent branch
- Chat history (committed messages only)
- UI preferences (model, mode, thinking level, etc.)
**Seamless mid-stream forking:** If a stream is active when forking, the
partial response is automatically committed to history first. Both
workspaces get the response content up to the fork point, then continue
independently.
## Implementation
**Backend (`src/services/ipcMain.ts`):**
- Validates workspace name
- Auto-commits streaming responses before fork
- Creates git worktree from current branch (not trunk)
- Copies `chat.jsonl`, skips `partial.json`
- Generates stable workspace ID (10-char hex)
**Frontend (`src/components/ChatInput.tsx`):**
- Parses `/fork` command with optional start message
- Copies workspace storage to new workspace
- Switches UI to forked workspace
- Optionally sends start message after 300ms
**Type safety:**
- Imports `WorkspaceMetadata` in IPC layer
- Uses `metadata.name` for directory paths (not ID)
## Testing
6 integration tests covering:
- Name validation (invalid formats rejected)
- Successful workspace creation
- Chat history copying
- Config updates
- Independent git branches
- `partial.json` handling (not copied)
All tests run concurrently for speed.
## Technical Notes
**Stable IDs architecture:** Workspaces have separate ID (stable,
10-char hex) and name (mutable, user-facing). Directories use names,
metadata uses IDs. Fork handler correctly uses `metadata.name` for path
computation via `getWorkspacePath()`.
**Auto-commit rationale:** `PartialService.commitToHistory()` is
idempotent and file-locked, making it safe to call during streaming.
This preserves work without forcing manual interruption (ESC → fork
workflow).
_Generated with `cmux`_
---------
Co-authored-by: Ammar Bandukwala <ammar@ammar.io>
0 commit comments