Add unified new chat project setup modal#157
Conversation
Review Summary by QodoAdd unified project setup modal with GitHub clone support
WalkthroughsDescription• Add GitHub repository cloning support to new chat project setup • Replace separate create/clone prompts with unified modal interface • Implement tab-based mode switching between create and clone operations • Add comprehensive dark theme styling for modal and form elements Diagramflowchart LR
A["User clicks Create Project"] --> B["Project Setup Modal Opens"]
B --> C{"Select Mode"}
C -->|"New project"| D["Enter project name"]
C -->|"Clone from GitHub"| E["Enter repository URL"]
D --> F["Create project in destination"]
E --> G["Clone repository to destination"]
F --> H["Register and select project"]
G --> H
File Changes1. src/api/codexGateway.ts
|
Code Review by Qodo
1. Workspace roots cache stale
|
| export async function cloneGithubRepository(url: string, basePath: string): Promise<string> { | ||
| const response = await fetch('/codex-api/github-clone', { | ||
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/json' }, | ||
| body: JSON.stringify({ url, basePath }), | ||
| }) | ||
| const payload = await readJsonResponse(response) | ||
| if (!response.ok) { | ||
| const message = getErrorMessageFromPayload(payload, 'Failed to clone GitHub repository') | ||
| throw new Error(message) | ||
| } | ||
| const record = | ||
| payload && typeof payload === 'object' && !Array.isArray(payload) | ||
| ? (payload as Record<string, unknown>) | ||
| : {} | ||
| const data = | ||
| record.data && typeof record.data === 'object' && !Array.isArray(record.data) | ||
| ? (record.data as Record<string, unknown>) | ||
| : {} | ||
| return typeof data.path === 'string' ? normalizePathForUi(data.path) : '' | ||
| } |
There was a problem hiding this comment.
1. Workspace roots cache stale 🐞 Bug ≡ Correctness
After a successful GitHub clone, the server persists the cloned folder as a workspace root, but the client-side getWorkspaceRootsState() cache is not invalidated, so the UI can reload/persist an out-of-date roots list and omit (or overwrite) the new root. This can make the newly-cloned project not show up in the folder selector or have incorrect ordering until a full refresh.
Agent Prompt
### Issue description
`cloneGithubRepository()` persists a new workspace root on the server, but the browser keeps using a cached `getWorkspaceRootsState()` result, so immediately after cloning the UI can operate on stale workspace-roots state (missing the new root) and even persist that stale state back.
### Issue Context
`openProjectRoot()` explicitly calls `invalidateWorkspaceRootsStateCache()`, but `cloneGithubRepository()` does not.
### Fix Focus Areas
- src/api/codexGateway.ts[2810-2830]
- src/api/codexGateway.ts[2760-2785]
### Suggested fix
- After a successful clone (once a valid `data.path` is returned), call `invalidateWorkspaceRootsStateCache()` (mirroring `openProjectRoot()`).
- Optionally, consider returning additional data from the clone endpoint (e.g., updated workspace-roots state) and updating the cache directly, but invalidation alone should fix the immediate correctness bug.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Summary
Verification
Performance profile: output/playwright/browser-runtime-profile-home-2026-05-11T04-50-25-588Z.json. Existing warning remains: threadRead=3; no new startup fanout from this modal change.