fix: Web ↔ TUI skill parity — info events, skill_run RPC, symlink skills#2359
fix: Web ↔ TUI skill parity — info events, skill_run RPC, symlink skills#2359lanshi17 wants to merge 7 commits into
Conversation
loopEventToDashboard now converts 'info' LoopEvents to DashboardEvents so they propagate to web dashboard subscribers via SSE. Added 'info' to EventRole type and corresponding test coverage.
Slash commands that return info text (unknown commands, /help, /skill list, etc.) now also emit DashboardEvent via SSE so the web dashboard displays the same feedback as the TUI.
The sseToIncoming converter now handles kind='info' events, mapping them to $info incoming events that render as info rows in the message thread. Added InfoEvent type to protocol, info icon to icon set, and info message type to ChatMessage. This gives web users feedback for slash commands (unknown commands, skill list output, etc.) that was previously TUI-only.
The skill_run RPC was calling POST /api/skills/run which doesn't exist (server expects /api/skills/<scope>/<name>). This caused skills to silently fail, leaving the web UI stuck in 'Reasoning' state. Now routes through POST /api/submit with '/skill <name>' text, matching TUI behavior. Also emits $error on failure instead of silently swallowing errors.
Web dashboard now uses the same /skill <name> syntax as the TUI instead of the shorthand /<name>. Autocomplete entries and user messages in the thread both reflect the canonical syntax. Unknown /<word> inputs that don't match a skill fall through to user_input for proper 'unknown command' feedback.
The web API's listSkills() function skipped symlinked skill directories (entry.isDirectory() returns false for symlinks), causing the web dashboard to show fewer skills than the TUI. Replaced the independent listSkills() calls with SkillStore.list() which correctly resolves symlinks via statSync, ensuring both surfaces show identical skill lists.
|
@codex review |
|
To use Codex here, create a Codex account and connect to github. |
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 50485dc9e2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
toEntries and builtin mappings now include runAs and model from SkillStore so subagent skills display correctly in the web dashboard instead of defaulting to inline.
|
Codex Review: Didn't find any major issues. Delightful! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Closes #2357
Summary
Fix four web dashboard bugs that caused parity issues between the TUI and web interface.
Bug 1: Web dashboard missing info/error feedback from slash commands
Slash commands like
/unknowncmd,/help,/statusproduce info text in the TUI but nothing in the web dashboard.Root cause:
loopEventToDashboard()had no case forinforole events;sseToIncoming()had no case forkind: "info".Fix:
src/loop/types.ts— Added"info"toEventRoleunion typesrc/cli/ui/effects/loop-to-dashboard.ts— ConvertinfoLoopEvents to DashboardEventssrc/cli/ui/App.tsx— Broadcast slash commandinforesults to SSE subscribersdashboard/src/lib/tauri-bridge.ts— Handlekind: "info"insseToIncomingdashboard/src/App.tsx— Handle$infoevents in reducer, render info rowsdashboard/src/protocol.ts— AddedInfoEventtypedashboard/src/icons.tsx— AddedinfoiconBug 2:
skill_runRPC stuck in "Reasoning" spinner foreverRoot cause: Web frontend's
skill_runRPC calledPOST /api/skills/runwhich doesn't exist (server expects/api/skills/<scope>/<name>), returning 400 silently.Fix: Route
skill_runthroughPOST /api/submitwith/skill <name>text, matching the TUI code path. Emit$erroron failure instead of swallowing errors.Bug 3: Inconsistent skill invocation syntax
TUI uses
/skill <name>, web used shorthand/<name>.Fix: Unified autocomplete entries and user messages to
/skill <name>in both interfaces.Bug 4: Web skills list shows fewer skills than TUI
Root cause: Web API's
listSkills()usedentry.isDirectory()which returnsfalsefor symlinks, skipping all symlinked skills.Fix: Replaced
listSkills()withSkillStore.list()which correctly resolves symlinks viastatSync.Tests
infoevent conversion test intests/loop-to-dashboard.test.ts