feat: add cross-project run board - #32
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6411d4c1f8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Extension UI (dialogs, statuses, widgets) is chrome for the project on | ||
| // screen; an inactive project's prompts would have nothing to attach to. | ||
| if (projectDir === s.activeProjectPath) applyExtensionUi(set, get, event as ExtensionUiRequest); | ||
| applyExtensionUi(set, get, projectDir, event as ExtensionUiRequest); |
There was a problem hiding this comment.
Gate non-prompt extension UI by project
When project A emits an extension request while project B is active, this unconditional call now routes every method through applyExtensionUi; only dialog prompts are project-scoped there, while setStatus and setWidget overwrite B's chrome and set_editor_text writes into B's active draft. A background extension can therefore alter or replace text the user is preparing in an unrelated project; retain the inactive-project prompt capture while ignoring or separately scoping the other project-bound methods.
Useful? React with 👍 / 👎.
| case "agent_end": | ||
| return { running: false, runStartedAt: null }; | ||
| return { running: false, runStartedAt: null, runEntryStart: null }; |
There was a problem hiding this comment.
Preserve turn state until agent_settled
When Pi enters an automatic retry delay, compacts, or proceeds to a queued follow-up, agent_end closes only the current low-level run; apps/desktop/src/main/ipc.ts:111-116 explicitly keeps the project busy until agent_settled. Clearing the running flag, timer, and entry boundary here makes the new run board temporarily report that project as inactive, then restarts its metrics at the next agent_start, so the final elapsed time and token count omit earlier attempts in the same turn.
Useful? React with 👍 / 👎.
|
|
||
| return ( | ||
| <main className="flex h-full min-w-0 flex-col bg-background text-foreground"> | ||
| <header className={`${DRAG_REGION} flex h-12 shrink-0 items-center gap-3 border-b px-4 sm:px-10`}> |
There was a problem hiding this comment.
Reserve space for the desktop window controls
In the desktop shell, the always-on WindowControls occupy the rightmost 132 px at z-[60], but this header does not apply WINDOW_CONTROLS_CLEARANCE. The run-board close button consequently sits underneath those controls and cannot be clicked; because selecting a row also leaves the full-screen board open, pointer users can become stuck on this screen until they reload or discover a keyboard workaround.
Useful? React with 👍 / 👎.
| <div className="overflow-hidden rounded-lg border"> | ||
| <div className="grid grid-cols-[minmax(12rem,1.35fr)_minmax(10rem,1.1fr)_minmax(7rem,.8fr)] gap-x-4 border-b bg-muted/30 px-4 py-2 text-xs font-medium text-muted-foreground sm:grid-cols-[minmax(10rem,1.1fr)_minmax(10rem,1.1fr)_minmax(10rem,1fr)_5rem_7rem_6rem]"> | ||
| <span>Project / chat</span><span>Model</span><span>Current work</span><span>Elapsed</span><span>Tokens</span><span>Status</span> |
There was a problem hiding this comment.
Allow the compact run table to fit or scroll
On a phone or other sub-640 px browser viewport, this compact grid still requires about 496 px before padding (12rem + 10rem + 7rem plus two gaps), while its parent uses overflow-hidden and provides no horizontal scrolling. The right-hand Current work and Status cells are therefore clipped and unreachable on typical 375–430 px screens; use genuinely flexible compact columns, hide secondary fields, or make the table horizontally scrollable.
Useful? React with 👍 / 👎.
| <span>Project / chat</span><span>Model</span><span>Current work</span><span>Elapsed</span><span>Tokens</span><span>Status</span> | ||
| </div> | ||
| {rows.map((row) => ( | ||
| <button key={row.project.path} type="button" onClick={() => void selectProject(row.project.path)} className="grid w-full grid-cols-[minmax(12rem,1.35fr)_minmax(10rem,1.1fr)_minmax(7rem,.8fr)] gap-x-4 border-b px-4 py-3 text-left last:border-b-0 hover:bg-muted/50 focus-visible:bg-muted/50 focus-visible:outline-none sm:grid-cols-[minmax(10rem,1.1fr)_minmax(10rem,1.1fr)_minmax(10rem,1fr)_5rem_7rem_6rem]"> |
There was a problem hiding this comment.
Open the chat represented by a settled row
After a run settles and the user switches to another chat in the same project, the board intentionally retains the settled row and labels it with the original run's chat, but clicking it calls only selectProject. Because selectProject chooses getLastChat(path) for a non-running project, closing the board then reveals the newer chat rather than the session named by the clicked row; navigate to row's recorded sessionFile as well as selecting its project.
Useful? React with 👍 / 👎.
Summary
Verification