chat urls: a group is a path, a session decides its own directory

the chat group moves from ?cwd= to a path suffix behind a g/ discriminator
(/chat/g/home/me/project), and a session url carries no group at all.

the real fix is not the spelling. a session's working directory was read back
off the query string to decide where the agent executes, so the address bar was
the authority on where code runs. a pasted or refreshed /chat/<id> arrives with
no ?cwd= at all, so a turn sent before the resolve landed ran in the default
general_chat_sessions dir instead of the project; and a hand-edited ?cwd= could
name a group the session doesn't belong to, with nothing to reconcile them.

loadClaudeSessionById already resolves a session's cwd from the id alone, so the
id is the only source of truth there. it now travels on SelectedSession.cwd,
which is what the composer reads. the url can no longer contradict it.

the vocabulary lives in apps/ChatHistory/chat-routes.ts so a link built in a
panel and one built in a screen cannot drift.

also: startAgentRun no longer returns a literal chatUrl — it returns cwd and
AgentRunnerModal builds the link, so the server holds no copy of the frontend
url shape. and the post-turn permalink strips a stale ?cwd= instead of carrying
it forward onto the new session's url.

walkthrough doc gains item 13.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 23:59:39 +00:00
co-authored by Claude Opus 5
parent 203f65d03f
commit 236541fa2a
12 changed files with 225 additions and 68 deletions
+6
View File
@@ -35,8 +35,14 @@ export function App() {
<Route path="/settings/system" element={<Dashboard.SystemSettings />} />
<Route path="/settings/integrations" element={<Dashboard.IntegrationsSettings />} />
<Route path="/settings/user-management" element={<Dashboard.UserManagementSettings />} />
{/* A project group is a working directory, so it is spelled as a path, not ?cwd= — see
apps/ChatHistory/chat-routes.ts. The splat has to be last in a pattern, which is why
"new" comes before the group rather than after it. A session carries no group: the
transcript records its own cwd and the server resolves it by id. */}
<Route path="/chat" element={<Dashboard.SessionListPage />} />
<Route path="/chat/new" element={<Dashboard.SessionListPage isNew />} />
<Route path="/chat/new/g/*" element={<Dashboard.SessionListPage isNew />} />
<Route path="/chat/g/*" element={<Dashboard.SessionListPage />} />
<Route path="/chat/:sessionId" element={<Dashboard.SessionListPage />} />
<Route path="/plans" element={<Dashboard.Plans />} />
<Route path="/files" element={<Dashboard.FilesScreen />} />