fix(web): align Kit routes with frontend transport contract#84
Merged
Conversation
Kit routes were registered REST-style (e.g. GET /api/kits/candidates) while
the frontend transport posts flat command names (POST /api/list_kit_asset_candidates).
Every Kit endpoint therefore fell through to the SPA fallback and returned
200 text/html, which the frontend failed to parse as JSON β so web mode
silently showed empty kit lists and no skill candidates while desktop worked.
Align all 12 kit routes to POST /api/{command}, and fix the handler body/
response shapes to match the frontend: unwrap { req } payloads, read { id }
from the body instead of path params, and return JSON () instead of empty
204 bodies (which would break the frontend's unconditional response.json()).
Add a regression test asserting kit commands return JSON, not the SPA fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In web mode (
hk serveβ browser), the Kits page showed empty kit lists and the new-kit dialog couldn't discover any existing skills/MCPs β while the desktop app worked fine on the same machine / same database.Root cause
The frontend transport posts every command as
POST /api/{snake_case_command}(src/lib/transport.ts), and all other features' routes follow that contract. The Kits block alone was registered REST-style:POST /api/list_kit_asset_candidatesGET /api/kits/candidatesPOST /api/list_kitsGET /api/kitsPOST /api/create_kitPOST /api/kitsNone matched, so every kit request fell through to the SPA
fallback(serve_frontend)and returned 200 +text/html(index.html). The frontend then calledresponse.json()on HTML β threw β.catch(console.error)swallowed it β lists stayed empty, with no visible error. Desktop was unaffected because Tauriinvokedispatches by command name directly.Verified empirically (oneshot against the real router):
POST /api/list_kit_asset_candidatesβ200 text/html;GET /api/kits/candidatesβ200 application/json.It went unnoticed because: zero router-level test coverage for kits, the failure was silent (200 + swallowed parse error), and the embedded
dist/was stale.Fix
POST /api/{command}, matching the frontend transport and the desktop Tauri command names.{ req }payloads (create/update/preview/sync/unsync),{ id }from the JSON body instead of path params (get_details,delete_kit),()instead of empty204bodies (which break the frontend's unconditionalresponse.json()).kit_command_routes_return_json_not_spa_html) asserting kit commands reach a JSON handler, not the SPA HTML fallback.Testing
cargo test --workspaceβ all green (hk-core 519, hk-web 8, β¦), including the new regression test.npm run testβ 231 passed.biome checkclean; no new clippy warnings from the change.npm run dev@ 1420): existing kits appear and skills are discoverable in the new-kit dialog.π€ Generated with Claude Code