Skip to content

feat(web): add optional Session Name field to the Spawn Agent dialog#279

Open
vprudnikoff wants to merge 3 commits into
awslabs:mainfrom
vprudnikoff:feat/web-session-name
Open

feat(web): add optional Session Name field to the Spawn Agent dialog#279
vprudnikoff wants to merge 3 commits into
awslabs:mainfrom
vprudnikoff:feat/web-session-name

Conversation

@vprudnikoff

@vprudnikoff vprudnikoff commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Summary

The Spawn Agent dialog in the web UI had no way to set a session name, so every web-created session got an auto-generated cao-<hash> name (8 hex chars from a UUID). That generated id is the only label the session list shows and searches by, and there is no rename — so the spawn dialog is the one place to give a session a readable identity. The backend POST /sessions and the CLI --session-name already accept a custom name; this just exposes it in the UI.

What changed

  • AgentPanel — add an optional "Session Name" input to the Spawn dialog (with a tag icon, mirroring the Working Directory field) and pass it to createSession.
  • store — thread sessionName through createSession (it was hardcoded to undefined).
  • api — URL-encode session_name in the query string (matching working_directory).
  • testcreateSession includes the URL-encoded session_name.

Behavior

  • Empty field → unchanged: the backend auto-generates cao-<hash> exactly as before.
  • Filled → the session is created with that name; the backend validates it (validate_tmux_name) and prefixes cao- if missing, identical to cao launch --session-name and the API. A duplicate name surfaces the backend error in the existing snackbar.
Screenshot 2026-06-05 at 16 51 53

This brings the web UI to parity with the CLI's --session-name.

Testing

  • npm test (vitest) — green.
  • npm run build (tsc + vite) — clean.

The Spawn Agent dialog had no way to set a session name, so every web-UI
session got an auto-generated cao-<hash> name. That hash is the only label
the session list shows and searches by, and there is no rename — so the
spawn dialog is the one place a user can give a session a readable identity.
The backend POST /sessions and the CLI --session-name already accept a custom
name; this just exposes it in the UI.

- AgentPanel: add an optional "Session Name" input, pass it to createSession
- store: thread sessionName through createSession (it was hardcoded undefined)
- api: url-encode session_name in the query string (mirrors working_directory)
- test: createSession includes the url-encoded session_name
@haofeif haofeif requested a review from Copilot June 6, 2026 10:02
@haofeif haofeif added the enhancement New feature or request label Jun 6, 2026
@codecov-commenter

codecov-commenter commented Jun 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@1224cd0). Learn more about missing BASE report.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #279   +/-   ##
=======================================
  Coverage        ?   92.14%           
=======================================
  Files           ?       70           
  Lines           ?     7106           
  Branches        ?        0           
=======================================
  Hits            ?     6548           
  Misses          ?      558           
  Partials        ?        0           
Flag Coverage Δ
unittests 92.14% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an optional “Session Name” field to the web UI’s Spawn Agent dialog so users can create readable session identities instead of relying solely on auto-generated cao-<hash> names, bringing the web experience closer to existing CLI/API capabilities.

Changes:

  • Adds an optional Session Name input to the Spawn Agent modal and passes it through the store to session creation.
  • Threads sessionName through the Zustand store’s createSession call (previously always undefined).
  • URL-encodes session_name in the POST /sessions request and adds a unit test asserting the encoding.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
web/src/components/AgentPanel.tsx Adds Session Name input and passes it into session creation from the spawn dialog.
web/src/store.ts Extends the store createSession API to accept and forward sessionName.
web/src/api.ts Encodes session_name in the create-session query string.
web/src/test/api.test.ts Adds a test ensuring session_name is URL-encoded in requests.
Comments suppressed due to low confidence (1)

web/src/store.ts:82

  • createSession swallows errors and always resolves, which prevents the caller from keeping the Spawn dialog open on validation/duplicate-name failures (now more likely with the new Session Name field). Consider returning a success boolean or rethrowing after showing the snackbar so the UI can avoid closing/resetting on failure.
  createSession: async (provider, agentProfile, workingDirectory, sessionName) => {
    try {
      await api.createSession(provider, agentProfile, sessionName, workingDirectory)
      get().showSnackbar({ type: 'success', message: 'Session created' })
      await get().fetchSessions()
    } catch (e: any) {
      get().showSnackbar({ type: 'error', message: e.message || 'Failed to create session' })
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread web/src/api.ts Outdated
Comment on lines +109 to +110
createSession: (provider: string, agentProfile: string, sessionName?: string, workingDirectory?: string) =>
fetchJSON<Terminal>(`/sessions?provider=${provider}&agent_profile=${agentProfile}${sessionName ? `&session_name=${sessionName}` : ''}${workingDirectory ? `&working_directory=${encodeURIComponent(workingDirectory)}` : ''}`, { method: 'POST', timeoutMs: 90000 }),
fetchJSON<Terminal>(`/sessions?provider=${provider}&agent_profile=${agentProfile}${sessionName ? `&session_name=${encodeURIComponent(sessionName)}` : ''}${workingDirectory ? `&working_directory=${encodeURIComponent(workingDirectory)}` : ''}`, { method: 'POST', timeoutMs: 90000 }),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, and it's right on the line this PR touches. agent_profile can be free-text when no profiles are loaded, so a space or reserved character would corrupt the query. Fixed: encodeURIComponent is now applied to both provider and agent_profile (and to the sibling addTerminalToSession, which shared the same raw interpolation).

agent_profile can be free-text when no profiles are loaded, so a space or
reserved character would corrupt the query string. encodeURIComponent both
provider and agent_profile, matching the existing session_name and
working_directory encoding. Applied to createSession and the sibling
addTerminalToSession, which shared the same raw interpolation.
@vprudnikoff vprudnikoff force-pushed the feat/web-session-name branch from 2c90ddb to ee900b2 Compare June 6, 2026 14:48
@vprudnikoff

Copy link
Copy Markdown
Contributor Author

Re: the suppressed low-confidence note about createSession swallowing errors in store.ts — I'm intentionally leaving that out of this PR. It's pre-existing behavior: this change only threads the optional sessionName through and doesn't add client-side validation or alter the error path. Making createSession surface failures so the dialog can stay open is a reasonable improvement, but it's a broader UX change affecting all session creation, so it's better as a focused follow-up than scope-creep here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread web/src/components/AgentPanel.tsx Outdated
Comment on lines 139 to 143
const handleCreate = async () => {
if (!profile.trim()) return
setCreating(true)
await createSession(provider, profile.trim(), workingDirectory.trim() || undefined)
await createSession(provider, profile.trim(), workingDirectory.trim() || undefined, sessionName.trim() || undefined)
setCreating(false)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d90c783. Added a synchronous useRef in-flight lock so a second submit (rapid double-click, or Enter in the modal inputs — which bypass the button's disabled state) early-returns instead of firing a duplicate createSession. The success-side resets now run in a try, with setCreating(false) (and the lock release) in finally, so the form can't get stuck in "Spawning…" if the call throws, and the dialog stays open with its fields preserved on failure.

handleCreate is reachable via the Spawn button and via Enter in the modal
inputs; the inputs bypass the button's disabled state, so a rapid double-press
could fire a second createSession before the `creating` state re-renders. Add
a synchronous useRef in-flight lock, and move the success-side resets into a
try/finally so `creating` is always cleared (even if createSession throws) and
the dialog stays open with its fields preserved on failure.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants