Repository navigation
[Stage 3 / P2] refactor: split slash.js into interaction/ + feedback/ subsystems #27
Description
[Stage 3 / P2] refactor: split slash.js into interaction/ + feedback/ subsystems
Author: @modacker
Source borrow:docs/BORROW-dsh-deepseek-harness-2026-08-28.md
borrow #3.
Related: Stage 1 event log + authorize helper should be in
place first (this refactor wires into them).
Why
server/lib/slash.js is a 304-line god module that mixes
governance and non-governance concerns. The deepseek-harness (dsh)
project demonstrates a clean split: packages/interaction/ owns
the act of asking (commands, permissions, ask-user, approvals,
questions) and packages/feedback/ owns the response on past acts
(command feedback, message feedback).
Today mcode-webui has no feedback/ concept at all — users have
no way to rate a response, no way to flag a bad tool call, no way
to say "this plan was wrong". As governance actions are added
(Stage 1 authorize + anomaly), feedback becomes load-bearing for
the "what just happened" UX.
The win is decoupling the LLM-facing API from the UI: today
mcode-webui has the LLM directly write to its chat stream. After
this refactor:
- Slash commands can be UI-gated (per Stage 1 authorize)
- Tool-ask-user becomes a typed modal (vs the current ad-hoc parsing)
- Feedback events get their own append-only log entries (per Stage
1 event log) - The 304-line file becomes 5–6 files of ~50–100 lines each,
with one responsibility each
What
Mechanical refactor: split slash.js (304 lines) into:
server/lib/interaction/commands.js— slash command dispatchserver/lib/interaction/permission-presets.js— named permission
policies (currently inline inroutes/model.js#handleSetPermissions)server/lib/interaction/tool-ask-user.js— mid-toolAskUser
modal handlerserver/lib/interaction/user-questions.js— typed question UI
(text/choice/confirm), currently ad-hoc inroutes/model.jsserver/lib/feedback/command-feedback.js— emit feedback events
on slash command completionserver/lib/feedback/message-feedback.js— emit per-message
feedback (thumbs up/down + comment)
Each file is the seam; the SSE channel for human prompts is
the single shared transport (already exists at /api/events).
Do NOT vendor dsh's Cordis framework or its monorepo structure —
mcode-webui's design constraint is "zero npm deps". Borrow the
concept (subsystem split), not the implementation (Cordis
plugins).
Acceptance criteria
-
server/lib/slash.jsno longer exists; its exports are
re-exported fromserver/lib/interaction/commands.jsfor
backward compatibility (or callers are updated) - Each of the 6 new files is ≤ 150 lines
- No behavior change for existing tests (target 470/0/2 +
any new tests in the new files) - New
feedback/modules emitevents.ndjsonlines (uses
the Stage 1 event log) -
npm testpasses;npm run lintreports 0 warnings
Out of scope
- Multi-package monorepo split — single plugin stays single plugin
- Cordis framework adoption — would violate zero-dep contract
- dsh's
sandbox/code-runtime— mcode concern, not webui - mcode-side
goal//plan/packages — mcode concern, not webui
Activity
modacker commentedon Sep 17, 2026
Withdrawing alongside the mcode-webui PR closures (#23/#31) — with the marketplace submission pulled, this proposal no longer has an owner here. Re-open if it becomes relevant again.