Skip to content

fix: Web ↔ TUI skill parity — info events, skill_run RPC, symlink skills#2359

Open
lanshi17 wants to merge 7 commits into
esengine:v1from
lanshi17:fix/web-tui-skill-parity
Open

fix: Web ↔ TUI skill parity — info events, skill_run RPC, symlink skills#2359
lanshi17 wants to merge 7 commits into
esengine:v1from
lanshi17:fix/web-tui-skill-parity

Conversation

@lanshi17
Copy link
Copy Markdown

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, /status produce info text in the TUI but nothing in the web dashboard.

Root cause: loopEventToDashboard() had no case for info role events; sseToIncoming() had no case for kind: "info".

Fix:

  • src/loop/types.ts — Added "info" to EventRole union type
  • src/cli/ui/effects/loop-to-dashboard.ts — Convert info LoopEvents to DashboardEvents
  • src/cli/ui/App.tsx — Broadcast slash command info results to SSE subscribers
  • dashboard/src/lib/tauri-bridge.ts — Handle kind: "info" in sseToIncoming
  • dashboard/src/App.tsx — Handle $info events in reducer, render info rows
  • dashboard/src/protocol.ts — Added InfoEvent type
  • dashboard/src/icons.tsx — Added info icon

Bug 2: skill_run RPC stuck in "Reasoning" spinner forever

Root cause: Web frontend's skill_run RPC called POST /api/skills/run which doesn't exist (server expects /api/skills/<scope>/<name>), returning 400 silently.

Fix: Route skill_run through POST /api/submit with /skill <name> text, matching the TUI code path. Emit $error on 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() used entry.isDirectory() which returns false for symlinks, skipping all symlinked skills.

Fix: Replaced listSkills() with SkillStore.list() which correctly resolves symlinks via statSync.

Tests

  • Added info event conversion test in tests/loop-to-dashboard.test.ts
  • Full suite: 4042 passed, 0 failed (314 test files)
  • Build: Clean, no TypeScript errors

lanshi17 added 6 commits May 29, 2026 23:03
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.
@lanshi17
Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@lanshi17
Copy link
Copy Markdown
Author

To use Codex here, create a Codex account and connect to github.

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/server/api/skills.ts
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.
@lanshi17
Copy link
Copy Markdown
Author

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 50485dc9e2

ℹ️ About Codex in GitHub

@codex review : Fixed in 7593492. toEntries and builtin mappings now pass through s.runAs and s.model from SkillStore.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

ℹ️ 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".

@esengine esengine added the v1 Legacy TypeScript line (0.x) — v1 branch, maintenance only label May 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v1 Legacy TypeScript line (0.x) — v1 branch, maintenance only

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: Web dashboard missing info feedback & skill_run RPC broken & symlink skills not listed

2 participants