fix(tui): delegate unknown /tools subcommand to slash.exec

/tools' local handler silently returned for anything other than enable
or disable, so /tools list and friends looked broken even though the
Python CLI already implements them (hermes_cli/main.py registers
tools_sub for list/enable/disable).

Keep the client-owned enable/disable path (which has to run
session.setSessionStartedAt + resetVisibleHistory locally) and route
every other sub through slash.exec, matching createSlashHandler's
page/sys split for long vs short output.
This commit is contained in:
Brooklyn Nicholson 2026-04-21 11:43:58 -05:00
parent ce98e1ef11
commit 83c1d4ec27
22 changed files with 221 additions and 76 deletions

View file

@ -1,4 +1,4 @@
import type { ToolsConfigureResponse } from '../../../gatewayTypes.js'
import type { SlashExecResponse, ToolsConfigureResponse } from '../../../gatewayTypes.js'
import type { PanelSection } from '../../../types.js'
import { patchOverlayState } from '../../overlayStore.js'
import type { SlashCommand } from '../types.js'
@ -207,10 +207,25 @@ export const opsCommands: SlashCommand[] = [
{
help: 'enable or disable tools (client-side history reset on change)',
name: 'tools',
run: (arg, ctx) => {
run: (arg, ctx, cmd) => {
const [subcommand, ...names] = arg.trim().split(/\s+/).filter(Boolean)
if (subcommand !== 'disable' && subcommand !== 'enable') {
ctx.gateway.gw
.request<SlashExecResponse>('slash.exec', { command: cmd.slice(1), session_id: ctx.sid })
.then(r => {
if (ctx.stale()) {
return
}
const body = r?.output || '/tools: no output'
const text = r?.warning ? `warning: ${r.warning}\n${body}` : body
const long = text.length > 180 || text.split('\n').filter(Boolean).length > 2
long ? ctx.transcript.page(text, 'Tools') : ctx.transcript.sys(text)
})
.catch(ctx.guardedErr)
return
}