feat(v0.6): kill a session directly from the Projects grid cards

The detail view could kill sessions, but the grid card's session rows were
enter-only. Add a ✕ kill button to each card session row (stopPropagation so it
doesn't also enter the session); makeSessionRow gains an optional onKill,
makeProjectCard an optional onKillSession, and mountProjects wires it to
DELETE /live-sessions/:id followed by a refresh.

Frontend-only. projects-panel tests +1 (51): ✕ present only with the callback,
click kills the right id without entering. Verified in-browser: a card with 2
sessions dropped to 1 after clicking ✕.
This commit is contained in:
Yaojia Wang
2026-06-30 13:35:53 +02:00
parent 99bc6fd9f6
commit 46698b8b5e
4 changed files with 69 additions and 1 deletions

View File

@@ -324,6 +324,25 @@ describe('makeProjectCard — launcher row', () => {
expect(card.querySelectorAll('.proj-launch')).toHaveLength(3)
})
it('shows a Kill (✕) on each session row only when onKillSession is given', () => {
const p = makeProject({
sessions: [{ id: 's1', status: 'idle', clientCount: 1, createdAt: 1, exited: false }],
})
// Without the callback: no kill button (enter-only).
const plain = makeProjectCard(p, new Set(), noopHooks(), () => {})
expect(plain.querySelector('.proj-session-kill')).toBeNull()
// With the callback: clicking ✕ kills that session and does not enter it.
const hooks = noopHooks()
const onKill = vi.fn()
const card = makeProjectCard(p, new Set(), hooks, () => {}, undefined, onKill)
const kill = card.querySelector('.proj-session-kill') as HTMLButtonElement
expect(kill).not.toBeNull()
kill.click()
expect(onKill).toHaveBeenCalledWith('s1')
expect(hooks.onEnterSession).not.toHaveBeenCalled()
})
it('highlights the Claude launcher when a Claude session (known status) is live', () => {
const p = makeProject({
sessions: [{ id: 's1', status: 'working', clientCount: 0, createdAt: 1, exited: false }],