夢想 Musou / System

A terminal line, sorted before it reaches the model.

Musou was a browser-based code editor from early 2024, built months after ChatGPT: a CodeMirror pane and a terminal that was also the assistant. Each line typed into the terminal was walked through a static lookup table; what matched ran as a command, and everything else went to GPT-4 with the open file attached as hidden context. It stayed a prototype.

live command paths: clear, code, analyze, analyze abstract, rename, chat
6live command paths: clear, code, analyze, analyze abstract, rename, chat
API endpoints planned in the architecture note; 10 route handlers exist
17API endpoints planned in the architecture note; 10 route handlers exist
system prompts, temperatures or token limits set on the chat call
0system prompts, temperatures or token limits set on the chat call
Redux slice: messages, the one stream the terminal and the assistant share
1Redux slice: messages, the one stream the terminal and the assistant share

Specified from the prototype’s source, a single commit of March 2024No runtime data; the repository is the evidence

01

The run

The path of one terminal line from submit to the streamed reply. The lookup table runs first; the model receives only what the table did not match.

1.0

Four identities the prototype is built from.

Named once here; the sections below refer to them.

Design identities and where each appears
IdentityRuleAppears in
Table before modelDeterministic lookup first; the model is the default branch, never a classifier.Command walk, fallback, help
One streamCommands, errors, code context and model replies are messages in one ordered array with a role; rendering and the model request both read that array.Redux messages slice, renderer, role map
Hidden contextThe editor buffer is a message the user never sees and the model always does, kept in place rather than appended.Code context injection
Client-owned persistenceThe browser writes to the database directly and optimistically; the server is reached only for the model and for titles.Save debounce, React Query, Supabase client

1.1

Classification: a token walk over a static handler table.

Table before model. The input splits on spaces; a nested handler object is walked token by token, lowercased, with a default at each level. The walk ending without a handler is the model call.

switchyardrest
0.72 of the siding
A main line fans into six sidings: the blade swings to the one under the pointer and the wagon runs out along it.

The figure is the classifier: the blade is set by the first tokens of the line before the wagon reaches it, so the wagon can only take the siding the table chose. Five sidings are handlers; the sixth is the model call, which receives every line the table did not match.

  1. 01 Rewrite

    An alias at the start of a line becomes the mark 夢想.

    Reads
    The textarea as you type
    Returns
    The line with 夢想 in place of mu, musou or ms
  2. 02 Split

    The line is split on spaces into tokens.

    Reads
    The submitted string
    Returns
    string[]
  3. 03 Walk

    parseCommand follows COMMAND_HANDLERS by token, lowercased, with a default at each level.

    Reads
    The tokens
    Returns
    A handler, or the default: chat
    When it cannot
    A table with no default, like 夢想 project, calls undefined and throws.
  4. 04 Run

    The handler logs its own message to the stream and does its work.

    Reads
    The Redux messages slice
    Returns
    A user message, then an ai or system message
  5. 05 Stream

    A chat posts the mapped history and writes each chunk back into one message.

    Reads
    /api/v1/assistant/chat
    Returns
    The whole string so far, dispatched on every chunk
Limits of this part+

There is no regex and no model in the classifier. The alias rewrite is the only regex: `(^|\\n)(mu|musou|ms) ` becomes `夢想 ` as you type. Submit is Ctrl or Cmd with Enter; a Ctrl+M binding only logs to the console.

1.2

Six handler paths; the default is a model call.

A command that matches is cheap and deterministic. A line that does not match costs a GPT-4 call, including the error text that tells the user to type help, because no help handler exists.

Each input, its handler and its effect
InputHandlerEffect
clear [n]useUtilCommands.clearRemoves the last n messages. With no n, parseInt gives NaN and everything clears.
夢想 code <src>useCodeCommands.setNewCodeLogs a code message and calls setCode. The editor is bound to the stored file, so the change does not persist.
夢想 analyze [abstract]handleDefaultMessageInputSends the raw text to the model. No special prompt.
夢想 rename [title]renameRenames the file through the API.
夢想 <unknown>handleFallbackCommandInputAn error, or a "secret command" info message.
anything elsehandleDefaultMessageInputChat with the model.

1.3

The chat route sets no system prompt, temperature or token limit.

One stream, mapped to roles: the edge route forwards the whole message array to gpt-4-1106-preview with stream on. No system prompt, no temperature, no max tokens.

The chat route
export const runtime = 'edge'
const response = await openai.chat.completions.create({
  model: 'gpt-4-1106-preview', stream: true, messages,
})
return new StreamingTextResponse(OpenAIStream(response))

Roles, as the client maps them before the call

system → user
errors and the code context go to the model as user turns
ai → assistant
the stream so far
user → user
the typed line
Limits of this part+

The route has no auth check; middleware gates only /dashboard. The assistant key is commented out, the thread route is a stub, and the persona in musou-assistant/instructions.md, with its maintainability score out of 10, is prompt text that nothing loads.

1.4

The editor buffer is injected as a hidden system message.

Hidden context: one system message holds the editor buffer, spliced in once three from the end and updated in place, so the model always sees the current code and the user never sees the message.

Where

Index −3 in the messages array.

Behind the last user line and the blank ai message that will receive the stream.

When

Once, then updated in place.

A change in the editor rewrites the hidden message rather than adding one.

Shown

Never.

The renderer has no component for system/code-context, so the stream shows nothing for it.

Limits of this part+

The whole buffer is sent on every chat with no truncation; the model's context window is the only bound.

1.5

File titles come from a second model call on a text heuristic.

When a new file gets its first message, gpt-3.5-turbo-16k is asked for a very short title. The trigger is a heuristic on the text, not a schedule.

The title fires when the first message

contains
the word code
or contains
a character outside letters, digits, whitespace and .,-!?;:
or is longer than
200 characters
and the file is still called
New File
02

Editor and data

The editor is a CodeMirror pane bound to a Supabase row. Code and titles persist; the message stream does not.

2.1

Editor: one language extension, a 2 s debounce, an optimistic client write.

Client-owned persistence. The editor is @uiw/react-codemirror with the JavaScript language (JSX and TypeScript on). An edit updates the hidden context at once and, two seconds after the last keystroke, writes the code to Supabase from the client through React Query.

Timing

Save debounce
2 000 ms, continuous
File query stale time
1 hour, no refetch on focus
Project query
stale 1 min, refetch every 5 min
Route to a file
middleware sends /dashboard/:user/:project to the last edited file, or makes one
Limits of this part+

There is no file tree or virtual file system: a project is a flat list of files. Escape blurs the editor so Tab does not trap the keyboard.

2.2

Data: three tables; the chat thread is not persisted.

Projects, Files and Identity. Code, titles, profile and custom instructions are saved. The chat thread lives only in Redux: the call that would save it is commented out. Custom instructions are saved but never sent to the model.

The schema
TableColumnsWritten by
Projectsid, owner_id, title, description, intent, keywords[], dependencies[], code_language, privacy, thread, last_editedThe app, through the API
Filesid, project_id, code, thread, title, name, code_annotations, documentation, metadata, intent, keywords[], dependencies[]code and title only
Identityprofile fields, custom_instructions, palette_presets[], feature_flags, subscription_type, user_roleprofile and custom_instructions

Auth and plans

Sign-in
email and password, GitHub, Google
Gate
middleware redirects anyone without a session away from /dashboard
Plans (copy only, not enforced)
Free $0: 1 project, 10 files, 50 chats a day · Plus $14.99 · Pro $20
Limits of this part+

The /api/user routes decode the bearer token without verifying its signature and query with the service-role key. getFile checks that the user owns the project but not that the file belongs to it. The documentation, code_annotations and metadata columns have Zod schemas and no writer.

2.3

Palettes: seven token colours, four presets, localStorage only.

The palette manager holds identifier, keyword, string, class, sign, comment and JSX literal colours. It writes them to CSS variables and converts them into a CodeMirror theme. Custom presets go to localStorage; the Identity column for them is mapped but never read.

Presets
SH Default, v0, vercel, Dracula
Storage key
"palettes" in localStorage
Applied as
--sh-* variables and a CodeMirror theme
03

Interface rules

Tokens, layout, the decisions behind the structure, and what the prototype did not finish.

3.1

Tokens and layout.

theme.colors is set at the top level, so the default Tailwind palette is gone. Dark mode is the default and dark is #000.

Colour

OffWhite
#e2e2e2
LunarGrey
#202020 to #8B8B8B
terminal foreground / highlight
#A6A4A1 / #FFE86D
cli musou
cyan in light, yellow in dark
cli command / error
#ff6dfd / #ff6d6d

Layout and type

Panes
a row at lg, stacked below; sidebar 260 px
Mobile sidebar
a drawer at 45dvh
Body face
Inter; Cygnito Mono on the landing, nav and 404
CLI face
the system monospace
Buttons
rounded-3xl, VoidBlack, OffWhite border at 33%

3.2

Trade-offs.

Each choice, why it was made, and what it costs.

Design decisions, reasons and costs
DecisionReasonCost
A lookup table before the modelKnown commands are free and deterministic.Every unknown line, including the error that says type help, costs a GPT-4 call.
One stream for terminal and chatOne place to read; commands and answers in order.Errors and the hidden context reach the model as user turns.
The code buffer injected automaticallyThe model always sees the current file.The whole file on every call; no truncation.
Scoring as a prompt instructionCheap to write.No structured output; nothing parses or shows a score.
Client-side Supabase writesOptimistic saves with little code.Authorisation depends on row policies that the API routes bypass with the service key.

3.3

Unfinished and missing.

From todo.md and the code.

Tests
none
Maintainability score in code
none: prompt text only
Saved chat threads
none: the save is commented out
Done from todo.md
password recovery, email verification, Stripe, message sync, typing indicators, editing, light mode: none
DEBUG_MODE in middleware
true
Unmounted code
local-storage util, MusouPreview, the text editor interface, the ai/list message type