fix(tui): address rollback guard and parity registry review

Load slash command names from the Python registry instead of regex-parsing source, and guard native rollback when no TUI session is active.
This commit is contained in:
Brooklyn Nicholson 2026-04-27 13:10:13 -05:00
parent 4f59510dd4
commit 8a33ed6136
3 changed files with 36 additions and 4 deletions

View file

@ -193,7 +193,6 @@ describe('createSlashHandler', () => {
it.each([
['/browser status', 'browser.manage', { action: 'status' }],
['/reload-mcp', 'reload.mcp', { session_id: null }],
['/rollback', 'rollback.list', { session_id: null }],
['/stop', 'process.stop', {}],
['/fast status', 'config.get', { key: 'fast', session_id: null }],
['/busy status', 'config.get', { key: 'busy' }]
@ -206,6 +205,16 @@ describe('createSlashHandler', () => {
expect(ctx.gateway.gw.request).not.toHaveBeenCalled()
})
it('routes /rollback through native RPC when a session is active', () => {
patchUiState({ sid: 'sid-abc' })
const rpc = vi.fn(() => Promise.resolve({}))
const ctx = buildCtx({ gateway: { ...buildGateway(), rpc } })
expect(createSlashHandler(ctx)('/rollback')).toBe(true)
expect(rpc).toHaveBeenCalledWith('rollback.list', { session_id: 'sid-abc' })
expect(ctx.gateway.gw.request).not.toHaveBeenCalled()
})
it('drops stale slash.exec output after a newer slash', async () => {
let resolveLate: (v: { output?: string }) => void
let slashExecCalls = 0
@ -412,6 +421,16 @@ describe('createSlashHandler', () => {
expect(ctx.transcript.sys).toHaveBeenCalledWith('no active session — nothing to save')
})
it('/rollback without an active session tells the user instead of hitting the RPC', () => {
const rpc = vi.fn(() => Promise.resolve({}))
const ctx = buildCtx({ gateway: { ...buildGateway(), rpc } })
createSlashHandler(ctx)('/rollback')
expect(rpc).not.toHaveBeenCalled()
expect(ctx.transcript.sys).toHaveBeenCalledWith('no active session — nothing to rollback')
})
it('/title <name> uses session.title RPC and bypasses slash.exec', async () => {
patchUiState({ sid: 'sid-abc' })
const rpc = vi.fn(() => Promise.resolve({ pending: false, title: 'my title' }))