Skip to content

Latest commit

 

History

300 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Muse Spark Code: Meta's Muse Spark as a coding agent inside VS Code

Marketplace version Marketplace installs CI VS Code 1.125 or newer WCAG 2.2 AA checked 15 languages MIT license Donate via PayPal

Muse Spark Code puts Meta's Muse Spark model to work inside VS Code as a coding agent. A chat panel streams answers, reads and edits your files with reviewable diffs, runs commands behind permission modes, and delegates to subagents you can watch and steer. It also remembers past conversations and takes dictation from your microphone. It runs on your Muse subscription through the Muse Code CLI, or on a Meta Model API key, and never mixes the two.

Unofficial. Not affiliated with or endorsed by Meta. "Muse Spark" and "Muse Code" are Meta trademarks. You bring your own credentials.

Contents: What's new · Highlights · Screenshots · Get started · Backends · Permission modes · Rules, skills and memory · Muse Code's own tools · The panel · Voice dictation · Paid features · Languages · Limits · Commands · Settings · Requirements · Privacy · Troubleshooting · Development

What's new in 0.9.0

  • Install and sign in from the panel. Without Muse Code, Install Muse Code shows Meta's install command for your system and runs it in a terminal you can watch, then offers sign-in. Sign in with your Meta account now shows its approval code right in the panel.
  • PDFs and text files. Attach, paste or drop PDFs (up to 32 MB) on the Model API backend, and pick UTF-8 text files from the workspace on either backend. The Model API agent also reads workspace PDFs and images itself.
  • The Model API backend catches up with Muse Code:
    • the MCP servers from Muse Code's settings and the same memory notes;
    • session goals, ! shell commands and background work;
    • opt-in hooks and subagents.
  • Paid extras, opt in and loud. Web search, image generation and edits, Muse Voice, subagents and scheduled /loop prompts on your Model API key. Each is off until you turn it on and accept its price, every use is marked paid, and Account & usage tallies them.
  • Rewind the conversation, or take a side chat. Any sent message can branch the conversation before itself; Side chat opens a Plan-mode branch without stopping the main one.
  • More of Muse Code in the panel. A row for every tool Muse Code runs, workflows as live cards, goals, and background tasks you can stop.
  • Behind a corporate network. Muse Code gets VS Code's proxy, museSpark.sandboxNetwork sets its sandbox network, a request that never reached Meta says why, and Muse Spark: Diagnostics reports the network posture.

0.8.0 brought the panel in fourteen languages; 0.7.0 brought / as in Claude Code, skills, MCP servers and hooks in the panel, worktrees, export and the accessibility gate.

Every change is in the CHANGELOG.

Highlights

  • Streaming chat with tools you can see. Every read, edit, write and shell command is a row in the transcript: green when done, pulsing while running, red when refused, grey when a stopped turn cut it off. Edit rows show the diff, the path opens the file with the changed lines selected, Click to expand opens VS Code's diff editor, and any output opens in an editor tab with a click.
  • Permission modes, like Claude Code. Manual, Edit automatically, Plan and Auto (Bypass behind a setting), switched from the mode button or Shift+Tab. Gated commands arrive as approval cards with the CLI's own choices; questions from the agent arrive as question cards with radios, checkboxes, tabs and an "Other" answer.
  • / for everything. The palette holds the actions, the model, effort and thinking, the permission mode and your skills; type a letter after the / and it narrows to the slash commands, as in Claude Code.
  • Subagents on a map. When Muse Code delegates, or the Model API backend runs the paid subagents you turned on, each agent is a row and an N agents pill opens the Agent map: role, status, tokens, each agent's own transcript, and the controls the backend offers.
  • Workflows you can follow. When Muse Code runs a multi-agent workflow, the run is a card that keeps updating after the reply: its agents with their state, time and tokens, and the result it returned. Owner controls wait for a live accepted-command capture.
  • Reply and quote with context. A reply's ⋯ menu has Reply to this output; highlight anything in the chat and right-click for Ask about this or Comment on this. The passage, its author and your intent travel with the message.
  • Voice dictation at no cost. Tap or hold the microphone (Ctrl+D) and speak; the words land at the caret. Windows and macOS use the recogniser built into the operating system, so no audio goes to a paid service unless you turn on Muse Voice.
  • Paid extras, only if you ask. On a Model API key: web search with its sources, image files made on request, and Meta's Muse Voice for dictation. Each is off until you turn it on and accept its price, marked paid wherever it is used, and tallied in Account & usage.
  • Scheduled prompts under your control. On the Model API backend, /loop saves a recurring prompt in this conversation. A due prompt waits for you to run and confirm it; your key is never spent unattended.
  • Two backends, never mixed. Your Muse subscription through the Muse Code CLI, or a Meta Model API key (pay as you go) with the extension's own tools. The pasted key is never handed to the CLI.
  • Set up from the panel. No Muse Code yet? Install Muse Code shows Meta's command and runs it in a terminal; Sign in with your Meta account shows its approval code in the panel.
  • Context the way you work. @ mentions with .gitignore-aware fuzzy search, the open file or selection as a chip, images and PDFs pasted or dropped, and Alt+K to mention the editor selection. On the CLI backend the agent can also read the Problems panel.
  • History that survives the window. Every conversation in the workspace, searchable, resumable with its full transcript, archivable, with fork and rewind on every sent message. The sidebar picks its last conversation back up within ten minutes, and an editor-tab conversation comes back after a window reload.
  • Account & usage. On Muse Code, your subscription's current and weekly windows; this conversation's tokens (and cache hits, on the Model API); and what has been eating your usage (reminder agents, subagents, long sessions), from /usage.
  • In your language. Fourteen of VS Code's display languages, with the model's side kept in English so it behaves the same everywhere.
  • Accessible and observable. Checked against WCAG 2.2 AA in every default theme, and a log that records what happened without what you wrote.
  • No telemetry, no hosted server of its own. What leaves your machine and where it goes is written down in PRIVACY.md.

Screenshots

Rendered from the shipped panel by its own UI harness (npm run harness:shots) against a scripted session, so they match the build.

A turn: Thought for 1s, Read, an Edit row with its diff and Click to expand, a Write row, a PowerShell row with its input and output, the reply, and Working…
A turn: thinking, read, edit with its diff, write, shell, and the reply
The Agent map over a transcript: the 2 agents pill, this conversation, two agents, one running and one with its result ready, with their duration and tokens
Subagents: the 2 agents pill and the Agent map
A slash typed in the prompt and the palette above it: Context, Model and Customize groups with effort dots and a thinking toggle
Type /: the palette above the prompt
The prompt holding /co and the Slash commands list above it: /compact, /config, /cost, /clear, /export, /resume, /usage, each with its description
A letter more: the slash commands, ranked as you type
An approval card: Muse wants to Set-Content, step 1 of 2, a feedback box, Allow once, Always allow in this workspace, Reject
An approval card with the CLI's own choices
A question card with Colour and Toppings tabs, radio buttons, an Other answer, Submit greyed out, Explain instead and Cancel
A question card: tabs, radios or checkboxes, Other, Submit, Explain instead and Cancel
A highlighted passage of a reply with the Copy / Ask about this / Comment on this menu
Highlight, right-click: Copy, Ask about this or Comment on this
A sent message's rewind menu: Fork conversation from here, Rewind conversation to here, Rewind code to here, Fork conversation and rewind code, with the Side chat button in the header
Every sent message: fork, rewind the conversation or the code, or fork and rewind
The Modes menu: Manual, Edit automatically, Plan, Auto, each with its one-line description, and the effort row
Permission modes, one line each, Shift+Tab to cycle
The History dialog: sessions grouped by day, search, Show archived
History: search, resume, archive
The Account & usage modal on Muse Code: auth method, plan, backend, the current window and week bars, this conversation's tokens and context, what is contributing to usage by day or week, and Add Model API key
Account & usage: windows, tokens, and what is eating the usage
The composer listening: the red microphone and the Listening placeholder over a new conversation with its keyboard tips
Voice dictation: tap or hold, Ctrl+D

Get started

  1. Install Muse Spark Code from the Marketplace (VS Code 1.125 or newer), or from a .vsix attached to a GitHub Release:

    code --install-extension muse-spark-code-0.9.0.vsix
  2. Open the Muse Spark view from the activity bar (or press Ctrl+Shift+Alt+Esc on Windows, Cmd+Shift+Esc on macOS, Ctrl+Shift+Esc on Linux for a conversation in an editor tab).

  3. If Muse Code is missing, Install Muse Code opens a confirmation dialog showing Meta's exact command for this operating system. The same action is in Account & usage while you work with a Model API key. Run installer opens a visible VS Code terminal; the panel checks for the CLI and offers sign-in when it appears. You can also open Meta's installation instructions. If VS Code cannot open the installer terminal, the panel reports that directly and keeps the manual instructions available. Sign in, one of two ways:

    • Sign in with your Meta account shows an approval code in the panel. Open its sign-in page in your browser and approve the code within ten minutes, before it expires. Cancel sign-in stops the temporary CLI sign-in process; if the browser approved just before, the panel follows what Muse Code saved. If you deny the code, it expires, or Muse Code cannot save the sign-in, the panel says so; an ending Muse Code has not been seen to send is shown in its own word. Work is billed to your Muse subscription.
    • Use a Model API key takes a key from dev.meta.ai (Meta's current keys start with LLM_; older ones look like LLM|<id>|<secret>), stores it in VS Code's secret storage and runs the Model API backend with the extension's own tools, pay as you go. Account & usage lets you add or replace that key while Muse Code is signed in; there the key pays only for paid features you turn on. After a CLI install, Account & usage also offers Sign in with your Meta account.

    Signing out ends the old account's conversations and clears them from the panel; your unsent draft stays. If sign-out cannot finish, see Troubleshooting.

  4. Type a message and press Enter. / shows the palette, @ mentions a file, the microphone dictates.

VS Code opens the extension's four-step walkthrough on install; Muse Spark: Open Walkthrough brings it back.

Each panel is its own conversation, started on the first message with the standard muse-spark-1.3 model (never a contributor-tier model by default). The model pill shows the model as soon as the panel opens.

Backends

Backend Sign-in Billing Tools
Muse Code CLI (muse serve, Muse Session Protocol via @muse-code/sdk) The CLI's own device-code browser sign-in Your Muse subscription The CLI's, inside its OS sandbox where that works (see shellSandbox); its bundled skills, your user rules, its own memory, subagents, and the Problems panel through the extension
Meta Model API (https://api.meta.ai/v1) A key from dev.meta.ai, kept in SecretStorage, sent only to Meta Pay as you go The extension tools: read, edit, write, search, list, shell, skills, questions, todos, goals, memory and diagnostics; configured MCP servers; opt-in hooks and bounded subagents; paid web search and image tools when turned on; workspace rules and skills

museSpark.backend picks: auto (default) uses the CLI when it is installed and signed in, otherwise the Model API when a key is stored; museCode and modelApi force one. The palette's Backend row shows which one this window runs on. The CLI looks for muse through museSpark.museBinaryPath, then PATH, then the platform's install folder (%LOCALAPPDATA%\Programs\muse on Windows, ~/.local/bin elsewhere).

Conversations on the Model API backend are saved as they go under VS Code's workspace storage for the extension, so the History dialog lists them after a reload, and a resumed one continues with its transcript and its edit patches while the same Model API key is stored. History, resume, reads and forks are limited to that key's sessions. Replacing the key starts a fresh conversation; older sessions remain on disk for their original key. Sessions saved before ownership was recorded remain on disk but cannot be reopened because their account cannot be proved. The CLI backend keeps its own session store. Replacing its secondary Model API key keeps the Muse Code conversation running. A paid image awaiting its popup or a retry stops if that key changes; the old request cannot use the new key. If the panel itself ever fails to render, it shows the error and a Reload button instead of going blank; Reload brings the conversation back as it was, running turn and waiting cards included.

Sign-out and account replacement clear the panel's transcript, loaded tool output, agent transcripts and retained file chips before another account signs in. Unsent draft text stays in the composer. When an installer makes a signed-in Muse Code CLI available in auto mode, the current Model API session ends before the next message starts a fresh CLI session.

Permission modes

Mode Model API backend Muse Code backend
Manual Asks before every edit and every command The CLI decides: it applies edits inside the workspace without asking (Muse Code 1.3.0) and asks before commands
Edit automatically Approves plain file edits, asks before commands As Manual, plus the file approvals the CLI does raise are approved for you
Plan Refuses edits and commands The CLI plans without editing
Auto Runs edits, asks before commands (no safety-check model on this backend) The CLI runs its own safety check and asks for anything risky
Bypass Only with allowDangerouslySkipPermissions; nothing asks The same

A Manual approval still needs your answer if you open the conversation in another panel set to Edit automatically. Joining a conversation never approves a card that was already waiting. A Manual panel's new edit approval also stays Manual when an older Edit automatically panel remains open on that conversation. While two panels share a conversation, every approval needs an explicit choice. Edit automatically resumes when it is the only panel holding that session.

"Always allow in this session" on a command allows that exact command line again, nothing broader; on an MCP tool, that tool. An MCP tool asks like a command on the Model API backend; Auto runs one its server marks read-only without asking, as Muse Code does, and Plan refuses all but those, which ask. The Model API backend's file tools refuse any path that leaves the workspace, including through a symbolic link or junction inside it. Muse Code refuses such a write while its sandbox runs; without the sandbox (shellSandbox set to off, or auto for a Windows workspace under your profile) its file tools may write outside the workspace, so choose the permission mode with that in mind.

Protected writes. On the Model API backend, writes to files that configure or run code always ask, whatever the mode: .git, .husky, .vscode, .idea, .devcontainer, .github/workflows, .agents (the agent's own skills and memory), .muse (Muse Code's hooks), AGENTS.md, CLAUDE.md, .envrc and .gitmodules. Plan refuses them and Bypass skips the card. On Muse Code the CLI decides which writes are protected, and the extension never approves one for you. A note saved with the memory tools is the one exception under .agents: those tools write only Markdown notes in the memory folders, so they are treated as ordinary edits (see Memory).

Rules, skills and memory

In a trusted workspace the agent follows the same files Muse Code does:

  • Rules: AGENTS.md at the workspace root (CLAUDE.md where there is no AGENTS.md), and the same files in subdirectories, which apply once the agent touches a path beneath them; the deeper file wins.
  • Skills: .agents/skills/<id>/SKILL.md in the workspace (project scope) and Muse Code's personal root ~/.config/muse/skills ($XDG_CONFIG_HOME/muse/skills when set). The palette's Skills group lists them, /id arguments invokes one, and the model loads one itself when a task matches its description. user-invocable: false in the front matter keeps a skill out of the palette.
  • Memory: Markdown notes the agent keeps for later conversations, in Muse Code's three places, on both backends; see Memory.

Muse Spark: Create AGENTS.md starts the rules file for a workspace that has none. muse init writes it when the CLI is installed and the workspace is trusted (the CLI's own scaffold, no model call); otherwise the extension writes the same layout. An existing file is opened, never overwritten.

On the CLI backend Muse Code loads all of this itself (the extension starts it with --trust-workspace), plus its bundled skills and your user rules. On the Model API backend the extension loads the files above and nothing else:

  • Sizes: a rules file or a SKILL.md over 64 KB is skipped with a warning in the log; the rules together are cut at 256 KB, and each scope's MEMORY.md at 200 lines or 32 KB.
  • Encodings: UTF-8, or UTF-16 with a byte-order mark; a file that is not text is skipped with a line in the log. Memory notes are UTF-8 only, as Muse Code reads them.
  • Links: a skill folder may be a symbolic link or junction. In the workspace it must lead to a place inside it or it is skipped; links in the personal root are followed wherever they lead.
  • The system prompt also carries the date, the git branch, the number of changed files and the latest commit subjects at session start (metadata only), and a short set of working rules (read before editing, no commits unless asked, path:line references).

In VS Code's Restricted Mode (an untrusted folder), neither backend loads rules or skills. The Model API backend loads no memory, offers no memory tools, starts no MCP servers and runs no hooks. No shell command or git runs (git reads the repository's own config, which can name programs to run): @ mentions come from VS Code's file search and the prompt carries no git facts. Trust the workspace to enable them. Muse Code itself, by its documentation, still reads a repository's committed project memory in an untrusted workspace: treat a checkout's .agents/memory/MEMORY.md as text someone else wrote.

Memory

Muse Code keeps memory in three scopes, and both backends read and write the same notes, so a fact saved in one is known in the other:

Scope Where the notes are Who sees them
Your memory for this project (the default) ~/.local/share/muse/memory/projects/<folder>-<hash>, outside the repository You, in this workspace
Project memory .agents/memory in the repository Everyone who clones it
Your memory for every project ~/.local/share/muse/memory/personal You, everywhere

$XDG_DATA_HOME replaces ~/.local/share when it is set (on Windows too, as Muse Code does). Each scope may keep a MEMORY.md index, one line per note: - [Title](file.md) | hook. Names with spaces or Markdown punctuation are encoded in the index link, so the note can still be found and its line removed when the note is deleted.

  • Memory… in the palette (/memory, or Muse Spark: Memory in the Command Palette) lists up to 500 Markdown notes per scope, nested up to eight folders, with each note's scope and what it is about. Pick one to open it in an editor, where you read and change it like any file, or to delete it (to the trash, after a confirmation). New note… asks for the scope, a name and a one-line description, creates the note and opens it. A note the view creates gets its line in the scope's MEMORY.md, and a note it deletes loses its lines, so the index the next conversation reads stays true.
  • On the Model API backend the model has Muse Code's own memory tools, read_memory, add_memory and edit_memory, with the same arguments and results, so their rows look the same as on the CLI backend. At the start of a conversation it is given each scope's MEMORY.md and the names of the other notes (up to 48 per scope), as Muse Code gives them. A new note gets its line in its scope's index. A write asks in Manual, is made in Auto and Edit automatically, and is refused in Plan, like any edit; a read never asks. A path Muse Code would refuse (outside the scope, hidden, not a .md file, or through a link) is refused before any card.
  • On the CLI backend Muse Code runs its memory tools itself.

A new note is published only if its path is still free. The extension writes and syncs it under a hidden temporary name, then hard-links the complete file to the note's name in one step. Another writer's file is never replaced or exposed half written; a filesystem without hard-link support refuses the create rather than using a partial-write fallback. The index line is added only after publication. Updates to an existing note replace it whole (a temporary file renamed over it). The extension does not take Muse Code's own lock, so two agents updating the same note or index in the same instant could lose one of the writes. The .muse-memory.lock file can remain after its owner exits; its presence or stored PID alone does not show that a write is in progress.

Muse Code's own tools

These use the Muse Code CLI, except worktrees, MCP servers and hooks, which the Model API backend has too (each says how below); memory works on both backends as Memory describes.

What its tools show. Every tool Muse Code runs has a named row, and the ones that answer in JSON are shown as what they mean:

  • Memory (Read memory, Save memory, Edit memory): the note saved or read back, where it lives (your memory for this project, the project's shared memory, or your memory for every project), and an edit as the text replaced beside its replacement.
  • Goals (Set goal, Check goal, Update goal, Goal progress): the objective, its status, a progress bar, what the agent is doing now and next, and the tokens spent against any budget.
  • Scheduled prompts (/loop and cron): each prompt with its schedule, whether it repeats, its next run and how often it has run. These rows report Muse Code's native cron tools, not the extension's Model API schedules described below.
  • Web search: the results as links that open in your browser, with their snippets. Search rows on the Model API backend look the same.
  • Background work: a command Muse Code moved to the background shows what it printed and that it is still running, and it stays running after the turn ends instead of reading "Interrupted". See Background work under The panel for moving one there yourself and stopping it.
  • Pictures: when the agent reads an image, or the Model API backend generates one, the row shows it; click it to open the file. Only images inside the workspace are shown. The preview reads the checked target with the same 10 MiB file cap if a workspace link or file changes meanwhile.
  • MCP tools read "tool (server)", and any tool the panel has no special view for shows its arguments and result as indented JSON.

Skills. The palette's Skills group has two more rows on the CLI backend:

  • Manage skills… is a checklist of every skill Muse Code knows (built-in, yours, this project's, plugins); unchecking one turns it off (muse skills disable).
  • Import skills… shows what muse skills import would copy from Claude Code or Codex into your Muse skills folder, imports it once you confirm, and reports what was imported, skipped, failed or quarantined.

Muse Code reads skill changes when it starts, so both end by offering to restart it; the conversation continues on your next message. Where the session offers Muse Code's resume-claude and resume-codex skills, the palette's Context group has Continue a Claude Code session and Continue a Codex session.

MCP servers and hooks. Muse Code reads both from its own settings file (~/.config/muse/settings.json, or under XDG_CONFIG_HOME), and project hooks from .muse/hooks.json. The extension shows them and never edits them:

  • MCP servers… lists each server:
    • Its transport, where it points (a URL is cut to its scheme and host), and whether Muse Code stops when it fails ("required") or skips it.
    • The names of its environment variables and headers. The values stay in the file.
    • A remote server can be signed in to or out of. That runs muse mcp login or muse mcp logout in a terminal, with the server's name quoted.
    • Restart Muse Code to load changes, since Muse Code reads the file when it starts.
  • Loud warnings for the two settings mistakes that make Muse Code load no server at all: both mcpServers and the older mcp_servers in one file, or required beside mode on a server.
  • On the Model API backend the window runs the same servers itself, so their tools work with your key as they do in Muse Code:
    • When: they start with the first conversation, and the first message waits for them; they stop with the window, and Restart the MCP servers in the view restarts them with the settings as they are then. At most four start together, so a long server list can make the first message wait longer. None runs in Restricted Mode.
    • The view shows each one's state: connected with how many tools, still starting, turned off, or not running and why. A server's row opens the log, where its stderr goes. The extension's own diagnostics server is listed as ide, built in.
    • Loud: a server that is not running is a warning in the panel, once per conversation; a required one (the default, unless its entry says "mode": "optional") stops the message with the reason and how to fix it, as Muse Code refuses to start without it. Both keys in one file, or required beside mode, loads none, as in Muse Code, and says so.
    • What an entry may hold: command, args, env, cwd and framing (auto, line_delimited_json, content_length) for a local server; url and headers for a remote one (streamable HTTP); enabled, mode, startup_timeout_sec, tool_timeout_sec, enabled_tools and disabled_tools for either. ${VAR} reads an environment variable of VS Code's; an unset one keeps the server from starting. A local server sees only a short list of VS Code's environment variables (PATH, HOME, TEMP and the like) plus its own env. On Windows a .cmd launcher such as npx runs through cmd.exe, and an argument with " or % is refused there. A hidden Windows job helper passes stdin, stdout and stderr as binary pipes, assigns the server to its job before it runs, after a private handshake confirms this extension process still owns the launch. It ends descendants on Stop, server exit or extension shutdown. If Windows cannot load the helper, local stdio servers do not start; the view gives the reason. Remote HTTP servers can still connect.
    • Sign-in: muse mcp login signs in Muse Code only. A remote server that needs a credential takes it in its entry's headers ("Authorization": "Bearer ${MY_TOKEN}").
    • Tools are named mcp__<server>__<tool> and read "tool (server)" in the transcript. Their results reach the model as text and pictures; audio and files are described instead. Resources, prompts and sampling are not supported.
  • Hooks… lists the project's, yours and your administrator's hooks, and opens the file behind each. A hook runs through your shell outside Muse Code's sandbox and approvals, so read a repository's hooks before you trust its folder.

On the Model API backend, museSpark.modelApiHooks is a machine-scoped setting, off by default. When enabled, a new session in a trusted workspace reads the same managed, user and project hook sources. No hook loads or runs while the folder is in Restricted Mode. The implementation currently fires SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure, PostToolBatch, PreLLMCall, PostLLMCall, PreCompact, PostCompact, SubagentStart, SubagentStop, Stop, StopFailure, SessionEnd and Notification; unsupported events and handlers are reported and skipped. Hook commands run as your user outside the agent's sandbox, with a narrow environment that excludes the Model API key. They get JSON on stdin, have a timeout and output cap, and may approve an ordinary tool call that would otherwise ask. Paid calls and protected writes still need your confirmation. A PreToolUse hook that asks forces a human card for memory reads or writes, including in Bypass and Edit automatically; Plan still refuses memory writes. Review each source with Muse Spark: Hooks in the Command Palette before enabling the setting. On the Model API backend, that picker shows the machine setting's on/off state and opens it. Turning the setting off stops hook dispatch in an open session; source file changes are read at the next session start. Model-call hooks receive bounded summaries without inline image bytes or the Model API key. A pre-call veto stops the request before it reaches Meta. A post-call veto stops returned tools and follow-up requests. An isolated Muse Code echo capture also ended the run as failed without another model request. Pasted media data URLs inside ordinary text are removed before any model-call hook preview is shortened; the original text still reaches the model. Tool hooks receive bounded previews of arguments and output, with media data URLs and credential-named fields omitted. MCP tools and the model still use the original arguments and results. A required MCP server failure ends the turn even if a post-tool hook asks to stop it.

Worktrees. New worktree… asks for a new branch and its base (the current commit or any local branch), creates it in a folder of its own, and offers to open it in a new window, so a conversation there leaves your checkout alone:

  • Where it goes: <repository>.worktrees/<branch>, beside the repository, so the second copy never lands inside your workspace. A / in the branch name becomes - in the folder's.
  • Refused: a name git rejects, a branch that already exists, and a folder that is already there.

Remove a worktree… lists the others (never the main checkout or the one this window is in) and deletes the chosen folder. Its branch stays. A worktree with uncommitted changes is removed only after a second confirmation that says the changes will be lost. Both commands need a trusted workspace, since git does not run in Restricted Mode.

Session goals

Give a conversation a goal and Muse keeps working toward it across turns, on both backends, as Muse Code's /goal does.

  • Set one with /goal <objective> in the prompt, or choose /goal in the / menu, which leaves /goal ready for the objective. When nothing is running, Muse starts on it at once; a reply that is running takes it up instead.
  • The goal strip above the task list shows the objective, its status (Active, Paused, Complete, Blocked, or a limit reached), a progress bar, and what the agent says it is doing now and next.
  • Its controls: Pause or Resume, Edit (the objective changes in place; a paused goal stays paused) and Clear. Typed, they are /goal pause, /goal resume, /goal edit <objective> and /goal clear. Stop pauses an active goal. A command that cannot apply (there is no goal, or the goal is finished) says why.
  • On Muse Code these are Muse Code's own goal verbs. Its goal loop also continues unfinished work on its own and checks the work before the goal closes; each of those is a model turn on your subscription. A resumed conversation shows its goal.
  • On the Model API the agent has the same four goal tools (Set goal, Check goal, Update goal, Goal progress, with Muse Code's rows), the goal is kept with the conversation, and it is pinned into every request while it is active. A turn starts only when you set, edit or resume a goal while nothing runs: the backend never continues on its own and runs no check of its own, so your key pays for nothing you did not ask for. A token budget the agent gives a goal stops it once spent.

Scheduled prompts (Model API)

On the Model API backend, /loop 10m Review the build saves a prompt in the current conversation to become due every ten minutes. Use m, h, or d for minutes, hours, or days; /loop "0 9 * * 1-5" Summarize new bugs uses a five-field cron expression in your machine's local time. /loop <prompt> defaults to ten minutes. /loop list refreshes the panel's schedule list, and /loop cancel <id> removes one. The list above the composer shows each prompt, cadence, next run or due state, run count, and ID, with Run now and Cancel schedule controls.

Each job belongs to this workspace, conversation, and stored Model API key. Signing out or switching backends hides its prompts immediately; a temporary CLI sign-in attempt leaves the still-active Model API list in place. It expires after seven days; /loop 7d ... has no run before that deadline and is refused. A due prompt stays pending until Run, Cancel or expiry. Only a loaded conversation checks for due work; closing VS Code stops checks. A missed recurring interval leaves one due occurrence, without a backlog. A due prompt never runs by itself: turn on Scheduled prompts (paid) and accept both published standard and contributor token rates, then choose Run now and allow that occurrence's prompt, model and exact tier rates in the paid-use popup (Allow once, Allow always in this workspace, or Deny). An unpriced model cannot be approved. Declining leaves it due until expiry and makes no API call. Bypass permissions does not skip either one; only Allow always in this workspace skips the per-run popup, and Run now is still yours to press. A changed model, prompt, conversation or paid setting refuses an old confirmation; the client checks the key it actually reads before HTTP. A receipt claimed just before such a change is never replayed, so that occurrence may be skipped without a charge. A run that reaches its first Model API request has a paid row in the transcript and a count in Account & usage; its token cost is already in that conversation's token estimate. A run admitted just before a crash is not replayed, even if its result was never seen. Cancel does not stop a turn that already began.

Muse Code has its own subscription-backed cron_create, cron_list and cron_delete tools. Ask it in chat to schedule, list or cancel its jobs; those are not the Model API jobs shown by this panel. Muse Code 1.3.0 does not expose scheduler controls over MSP or a muse cron CLI command, so the panel cannot present an authoritative native job list or direct cancel.

The panel

Composer.

  • Enter sends and Shift+Enter breaks a line (or send with Ctrl+Enter through a setting). The box grows with your draft up to ten rows, then scrolls inside.
  • While a turn runs, Enter steers it and Stop cancels it; Stop also drops messages still queued, which read "Not sent". A picked text file on Muse Code queues a new turn so its file annotation survives History resume.
  • The + button attaches images (PNG, JPEG, GIF, WebP), PDFs on the Model API backend, and UTF-8 text files up to 1 MiB from trusted, indexed workspace paths. Text files travel with their names as text on both backends. Files attached to Muse Code share its 10 MiB message limit; the composer counts their serialized content, including escaping, and refuses combinations that leave too little room for the prompt. Remove an attachment or shorten the message if that happens. Switching backends keeps visible chips; Muse Code checks them again before a send or steer and may require removal of an image attached under Model API. Model API text attachments share a separate 768 KiB allowance for their UTF-8 content and file-name wrappers. A large single file can be refused despite the 1 MiB per-file read cap; attach a shorter excerpt or remove another text attachment. A long conversation may still exceed the Model API context limit. Files outside that set become @ path mentions; known binary types and private files are refused. A PDF picked under a .png or .txt name follows its detected PDF header and 32 MB limit; Muse Code gives its PDF refusal. Ordinary unindexed text remains a path mention, and private filenames are refused before any PDF check. Images and PDFs also paste and drop. A dismissible banner gives the specific size, media, backend, text or private-file refusal; unknown file reasons keep generic unsupported-type guidance. Muse Code's MSP 1.3.0 cannot take a PDF part, so a PDF attachment there names the Model API backend instead. The Model API agent can read a workspace PDF or image through read_file; other workspace files use its existing UTF-8 text reader. Excluded text files share only a path mention, and the Model API reader confines paths to the workspace. Picker reads stop at the file's size cap even if it grows during the read. A native picker still open after New Conversation or sign-out cannot add an old file or mention to the new draft. Model API text, image and PDF reads use the checked canonical workspace target if a link changes after confinement. Host file I/O also rejects an observed change to that checked path when a parent directory becomes a junction after the first check; paid image output reservations recheck before fill and cleanup. Combined image and PDF data URLs are capped at 48 million encoded characters per message; an excess pasted or dropped attachment is refused before the browser reads and encodes it. Replayed requests use the same cap and keep newer media, announcing when older media is omitted from the request. Paste/drop checks the first 1 KiB of image-labelled files: a PDF named .png or .txt uses the 32 MB PDF limit and PDF media type, while a real image over 10 MiB is refused without encoding its full bytes. The check is discarded if the conversation changes before it finishes. Plain text clipboard content keeps its normal paste behavior; text-named files without clipboard text are probed and ignored when they are not PDFs. Private names are refused first. A PDF whose page tree cannot be counted without ambiguity reserves all 50 image slots, including when comments, escaped names or indirect /Count or /Type references obscure the real tree beside a visible decoy. The original attachments remain in local history. A batch of Model API read_file tool calls uses the same media cap; a file over that batch cap gets a failed tool result before its bytes are retained. PDF and image tool rows use the installed panel language and number format; the model receives its English result.
  • A path with a space, # or " is written in quotes, @"my notes/a b.md"#5-10, and the menu searches what you type after @".
  • The model pill reads model effort (effort tiers Minimal to Max, each verified per model); the mode button opens the Modes menu; the microphone dictates.
  • The context indicator is a button: click it to compact now; its tooltip carries the pressure level Muse reports.

/: the palette and the slash commands. A / on an empty prompt stays in the box and shows the palette above it; the / button opens the same palette with a filter box of its own. Its groups:

  • Context: attach, mention, clear, resume, new and remove worktree, and Continue a Claude Code or Codex session (CLI backend).
  • Model: switch model, effort (Left and Right step it), thinking.
  • Customize: permission mode, Focus view, Send with Ctrl+Enter, MCP servers, hooks, memory, settings, keybindings.
  • Account & usage (with the paid features' toggles where the backend can use them), Skills (the session's own, plus Manage and Import on the CLI backend), Slash commands and Support.

Type a letter after the / and the palette gives way to a flat list of slash commands narrowed as you type: /agents, /clear, /compact, /config, /cost, /export, /goal, /hooks, /logout, /mcp, /memory, /model, /permissions, /resume, /usage, /loop (Model API backend), and the session's skills. Names that start with your letters come first. Up and Down move, Enter runs a command (a skill, or /goal, is completed so you can add what follows it), Tab completes the name and Esc closes the list. With nothing matching, Enter sends the text as it is.

Transcript.

  • Replies render as GitHub-flavoured markdown with highlighted code and Copy, Insert at cursor and Apply on every block; a finished reply carries Copy on hover. A relative link in a reply (src/parser.ts#L12) opens that workspace file at those lines.
  • Tool rows show the diff or the command and its output from the start; read rows open on click, and a chevron marks the rows that open. Previews show 12 lines or 2,000 characters, with Show more. A backgrounded call carries a "background" badge.
  • The path of an edit or read row opens the file with the changed lines selected. Click a tool's output to open it in a read-only editor tab (a stored output in full, up to 16 MiB); Click to expand on an edit diff opens VS Code's diff editor (the file side is editable).
  • Thinking rows stream their summary while the model thinks and end as "Thought for Ns" (a resumed conversation's read "Thought").
  • A reply's ⋯ menu has Reply to this output: the next message carries that output to the agent as context. Highlight any text in the chat and right-click it for Copy, Ask about this or Comment on this; the passage, its author and your intent travel with the message. The composer shows a chip for either; × drops it.
  • Approval cards carry the CLI's own choices (Allow once, Always allow in this workspace or Allow for this session, Reject, with optional feedback); multi-step shell lines are approved one step at a time. Question cards stack radio buttons for one answer and checkboxes for several, put multiple questions on tabs, always offer Other, and keep Submit greyed until every question has an answer; Cancel declines the prompt, and Explain instead answers in your own words (up to 500 characters) rather than choosing, so the agent reads it and decides again.
  • The transcript follows new entries while you are at the end; scrolled up, it holds still and New messages jumps to the newest. The agent's task list pins above the composer, and the composer shows how much of the context window is used. Focus view (Ctrl+Alt+F) folds tool and reasoning rows behind Show N steps.

Edits and rewind. Muse applies in-workspace edits as it goes, so review comes after: the edit row shows the diff, its path opens the file at the change, and Click to expand opens the diff editor. To undo, use the rewind button on any sent message (on hover):

  • Fork conversation from here.
  • Rewind conversation to here starts a branch before that message and puts its prompt back in the composer. The original conversation stays in History. Images return when the backend still has their bytes; the panel warns if it cannot restore one. A Model API conversation cannot be rewound before its latest compaction. A rewind queued for a session the tab has since left is ignored. Messages steered into one turn use the last earlier turn as their branch point; if none exists, the conversation rewind choice is hidden. Wait for the selected turn to finish before rewinding its conversation. A just-sent Model API image can be restored before History is reopened. Conversation rewind is hidden for each PDF or named text file card because its bytes cannot be restored reliably on every backend and History path; an earlier text-only card in the same turn keeps its rewind choice. A request made outside the menu is checked against the served card and cut before the conversation changes.
  • Rewind code to here reverts every edit made after that message, the conversation's and its subagents', in the reverse of the order they landed. A file the edit created goes to the trash, unless you have added to it since, in which case your lines stay.
  • Fork conversation and rewind code.

Side chat. Use Side chat in the header to open a separate Plan-mode conversation with the completed turns as reference. Its inherited goal is cleared; the original tab keeps its session, goal and running turn. A delayed side-chat request is ignored if the original tab has since changed sessions. On the Model API backend, the side branch keeps Plan mode after reopen, suppresses local hooks and refuses external MCP tools, including ones their server labels read only. It also refuses scheduled prompt creation, cancellation and paid runs before any job claim or Model API request. Muse Code applies its own project and session rules in Plan mode; review those rules before treating that branch as read only. Close the side tab to return to the main one; its branch stays in History. It uses the selected backend's normal model allowance or key billing; it does not route Model API calls through a Muse subscription. In a side chat, Shift+Tab moves keyboard focus normally because its permission mode is fixed. A side panel's History shows only its own side branches; the same boundary applies when the window reloads.

Each edit is undone only where its own lines (the changed lines and the few around them) are still exactly as the edit left them. If you added or removed lines above them since, they are found where they moved to, as long as they appear in exactly one place. An edit whose lines you changed, or that could match more than one place, is left alone and says why, rather than guessed at; your other changes to the file are kept. A file's BOM and line breaks survive both.

Unsaved editors. Muse reads and edits the files on disk. With museSpark.autosave on (the default) every message saves your editors first; with it off the panel names the files whose unsaved changes Muse will not see. On the Model API backend the file tools also refuse a file an editor holds unsaved changes to, keep a file's BOM, line breaks and final line break, refuse files that are not UTF-8 text rather than rewrite them, and replace an existing file with write_file only after reading it (as Claude Code does). A linked path checks both its requested and canonical editor locations for unsaved changes.

History. The clock icon lists the workspace's conversations by day with search, resume (full transcript), archive and Show archived. Archive with the row's × or, while the search box is empty, Delete on the highlighted row, which also restores an archived one. Sessions idle for archiveInactiveSessions days are hidden, not deleted. Click the header's title to rename the conversation. A hidden panel shows a dot when Muse finished or needs a decision.

Export. /export (or Muse Spark: Export Conversation) saves the conversation as Markdown where you choose: messages, thinking, and tool calls with their arguments and visible output. Your ! commands include an exit code or termination signal when Muse Code reports one. On the CLI backend Export session log… also saves Muse Code's own JSON record of the session (muse export), which includes everything, stored outputs too; it needs a folder on this machine. An export asked for while a reply runs is refused until it finishes, and a conversation too long for Muse Code to replay is pointed to the session log.

Your own shell commands. Start a message with ! to run it as a shell command in the workspace instead of sending it to the agent, as Muse Code's ! does: !git status. The prompt switches to the editor's font and says Shell; the command runs at once, outside any turn (also while a reply runs), and gets its own row: You ran with the command, its exit code and run time, and what it printed, which opens whole in an editor tab. The agent sees the command and its output with your next message. No approval card asks first, since you typed it, whatever the permission mode; nothing runs while the workspace is in Restricted Mode, and a command that could not run comes back to the prompt with the reason. On Muse Code it runs through the CLI's own shell and sandbox (a missing Windows sandbox offers the setup, as the shell tool does); on the Model API backend it runs through the shell tool's runner, for ten minutes at most, and its row has a Stop. While a Model API command is still running, another surface sharing that session shows its row and can stop it. A session loaded in another VS Code window shows the saved row as interrupted, since that window cannot control the original runner.

Background work. A shell command the agent is waiting on can go on in the background while the agent carries on: Move to background on its row, or Ctrl+B (also on a Mac) while the conversation in view runs one; VS Code's own Ctrl+B (the sidebar) works as usual otherwise, including while a shell permission card waits for your answer. A background command keeps running after its turn ends, marked "background", with Stop on its row; the header pill counts the ones still running, and the Agent map lists every background task with its own Stop and a Stop all (also Muse Spark: Stop Background Tasks). On Muse Code these are the CLI's own task/background, task/stop and task/stopAll, and Muse Code tells the agent what the command printed when it ends. On the Model API backend the agent is answered at once that the command moved; it then runs without its time limit until it ends or you stop it, and what it printed reaches the agent with its next request (no model call is made for it on its own). When the last surface leaves a conversation, its remaining background commands are stopped; another open surface keeps them running. A resumed conversation restores Ctrl+B for a shell command still in the foreground. A second surface sharing a live Model API session also shows its running foreground command and can move it with Ctrl+B. If that shell is still awaiting permission, the second surface shows the same card and leaves Ctrl+B to VS Code until approval resolves. A fork has no running commands from its source; it carries the ending or lost-output context into the agent's next request for any inherited task.

Subagents. When either backend spawns subagents they appear as rows and an N agents pill in the header opens the Agent map (also /agents): this conversation, its agents with role, objective, status, duration and tokens, the background tasks, and each agent's own transcript.

  • Muse Code hides its subagent tools unless run.subagent_delegation_mode is "auto" in its settings file (~/.config/muse/settings.json, or under $XDG_CONFIG_HOME). The map says so and opens the file for you; the extension never edits it.
  • Muse Code gates subagent_spawn behind an approval: in Manual mode the card appears (Allow once / Allow for this session); Plan mode refuses it.
  • An agent's own replies and tool calls stay in its transcript in the map, and the map's details offer the controls Muse Code provides: Interrupt and Stop while it runs, a note to it, Resume, Close, and a follow-up task once its result is ready. A ready result can be marked read; a closed agent can be reopened on the Model API backend. Muse Code's Reopen and Mark result read controls wait for a live capture of their accepted MSP commands; its captured Interrupt, Stop, Resume and Close controls remain available.
  • On the Model API backend, the agent can spawn up to eight child sessions at once; more wait in order, up to 64 per conversation. A child has its own conversation and the same workspace tools and approvals, but cannot spawn again or ask you a question. Children share the workspace and use your Model API key; their tokens count in the conversation's usage. Paid subagents are off by default. Enabling them accepts the published model rates; each new child task then asks again before it starts, including in Bypass mode. Plan refuses the task. One approval allows at most four actual response requests, including retries and tool rounds. A running note uses that same allowance; a follow-up or reopen needs a new approval. This is a request limit, not a dollar limit. Failed requests without a usage report appear as unknown cost in Account & usage. A resumed child whose queued notes survived a window restart shows those notes in its fresh approval before they run. Stopping a queued child drops its unsent notes; reopening it starts from its retained objective without those canceled notes. A second panel joining during a child's pending tool approval sees the same card. Child tokens spent on an active goal count against that goal's budget; a replacement goal does not inherit an earlier child's cost.

Workflows. Muse Code can run a multi-agent workflow: a short script, written by the model for the task or saved in Muse Code beforehand, that starts child agents, up to 1,000 over a run, each making its own model calls on your subscription. The Workflow row shows the inline script when the model wrote one and says whether the run was launched. It does not infer a source file for a resumed run; that input shape has not been captured from Muse Code. The run itself is a card below it that keeps changing after the reply ends, as the run goes on in the background:

  • its captured generated label ("Written for this task"), or the entry ID or fallback text Muse Code sent for another run, plus its status, how many agents, their tokens, and what started it;
  • each agent with its label, state (queued, running, completed, failed…), attempt, time and tokens;
  • a status Muse Code adds later shown in its own words with a neutral mark;
  • the result the run returned, or the failure it reported;
  • The run and its agents are read-only in this version. Cancel, Skip and Retry will need a live capture of accepted Muse Code commands before the panel can offer them.

The token figure is the panel's sum of the latest usage reported for each agent row. It is not a billed total for a run with retries; use Muse Code's subscription usage for that. A reload of the same session keeps child labels and usage the panel saved earlier; without that saved state, Muse Code's final history item may omit those details.

The header's N agents pill counts workflow agents too, and the Agent map lists the runs with the same read-only cards. The map also says how Muse Code is set to start workflows, from run.workflow_trigger_mode in its settings file (auto, its default: the model may start one for large work, and starts one when you ask; explicit: only when you ask; off: no workflow tool), with the file a click away; the extension never edits it. Pausing and resuming a run are Muse Code's terminal UI's alone (/workflows), and a workflow agent keeps no transcript of its own to open. The Model API backend runs no workflows.

Account & usage (/usage, /cost) is a modal over the transcript:

  • Account: auth method, plan, backend, Muse Code version and model.
  • Usage (Muse Code): the subscription's current window and week. Muse Code reports them only after a reply. The modal reads the latest report from the signed-in CLI when opened; it does not use an account-agnostic snapshot after a host restart or sign-out. Countdowns update each minute while the modal is open. Once a reported reset has passed, that row waits for a fresh Muse Code report instead of showing an expired percentage or reset countdown. Each observation is dated "as of". The numbers are the CLI's account-level percentages and reset times: changing the selected model does not create a separate local quota or reset calculation, and an opaque plan ID is shown as "Muse Code subscription". Personal Muse Power/Maximum plan grants are separate from this CLI usage report.
  • This conversation: token totals (on Muse Code, prompt tokens as it counts them once). On the Model API also the cached tokens, the cache-hit rate and a dollar estimate from Meta's published per-token prices (standard versus contributor tier, read 2026-09-26; the dev.meta.ai dashboard is the bill).
  • What's contributing to your usage, over the last day or week, read from the Muse Code CLI's trace logs on this machine: the share of model attempts from Muse's reminder agents (which run after every reply), from subagents, and from sessions active for 8+ hours. Approximate, this machine only.

Prompt caching. The Model API backend sends a stable key for requests that share a model, instructions and tools, so repeated prefixes can be billed at the cached rate; the CLI caches on its own. The retention setting asks Meta for its shorter in-memory default, or up to 24 hours when you choose that machine-scoped setting. Either is a hint rather than a guaranteed lifetime. The modal shows the cache-hit rate instead of a "warm for N minutes" countdown.

Diagnostics. The agent can read the Problems panel through a getDiagnostics tool. On the CLI backend the extension serves it on a loopback MCP server, bound to 127.0.0.1 with a per-window token and started when a session first needs it; nothing else is exposed. On the Model API backend it runs inside the extension under the same name (mcp__ide__getDiagnostics), as a read in every mode. It reports the workspace's files only (the first folder), by relative path, each message cut at 1,000 characters, and past 200 problems a count instead of the rest.

Accessibility. Every screen the panel shows is checked against WCAG 2.2 AA's automated rules in Light Modern, Dark Modern and both High Contrast themes on every change.

  • Menus and lists work from the keyboard: the palette and History lists are Tab stops, the effort row moves with Left and Right, History rows archive with Delete, and Esc closes whatever is open.
  • Screen readers hear when Muse finishes, fails or is stopped, when an approval or a question arrives, when a tool fails, and when dictation starts and stops.
  • The operating system's "reduce motion" setting stops every animation.
  • Text in right-to-left scripts reads right to left, and with an input method Enter commits the candidate instead of sending.

Voice dictation

Tap the microphone to start and again to stop; hold it (or Ctrl+D / Cmd+D in the composer, or Space on the focused button) to record while held. The placeholder reads "Listening…", the mic pulses red, and each phrase lands at the caret followed by a space. Recognition runs in a small helper on the operating system's own engine, kept warm for five minutes after a recording. Nothing is billed and no third-party engine is involved, unless you turn on Muse Voice, the paid engine on a Model API key.

Dictation is off in a remote window (SSH, WSL, containers, tunnels, Codespaces): the extension runs on the remote machine, which cannot hear your microphone.

Platform How
Windows native/windows/dictate.ps1 under Windows PowerShell 5.1 on the .NET Framework's System.Speech, the desktop recogniser that ships with Windows (English always; other languages with Windows speech packs). Audio never leaves the machine. Accuracy is the classic engine's, below Windows 11's voice typing; Windows' Speech Recognition training improves it for your voice.
macOS native/darwin/muse-dictate, a Swift helper on Apple's Speech framework, built by CI on a Mac and shipped in the Marketplace package. Dictation (System Settings > Keyboard) or Siri must be on. Apple picks on-device recognition when its model is installed, otherwise its servers under Apple's terms at no charge (--on-device refuses the servers). See the macOS notes below the table.
Linux Not available for free: no distribution ships a speech recogniser and the extension adds none. The button is dimmed with that reason as its tooltip. With Muse Voice on, the system's arecord or parec records and Meta transcribes.

On macOS, two things can stop the helper, and the panel's error says which:

  • A permission. The first time you dictate, macOS asks for speech recognition and the microphone on behalf of the helper itself, muse-dictate, with its own usage descriptions, rather than for Visual Studio Code; the grants are managed under System Settings > Privacy & Security > Speech Recognition and > Microphone. The helper asks under its own name because Visual Studio Code, which starts it, declares no speech-recognition purpose (microsoft/vscode#307364), and macOS would refuse VS Code without asking; to do so it disclaims VS Code's responsibility with a private macOS call (the one Chromium, Qt and Electron use), and where that call is missing it asks as VS Code and the panel's error explains the refusal. The helper is ad-hoc signed, so macOS ties the grant to the build: after an update that changes the helper, macOS asks again.
  • The helper itself. The helper is ad-hoc signed, not notarised; VS Code's installer does not quarantine it, so Gatekeeper does not stop it. If the error names no permission step, macOS refused to run the helper: its file carries the quarantine flag, which a copy through a browser download or an archive tool can add. This clears it:
xattr -d com.apple.quarantine ~/.vscode/extensions/randynorthrup.muse-spark-code-*/native/darwin/muse-dictate

Diagnosing on Windows: the helper can replay a WAV file instead of the microphone, which separates a recogniser problem from a microphone one.

& "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -File native\windows\dictate.ps1 -InputWav C:\path\to\speech.wav

Type start and press Enter; phrases print as JSON lines, then stopped. Muse Voice's recorder takes the same -InputWav (a 16 kHz, 16-bit mono file) and prints the audio as audio lines instead: native\windows\capture.ps1 -InputWav …. On macOS the helper takes --input-device <CoreAudio UID> to capture from one specific device; a Mac without any input device reports "no audio input device is available", and step markers on stderr name where a start failed.

Paid features

Five settings gate what costs money on your Model API key beyond an ordinary chat turn. They are always billed to your Model API key, never to your Muse Code subscription, and all five are off until you turn them on. All five work on the Model API backend; images and Muse Voice also work on the Muse Code backend while a key is stored (web search is Muse Code's own there, on the subscription):

Feature Price (Meta, read 2026-09-24) What it does
Web search $2.50 per 1,000 searches The model may search the web while it answers; the reply lists the pages it cites
Image generation $0.01 per image The model may create a PNG file in the workspace with muse-image-1.0, or edit workspace images into a new one, asking you each time
Muse Voice $0.18 per hour of audio The microphone uses Meta's Muse Voice Transcribe instead of your computer's own recogniser
Subagents Selected model's published input, cached input and output token rates Child tasks on the Model API backend; every task asks again and admits at most four response requests
Scheduled prompts Selected model's published input, cached input and output token rates A due /loop prompt runs only after you choose Run now and allow that run's model and rates

Scheduled prompts use ordinary Model API tokens, rather than an extra per-run service fee. The off-by-default paid gate names both standard ($1.25/$0.15/$4.25) and contributor ($0.10/$0.002/$0.20) rates per million input/cached/output tokens. Each due run names only its selected model's exact tier before any model call; an unpriced model cannot be approved. Other paid tools you have enabled may add their own charges during that confirmed turn.

Turn one on from the palette (Account & usage group, where the backend can use it) or with its setting (museSpark.modelApiWebSearch, modelApiImageGeneration, modelApiVoice, modelApiSubagents, modelApiScheduledPrompts). Either way a confirmation names the price first; declining it turns the setting back off, and turning a setting off means the next time asks again. The settings are machine-scoped, so a repository cannot turn one on.

Every paid use then asks first, in a popup, in every permission mode, Bypass included. The popup names what is about to be billed and its price, and offers three answers:

  • Allow once: this use only.
  • Allow always in this workspace: this use, and every later use of the same feature in this workspace, without asking. Offered only in a trusted workspace with a folder open. It lapses in every workspace when you turn the feature off (or accept a new price), and Ask again every time in Account & usage takes it back.
  • Deny (or closing the popup): nothing is billed.

What asks, and when:

  • Web search: once per prompt, before its first request, because Meta runs the searches inside the response and the model decides whether to search at all. Deny sends that prompt without web search. A child task searches only if its parent's prompt was allowed to.
  • Images: before every image, with its path, prompt, the images an edit starts from, and the price. Plan refuses it (it writes a file), and a path that is taken, outside the workspace, or not a .png, or a source that is missing, outside the workspace, not a PNG, JPEG or WebP image, or over 10 MB, is refused before anything is asked or billed. Edit sources are read from their checked canonical workspace targets, even if a link changes after the check. An image written to a protected path (D24) asks even when images are allowed always.
  • Muse Voice: before each recording.
  • Subagents: before every new child task, with its objective, model, published rates and four-request ceiling; Plan refuses it. Retries count; a running note spends the same grant.
  • Scheduled prompts: before each run, with its prompt, model and rates.

While one is on, you can always tell, even when it no longer asks:

  • The composer's badge names every paid feature that is on ("Paid: Web search, Images"), with the prices in its tooltip and the features allowed always in this workspace; it opens Account & usage.
  • Every use is its own row marked paid: each search, with its query and results; each image, with its path; each child task; and each admitted scheduled run. The child estimate in Account & usage is part of the conversation's total, not an extra charge added to it.
  • On the Muse Code backend, images come from the extension itself: its ide tool server, which every Muse Code session loads, offers Muse Code an image and an image-edit tool while image generation is on and a key is stored. Muse Code's own permission mode decides whether it may use the tool; then the same popup asks before the image is bought, billed to your key and not to the subscription. The key never leaves the extension, and the row is marked paid as on the Model API.
  • The microphone says so: ringed, and named "Record voice with Muse Voice (paid)" with the price in its tooltip.
  • Account & usage keeps the tally and names each feature allowed always in this workspace: this window's searches, images, seconds of audio, child request attempts and scheduled runs, with estimated cost when usage was reported. An attempt with no usage report has unknown cost. Scheduled-run tokens are included in the session token estimate rather than added to the extra-features total. The dev.meta.ai dashboard is the bill.

Web search's count errs high: Meta does not say how it bills a search with several queries, so each query counts. Muse Voice counts the whole seconds sent, as Meta bills them.

A paid Web search row with its query, the reply with its Sources list, and the composer's badge: Paid: Web search, Images
A search marked paid, the reply's sources, and the badge
Account and usage, Paid features in this window: Web search (on, allowed always in this workspace) 3 searches, Images (on) 1 image, the estimated total, and the note Allowed always in this workspace, without asking: Web search, with an Ask again every time button
What no longer asks in this workspace, and Ask again

Muse Voice records the same way as free dictation (tap or hold), and the transcript lands at the caret when you stop. The recording is made by a helper that only records: native/windows/capture.ps1 on Windows (the waveIn API that ships with Windows), the macOS helper's capture mode (which asks for the microphone only), and on Linux the system's arecord or parec, so Linux gets a microphone on this engine. Audio leaves the machine only while it records, and only to Meta.

Languages

The panel, its notices, the Command Palette's commands and the settings follow VS Code's display language:

  • Simplified and Traditional Chinese
  • Japanese and Korean
  • German, French, Spanish, Italian and Brazilian Portuguese
  • Russian, Polish, Czech, Hungarian and Turkish

Any other display language gets English. Change it with Configure Display Language in the Command Palette and reload the window.

The Account and usage modal in German: Konto und Nutzung, Anmeldemethode, Tarif, the current window at 42 % verbraucht, this conversation's Eingabe 20,8K, and what is contributing to the usage
Account & usage in German, with its numbers written the German way

The translations are machine-made, by the same AI that wrote the code, and checked by a gate rather than by native speakers. That gate checks that every string is present, every value and code span is kept, and every count uses the language's own plural forms. If a translation reads wrong, open an issue naming the language and the text; a correction is one line in l10n/ui.<language>.json or package.nls.<language>.json.

What stays in English:

  • Text sent to the model: the context notes, the compaction prompt and the tool errors. The model behaves the same in every language.
  • What Muse and the tools write: replies, tool output, and Muse Code's own approval choices.
  • The walkthrough's pages: VS Code translates the step titles, not the pages.
  • Log lines no one sees in the panel, and the names of commands, files and settings.

Limits

What Limit
Images and PDFs 20 attachments per message together; images 10 MiB each (PDFs: next row)
PDFs on the Model API backend 32 MB each locally (Meta allows 50 MB per inline file); images and PDF page images together: 50 per message. Meta reads text from the first 100 pages and page images from the first 50.
Model API encoded media 48 million data URL characters total per new message and replay request; older replayed media is named but omitted when over the cap.
Picked UTF-8 text attachments 1 MiB per-file read cap from trusted and indexed workspace paths; Model API also caps combined text and file-name wrappers at 768 KiB to leave context room.
A message to Muse Code 10 MiB. Attachment admission reserves 2 MiB for the prompt, context and frame; serialized text and base64 images count toward the rest. The exact outbound frame is checked at send.
Model API: tool rounds 50 per turn
Model API: shell commands 2 minutes by default, 10 at most
Model API: retries Up to 5 attempts on 429, 500, 502 and 503, and when a reply stream ends because the server shut down or was overloaded, honouring Retry-After, shown in the transcript; Stop cuts the wait short
Model API: a silent reply stream Ended after 5 minutes with nothing from the server; send again to retry
Model API: file tools Text and images up to 10 MiB, PDFs up to 32 MB; the search tool skips files over 1 MiB
Opened tool outputs 16 MiB each; the latest 20, and 32 million characters together

Commands and keybindings

Command Default keybinding What it does
Muse Spark: Open in Sidebar — Focus the chat view in the activity bar
Muse Spark: New Conversation Ctrl+N (Cmd+N) when enableNewConversationShortcut is on, Muse focused Clear the active panel to a new conversation, or open one where preferredLocation says
Muse Spark: Sign Out — Forget the stored Model API key and sign the CLI out when it is signed in (its account/logout, else muse logout)
Muse Spark: Open in Terminal — Run the Muse Code CLI's own interactive interface in a VS Code terminal at the workspace root
Muse Spark: Create AGENTS.md — Write the rules file with muse init (or the same template without the CLI) and open it; an existing file is opened
Muse Spark: Open Walkthrough — Open the four-step Get Started walkthrough
Muse Spark: Open in New Tab Ctrl+Shift+Alt+Esc on Windows, Cmd+Shift+Esc on macOS, Ctrl+Shift+Esc on Linux Open an independent conversation as an editor tab (also the + in the view title); the panel header's own button starts a new conversation in place
Muse Spark: Toggle Focus Ctrl+Alt+Esc on Windows, Cmd+Esc on macOS, Ctrl+Esc on Linux Move keyboard focus between the editor and the composer
Muse Spark: Insert @-Mention for Selection Alt+K, editor focused Insert @path#start-end for the active editor selection into the composer
Muse Spark: Toggle Focus View Ctrl+Alt+F, Muse focused Flip the museSpark.focusView setting (hides tool calls and reasoning)
Muse Spark: Toggle Thinking Ctrl+Alt+T (macOS Option+T, Linux Ctrl+Alt+O), composer only Turn reasoning on or off for this conversation. Claude Code uses Alt+T; on Windows that opens the Terminal menu, on GNOME Ctrl+Alt+T opens a terminal
Muse Spark: Set Up Shell Sandbox — Windows: run Muse Code's one-time muse sandbox windows setup through a UAC prompt and report the result; elsewhere reports that no setup is needed
Muse Spark: Show Logs — Open the "Muse Spark" log channel (keys redacted)
Muse Spark: Diagnostics — Write the versions, the backend and CLI facts, credential facts, never a value, the dictation state, the network posture and muse config status to the log and open it: what a bug report needs
Muse Spark: Manage Skills — Turn Muse Code's skills on or off (muse skills enable/disable), then offer to restart it so the change takes effect
Muse Spark: Import Skills from Claude Code or Codex — Preview what muse skills import would copy, import it once you confirm, report what was imported, skipped or failed
Muse Spark: Export Conversation — Save the conversation in front of you as Markdown where you choose, and open it
Muse Spark: MCP Servers — Show the MCP servers Muse Code will load (on the Model API backend, how each is running), sign in to or out of a remote one, open the settings file
Muse Spark: Hooks — Show where Muse Code's hooks come from (project, yours, managed) and open each file; on the Model API backend also whether modelApiHooks is on, with a link to it
Muse Spark: Memory — List Muse Code's memory notes for this workspace, open one to edit, create one, or delete one to the trash, keeping each MEMORY.md index in step
Muse Spark: New Worktree… — Ask for a new branch and its base, create it in its own folder beside the repository, then offer to open it in a new window
Muse Spark: Remove Worktree… — Delete another worktree's folder (its branch stays), asking again before discarding uncommitted changes
Muse Spark: Move Running Command to Background Ctrl+B (also on macOS), while the conversation in view runs a shell command Let the running shell commands go on in the background while the agent carries on; VS Code keeps Ctrl+B otherwise
Muse Spark: Stop Background Tasks — Stop every background task of the conversation in view
(composer) Record voice Ctrl+D (Cmd+D), composer only Tap to start or stop voice dictation, hold to record while held
(composer) Run a shell command Start the message with ! Run it in the workspace as you, outside any turn; the agent sees it with your next message

Windows keeps Ctrl+Esc for Start and Ctrl+Shift+Esc for Task Manager, which is why its two shortcuts add Alt. Nine commands appear in the Command Palette only where they can act: Insert @-Mention with an editor open, Toggle Thinking, Export Conversation and Stop Background Tasks with a Muse panel in view, Move Running Command to Background while one runs, Set Up Shell Sandbox on Windows (or in a remote window), Create AGENTS.md and the two worktree commands with a folder open.

Settings

All settings live under museSpark.*; changes apply to open panels immediately. The settings that choose what runs and what is billed (initialPermissionMode, backend, shellSandbox, sandboxNetwork, allowDangerouslySkipPermissions, museBinaryPath, environmentVariables, modelApiHooks, modelApiPromptCacheRetention and the five paid features, modelApiWebSearch, modelApiImageGeneration, modelApiVoice, modelApiSubagents and modelApiScheduledPrompts) are machine-scoped: they take effect from your user settings only, never from a repository's .vscode/settings.json. In a remote window (SSH, WSL, a dev container) machine settings live on the remote side, where a dev container definition can set them; there the extension never starts a conversation in Bypass permissions and asks you once before entering it. Turning allowDangerouslySkipPermissions off moves every open conversation out of Bypass at once.

Setting Default Purpose
preferredLocation panel Where new conversations open: sidebar or panel (editor tab)
initialPermissionMode manual manual, acceptEdits, plan, auto or bypassPermissions for new conversations; bypassPermissions applies only while allowDangerouslySkipPermissions is on, otherwise the conversation starts in manual
autosave true Save all dirty editors before every turn
attachOpenFile true Show the open-file chip and send the active file / selection with each message
useCtrlEnterToSend false Send with Ctrl/Cmd+Enter instead of Enter
enableNewConversationShortcut false Ctrl+N / Cmd+N starts a new conversation while a Muse panel is focused
hideOnboarding false Hide the getting-started tips
focusView false Show only prompts and responses
respectGitIgnore true Exclude .gitignore patterns from file searches and @-mentions
confidentialWorkspace false Block contributor-tier models (Meta may train on their traffic) in this workspace
allowDangerouslySkipPermissions false List Bypass permissions in the Modes menu and the Shift+Tab cycle (sandboxes only)
archiveInactiveSessions 14 Hide sessions idle for this many days from the History dialog (1, 2, 7, 14, or 0 for never); they stay on disk and Show archived lists them
cleanupPeriodDays 30 Delete Model API conversations idle for more than this many days when a window lists them (0 keeps them); Muse Code's own sessions are the CLI's to keep
backend auto auto: Muse Code when the CLI is signed in, else the Model API when a key is stored; museCode / modelApi force one. The pasted key never reaches the CLI. Changing it restarts the host
shellSandbox auto auto: Muse Code's OS sandbox, except for Windows workspaces under your profile where it cannot run commands; muse: always the sandbox; off: commands run directly as you, gated by approvals (Claude Code style). Without the sandbox Muse Code's file tools may also write outside the workspace. Changing it restarts the host
sandboxNetwork default The network Muse Code's shell sandbox gives commands: proxy-only asks before each new destination, restricted allows none, enabled allows all; default passes nothing, leaving Muse Code's own default (proxy-only) or your administrator's managed configuration. Applies while the sandbox is on. Changing it restarts the host
museBinaryPath "" Absolute path to the Muse Code executable (a relative one is refused); empty discovers it on PATH or the install dir. Changing it restarts the host
modelApiWebSearch false Paid: web search on the Model API backend, $2.50 per 1,000 searches; asks you to confirm the price when turned on, then asks before each prompt that may search
modelApiImageGeneration false Paid: the model creates PNG files in the workspace or edits workspace images into new ones, $0.01 per image, on the Model API backend and on Muse Code while a key is stored (billed to the key); every image asks first, in every mode, unless allowed always in this workspace
modelApiVoice false Paid: Muse Voice as the microphone's engine, $0.18 per hour of audio, on the Model API backend and on Muse Code while a key is stored; each recording asks first
modelApiPromptCacheRetention in_memory How long Meta is asked to keep the cached start of Model API requests: in_memory by default, or up to 24h when you choose it. Both have the same cached-input price; longer retention may improve cache hits after a pause. Meta may evict sooner. Machine-scoped, so a repository cannot extend it
modelApiSubagents false Paid: Model API child tasks, with a model-rate confirmation and a fresh four-request popup for every task
modelApiScheduledPrompts false Paid: a due prompt can run only after this machine-scoped gate and a separate confirmation of that occurrence's Model API token rates; never unattended
modelApiHooks false Run Muse Code's hook commands on the Model API backend in a trusted workspace: your administrator's, yours and the project's. They run as you, outside the agent's sandbox, without the Model API key; review them with Muse Spark: Hooks first. Machine-scoped
environmentVariables [] { name, value } pairs for the Muse Code process and the terminals that run the CLI (Open in Terminal, MCP sign-in, muse logout); an XDG_CONFIG_HOME here is where the extension looks for the CLI's sign-in and settings too. Never put API keys here; use Sign in. Changing it restarts the host

The Model API backend's shell tool applies terminal.integrated.env.* the way VS Code's terminal does. A restart of Muse Code, for a setting, trust granted, a sign-in or a crash, keeps the conversation: the running turn is stopped and the next message resumes the same session.

Proxies and certificates

  • The extension's own requests (the Model API, the paid features, Muse Voice's socket) go through VS Code's network support, as every extension's fetch and WebSocket do from VS Code 1.125: http.proxy, or the system's proxy settings or PAC file; proxy authentication as VS Code handles it (Basic and Kerberos); http.noProxy; and the operating system's certificate store while http.systemCertificates is on. http.proxySupport, http.fetchAdditionalSupport and http.webSocketAdditionalSupport must stay on (their defaults) for that. A network that inspects HTTPS needs its root in the system store. Naming the root's file in NODE_EXTRA_CA_CERTS before VS Code starts works only with http.systemCertificates off: in the M56 drill the variable did not help while that setting was on (its default).
  • Muse Code reads proxy variables from its environment (HTTPS_PROXY, HTTP_PROXY, ALL_PROXY, NO_PROXY). The extension hands it VS Code's http.proxy (and http.noProxy) when neither its environment nor environmentVariables sets one, in either case; a proxy VS Code finds in the system settings or a PAC file does not reach it, so set http.proxy or HTTPS_PROXY in environmentVariables; keep proxy credentials out of shared workspace settings. If http.proxy or http.noProxy has the wrong type, the extension ignores that value for Muse Code instead of passing it into the CLI's environment; correct the VS Code setting to restore it. Loopback bypasses an environment proxy, so Muse Code reaches the extension's ide tools. Muse Code also has its own endpoint_transport.proxy setting, which this extension does not manage. Muse Code 1.3.0 trusts the operating system's certificate store; SSL_CERT_FILE or SSL_CERT_DIR replace that store for it entirely, so a file named there must hold every root it needs.
  • Muse Spark: Diagnostics reports which of these are set (never a proxy's address) and known-safe source and generation fields from Muse Code's managed configuration (muse config status). Unrecognized lines and failed-command output stay out of the public-issue report.

Requirements

  • VS Code 1.125.0 or newer, on Windows, macOS or Linux.
  • The Muse Code CLI signed in with a Meta account (subscription), or a Meta Model API key (pay as you go).
  • git on PATH for .gitignore-aware @ mentions, worktrees and the Model API prompt's git facts (optional; VS Code's file search is used without it). The extension runs git only in a trusted workspace and only from an absolute PATH entry, never a copy inside the workspace.
  • Voice dictation: Windows, or macOS with Dictation or Siri enabled, in a local window.
  • A trusted workspace for rules, skills, memory, MCP servers, hooks and shell commands; in Restricted Mode the panel chats and edits under approval, nothing more. The first workspace folder is the root: the open-file chip, @ mentions, drops, the Problems panel the agent reads and relative file links all belong to it (a folder added inside it counts as part of it); a file in another folder is mentioned by its absolute path. Virtual workspaces are not supported.

Privacy and security

  • Your prompts, attachments, mentioned files and tool output go to Meta only when you press Send. The exceptions are ones you set up: on the Model API backend an MCP server you configured receives its tool calls' arguments, and with museSpark.modelApiHooks on your hook commands receive your prompt and bounded previews of tool and model calls. By default each message also carries the open file's path and any selected text (attachOpenFile); on the CLI backend each turn carries a short hidden note asking the model to offer choices through the question card. The extension has no telemetry and no hosted server of its own. Details: PRIVACY.md.
  • A pasted Model API key lives only in VS Code's SecretStorage, is sent only to api.meta.ai, is never passed to any child process, and never reaches settings, logs or the CLI.
  • Contributor-tier models (Meta may train on their traffic) are opt-in with one confirmation per conversation, and refused outright with museSpark.confidentialWorkspace. Resuming a contributor-tier conversation asks again, or in a confidential workspace moves it to a standard model.
  • Voice audio stays on the machine on Windows; on macOS Apple recognises on the device or on its servers under Apple's terms. With Muse Voice on (paid, off by default), the recording goes to Meta's Muse Voice Transcribe while you record, and nowhere else.
  • The paid features (web search, image generation, Muse Voice, Model API subagents and scheduled prompts) are off until you turn one on and accept its price; a repository's settings cannot turn one on.
  • Model API conversations are stored, per workspace, in VS Code's storage directory for the extension (not in the repository); ones idle longer than museSpark.cleanupPeriodDays (30 days by default) are deleted, and removing that directory deletes them all. The History dialog archives, it does not delete.
  • The log records what happened (sessions, turns and their times, approvals, failures) and never your prompts, files, dictated words or the model's output; keys are redacted.
  • The usage insights read the Muse Code CLI's trace logs on this machine and send nothing anywhere.
  • On the Model API backend Meta caches the start of each request to answer the next one faster and cheaper; the extension asks for the shorter in_memory retention by default. Only your machine-scoped museSpark.modelApiPromptCacheRetention setting can request up to 24 hours; a repository cannot extend your choice. The cache key is a digest of the model, instructions and tools it starts with, not a session or user id.
  • Behind a corporate network the extension's requests use VS Code's proxy and certificate settings, and Muse Code gets the proxy and certificate variables described under Proxies and certificates.
  • Workspace rules, skill files and the memory snapshot are read only in a trusted workspace; on the Model API backend their text is part of what goes to Meta with each request, on the CLI backend Muse Code sends them under its own terms. The memory snapshot is each scope's MEMORY.md and its notes' names, your personal scopes included; a note's text goes only when the model reads it.
  • The Model API backend's file tools resolve every path through the file system before touching it: a path that leaves the workspace, directly or through a link, is refused, and Windows names that would be reinterpreted (alternate data streams, device names, trailing dots) are refused too. Text reads and writes use the checked canonical target if a workspace link changes between the check and the operation. Paid image output is reserved at that same checked target before the API request. Its shell tool starts PowerShell or bash by absolute path with the environment VS Code's own terminal would give (the editor's internal variables removed). Stop and a timeout end everything a command started: its process group on macOS and Linux; on Windows the job object each command runs in, through a small helper the extension compiles once into its own storage with PowerShell's Add-Type (where policy forbids that, the log says so and a sweep of the process table stands in).
  • The webview runs under a strict CSP (default-src 'none', per-load script nonce, no remote origins, no inline styles); every message between host and webview is validated with a zod schema.

Troubleshooting

  • What happened, in order — Muse Spark: Show Logs opens the log.
    • What it records: every failure the panel or a popup showed, and anything that failed unseen, including an error inside the panel itself.
    • With ids and times: each session as it started, resumed or forked; each turn with its result, its duration and when its first output came; approvals; sign-in changes; and why the backend restarted.
    • Kept out: your prompts, files, dictated words and the model's output. Keys are redacted.
    • More detail: set the channel's level to Trace (the gear in the Output view) to see how long each Muse Code command and Model API request took.
  • A Model API request fails with "The server's certificate is not trusted" — the network inspects HTTPS and re-signs it with its own root. Install that root in the operating system's certificate store and keep http.systemCertificates on, or turn http.systemCertificates off and name the root's file in NODE_EXTRA_CA_CERTS before starting VS Code; the variable does not help while that setting is on. Muse Code reads the system store too.
  • "The proxy asked for credentials" or "The proxy refused the connection (HTTP 403)" — the proxy wants a sign-in VS Code did not give it, or does not allow api.meta.ai. Check http.proxy and http.proxyAuthorization, or ask for the host to be allowed.
  • Muse Code cannot reach Meta behind a proxy the browser uses — the proxy comes from the system settings or a PAC file, which only VS Code reads. Set http.proxy, or HTTPS_PROXY in museSpark.environmentVariables, and the next message restarts Muse Code with it. Muse Spark: Diagnostics says where Muse Code's proxy comes from.
  • A permission mode is refused with "Muse Code's configuration … does not allow this permission mode" — its default permission profile or a policy your administrator manages caps the modes; choose a stricter one. Muse Spark: Diagnostics prints muse config status.
  • A Model API reply ends with "sent nothing for 300 s" — the stream stalled, so the turn was ended rather than left running until Stop. Send the message again to retry.
  • The agent says a file is too large (Model API backend) — the file tools read and edit text and images up to 10 MiB and read PDFs up to 32 MB; the search tool skips files over 1 MiB. The agent can read part of a larger file with a shell command.
  • Sign-out does not finish, or the panel stays gated — sign-out asks Muse Code to sign itself out (account/logout). Only when Muse Code still reads signed in afterwards does it open muse logout in a terminal, with museSpark.environmentVariables, so it signs out the same config home. With META_API_KEY set, Muse Code cannot confirm the logout itself; the extension then reads the sign-in again and opens no terminal once it shows none.
    • Waiting for the terminal: the panel stays gated, with Check again, until muse logout has run. That command leaves ~/.config/muse/auth.json behind with no sign-in in it, and the extension reads that as signed out. Choose Check again once the terminal is done. If the terminal could not open, run muse logout yourself.
    • An inherited META_API_KEY: it stays outside the extension. Remove it from your environment or VS Code's configured environment variables, then choose Check again. Browser approval cannot override that key's billing priority.
    • Sign-out protection could not be saved: finish muse logout and remove META_API_KEY before reopening VS Code.
    • The old CLI sign-in remains: a fresh browser approval can replace it. The panel uses that sign-in only after Muse Code confirms it.
    • The stored Model API key cannot be deleted: sign-out stops this window's backend and keeps it gated until the key can be cleared.
  • The panel says Muse Code cannot start because its sign-in file is in the macOS format — the auth.json it names came from a Mac: a version-2 file, or one whose sign-in lives in the Keychain. Muse Code 1.4.0 on Windows and on Linux exits at startup with such a file, even an empty one. Move or rename the file, then sign in again. With META_API_KEY set, Muse Code starts anyway and uses the key.
  • The panel shows signed in on macOS, but the first message asks you to sign in — on a Mac the token is in the login Keychain, and the extension asks Muse Code about it only when you act: a click in the panel (sign-in, sign-out, Check again), or the Sign Out or Diagnostics command. That goes for any auth.json on a Mac but the empty one a sign-out leaves, since what Muse Code 1.4.0 does there with another file has not been seen. A Keychain prompt never appears just because VS Code opened. Choose Check again to have Muse Code asked afresh now. Muse Spark: Diagnostics says whether the Keychain item exists, looked up without reading the secret; it also asks Muse Code for its sign-in, and Muse Code may read the Keychain to answer, which can show the Keychain's prompt.
  • Browser sign-in fails with "keychain write failed (internal error -2147483648)" on Windows or Linux — Muse Code 1.4.0-R4161.1 could not save a sign-in there (#38, #53). R4302.1 fixed it, and Muse Code's launcher updates itself; 1.4.0-R4302.1 or later needs nothing more (Muse Spark: Diagnostics shows the version). Only if you are stuck on R4161.1: add TBH_CREDENTIAL_BACKEND with the value file to museSpark.environmentVariables and to the terminal you sign in from. That undocumented switch, which Meta's own SDK tests use, keeps the sign-in in auth.json. Remove it after updating, and never set it on macOS, where it hides a Keychain sign-in.
  • Every shell command fails with sandbox enforcement unavailable — Muse Code runs commands inside an OS sandbox that needs a one-time administrator setup on Windows. The panel offers it in a notification ("Set up now" relaunches muse sandbox windows setup through the UAC prompt); the same flow is Muse Spark: Set Up Shell Sandbox. Start a new conversation afterwards. Linux and macOS need no setup.
  • Shell commands run in C:\Windows\System32\WindowsPowerShell\v1.0 instead of the project — Muse Code's Windows sandbox (1.3.0 and 1.4.0; on 1.3.0 the first command also takes about half a minute) cannot enter folders under C:\Users\<you> (meta-models/muse-code-sdk#26). With museSpark.shellSandbox at auto the extension starts Muse Code without the sandbox for such workspaces: commands run directly as you, in the project, still gated by the approval cards, and the panel says so once per conversation. muse keeps the sandbox regardless; off never sandboxes.
  • No Rename, conversation rewind or Side chat with Muse Code on Windows — Muse Code refuses session/rename and session/fork on Windows (1.3.0 and 1.4.0; #30, #31), so the panel does not offer fork-based actions there, whatever the version, until a release is verified to fix them; Rewind code to here still works, and the Model API backend offers all of them.
  • A warning that "Muse Code reported an error for the decision (the tool may have run anyway): … approval ledger durability fence …" — Muse Code on Windows (seen on 1.3.0) sometimes fails its own ledger write after applying your decision (#29). The tool row shows what happened; nothing needs redoing.
  • Model API charges while using the CLI — the extension never hands your pasted key to the CLI (the "muse serve credentials" line in the Muse Spark log says which credential it started with). If the CLI itself holds a pay-as-you-go key (muse auth set) or META_API_KEY is exported in your environment, the CLI uses it, exactly as Meta documents.
  • The Agent map says delegation is off — Muse Code hides its subagent tools until run.subagent_delegation_mode is "auto" in its own settings file; the map's button opens that file. The extension never edits it.
  • Muse never starts a workflow — Muse Code's run.workflow_trigger_mode may be off (no workflow tool) or explicit (only when you ask); the Agent map says which and opens the settings file.
  • A workflow has no Cancel, Skip or Retry button — this increment follows its progress read-only. Owner controls wait for a captured accepted-command and outcome shape from Muse Code.
  • The microphone says "Voice dictation failed: No microphone is available" — Windows sees no recording device from this session (Remote Desktop hides the host's devices unless the client redirects a microphone). On macOS, "Siri and Dictation are disabled" means Dictation must be switched on in System Settings > Keyboard.

Development

git clone https://github.com/RandyNorthrup/muse-spark-code.git
cd muse-spark-code
npm ci          # also installs the pre-commit hook (lint-staged + gitleaks)

Press F5 to launch the Extension Development Host with a fresh build. CONTRIBUTING.md has the rules for a pull request; SECURITY.md the way to report a vulnerability.

Prerequisites.

  • Node 22 or newer (.npmrc enforces engine-strict).
  • gitleaks on PATH for the hook and npm run security:secrets.
  • semgrep for npm run security:sast, at CI's version: pip install -r .github/semgrep/requirements.txt.
  • Google Chrome (or CHROME_PATH) for test:a11y, harness:shots and images.
  • On Windows, PSScriptAnalyzer 1.25.0 for npm run lint (Install-Module PSScriptAnalyzer -RequiredVersion 1.25.0 -Scope CurrentUser).

Stack. TypeScript 6.0.3 (pinned: typescript-eslint does not yet support TS 7); the extension host bundled with esbuild to CommonJS, with the Model API backend as a second bundle (dist/modelApi.js) that loads when that backend first starts; the webview is React 19 bundled to one IIFE with its stylesheet; zod/mini validates every host ⇄ webview message; the voice helpers are Windows PowerShell and Swift with no dependencies.

Command What it does
npm run build:dev Dev bundles for the extension, the Model API backend, the search worker, the webview and the integration tests, with source maps
npm run watch Rebuild the extension, the Model API backend, the search worker and the webview on change
npm run harness:shots Screenshots of the webview in headless Chrome behind a fake host (test/harness/), every scenario or the names you pass; needs build:dev. The README's screenshots are these renders, copied from harness-shots/ into media/readme/: tools (as turn.png), agents, slash-palette (as palette.png), slash-commands, approval, question, quote-menu (as quote.png), rewind, modes, history, usage, dictation (as voice.png), paid and paid-always, and the Languages section's is usage --lang=de (as languages.png); the walkthrough's are empty, tools, slash-palette and signin (as open.png, welcome.png, chat.png and sign-in.png in resources/walkthrough/); --lang=<id> renders them in a table from l10n/ (--lang=pseudo in the pseudo-locale)
npm run harness:pseudo Write the pseudo-locale (test/harness/l10n/ui.pseudo.json): every string accented, bracketed and lengthened by about a third, with its slots kept, so English left outside the table and text that overflows stand out in harness:shots --lang=pseudo
npm run test:a11y The accessibility gate: axe-core checks every harness scenario in VS Code's four default themes against WCAG 2.2 AA and fails on any violation, on anything axe leaves undecided, and on a page without a result or whose scenario threw; needs a build. node scripts/capture-themes.mjs refreshes the theme colours from a real VS Code; --lang=<id> checks the scenarios in a table from l10n/
npm run images Render the Marketplace icon, the README banner and the social preview from their SVGs (headless Chrome)
npm run build Minified production bundles, then enforces the size budgets in scripts/check-bundle-size.mjs, fails if the Model API backend's files are in the activation bundle (scripts/check-bundle-split.mjs) or a host bundle reads navigator, and checks THIRD_PARTY_NOTICES.txt against the bundled packages
npm run notices Regenerates THIRD_PARTY_NOTICES.txt from the production bundles
npm run format / npm run format:check Prettier write / check
npm run lint eslint --max-warnings=0 (type-aware), stylelint --max-warnings=0, and PSScriptAnalyzer 1.25.0 over native/windows (Windows only; a reported skip elsewhere)
npm run typecheck tsc --noEmit for the host, webview, unit-test, e2e-test and integration-test projects
npm run deadcode knip: unused files, exports, dependencies (no --strict; see knip.jsonc)
npm run cycles dpdm circular-import check from the extension's, the Model API backend's and the webview's entry points
npm run duplication jscpd copy-paste detection (threshold 0)
npm run test:unit vitest with coverage thresholds (90 % statements/lines/functions, 85 % branches); includes test/e2e/, where a fake Muse Code CLI is spawned as a real child process (a compiled stub on Windows) and driven through the real backend manager
npm run test:e2e:live One real turn on the installed Muse Code CLI, opt-in with MUSE_LIVE_E2E=1; bills the signed-in subscription (25 to 45 model attempts measured for a reply-only turn: one for the answer, the rest for Muse Code's bundled reminder agents, which loop a varying number of times; budget 60, counted from the CLI's trace log); never in CI
npm run test:e2e:live:modelapi The Model API sweep: the production backend against Meta's real API in empty temporary workspaces, one case per feature (-- -t case07 runs one); opt-in with MUSE_LIVE_MODEL_API=1 and the key in MUSE_LIVE_MODEL_API_KEY, contributor tier only; bills the key (about $0.03 a full run, $0.02 of it two images; it stops sending past $0.50); never in CI
npm run test:integration Builds, downloads VS Code stable and the engines.vscode floor into .vscode-test/, runs test/integration/** in each; after npm run build:dev, npm run test:integration:run -- --label stable (or minimum) runs one
npm run test Unit then integration
npm run security:audit scripts/audit.mjs: fails on a high or critical advisory without a dated, reviewed entry in .github/audit-exceptions.json
npm run security:sast semgrep scan --config auto --error through scripts/sast.mjs, which also finds a semgrep that pip put in Python's user Scripts folder when that folder is not on the shell's PATH
npm run security:secrets gitleaks git over the repository history
npm run check:l10n The localization gate: every table in l10n/ has every key of the English one (src/shared/l10n/en.ts) with the same {slots}, code spans and bold markers, exactly the plural forms its language uses, and nothing left in English but the names l10n/untranslated.json allows; every string package.json shows is a %key% of package.nls.json; and nothing reads UI_TEXT while its module loads
npm run quality:gates format:check, lint, typecheck, check:l10n, deadcode, cycles, duplication, test:unit, build, security:audit: what CI runs on all three platforms
npm run quality quality:gates, then test:a11y, security:secrets and security:sast; exits non-zero on any finding
npm run quality:ci quality:gates, test:a11y, then test:integration (no secrets or SAST); CI itself runs these as separate steps, see Releases
npm run package vsce package --no-dependencies (after vscode:prepublish runs npm run build) → .vsix; it carries the macOS helper only if bash native/darwin/build.sh built it first, on a Mac
npm run clean Remove dist/ and coverage/

Tests. Unit tests (test/unit/**) run under vitest with vscode aliased to test/unit/mocks/vscode.ts and webview components under jsdom; the fakes in test/unit/helpers/ implement the full VS Code interfaces. The e2e tests (test/e2e/**) drive the real backend manager against a fake Muse Code CLI that answers the Muse Session Protocol, including approvals, questions and subagents. Integration tests (test/integration/**) run under mocha inside a real VS Code launched by @vscode/test-cli (on Linux under xvfb-run -a), against test/fixtures/workspace/.

Quality gates. Every gate fails the build rather than printing, and each was seen to fail on a deliberate break before being trusted; the records are in docs/certification/, one file per milestone. Accessibility is a gate too: every screen the harness shows passes axe-core's WCAG 2.2 AA rules in Light Modern, Dark Modern and both High Contrast themes (PLAN.md D32); CI runs it on Linux and Windows. So is localization (PLAN.md D33): text the user reads goes in the English table src/shared/l10n/en.ts, read as UI_TEXT.key when the code runs. A sentence around a value is a {slot} template filled with fill, and a count is forms({ one, other }) read with plural. Numbers and times go through the Intl helpers beside them. Text for the model is MODEL_TEXT and stays English. Escape hatches (eslint-disable, @ts-expect-error, casts) need an inline reason and a row in PLAN.md §8. Bundle budgets: 600 KiB for the extension, 400 KiB for the Model API backend's own bundle, 50 KiB for the search worker, 900 KiB for the webview.

Environment variables. Credentials live in SecretStorage, never in files. .env.example documents META_API_KEY, which the Muse Code CLI inherits untouched if you export it yourself (and prefers over its sign-in, as Meta documents); the extension never sets it. The tooling also reads MUSE_LIVE_E2E, CHROME_PATH and VSCODE_TEST_VERSION, as described above.

Project structure.

src/extension.ts            activation: the view, the panel, the commands, the output and file openers
src/host/                   VS Code-facing code: views and webview wiring, conversation, backend managers, the Model API bundle's entry and the search worker, commands, auth, settings, mentions, editor tracking, usage trace logs, voice, the diagnostics MCP server, the MCP servers' spawner, the network posture, the paid features' host side and the ide image tools
src/core/                   backend-agnostic logic, no `vscode` import: MSP host, Model API client and tools, the MCP client, rules/skills/memory, export, worktrees, usage insights, dictation driver, PDF and text attachments, the paid gate, Muse Voice, network failures
src/shared/                 constants + zod message protocol shared with the webview
src/shared/l10n/            the English table (en.ts), the fill, plural and Intl helpers, and the table checks
l10n/                       the translated tables (ui.<language>.json) and the gate's list of names left in English
package.nls.json            the manifest's text: commands, settings, the walkthrough
src/webview/                React app (own tsconfig, browser libs)
native/windows/             dictate.ps1 (dictation, System.Speech) and capture.ps1 (Muse Voice's recorder); MuseSparkJob.cs, MuseSparkMcpLauncher.cs, MuseSparkMcpJob.cs: the Windows job helpers' C#, compiled on first use
native/darwin/              Dictation.swift, Info.plist, build.sh, check-disclaim.sh: the macOS helper (built and checked in CI)
resources/walkthrough/      the Get Started walkthrough
test/unit/                  vitest tests, vscode mock, fakes
test/e2e/                   the fake Muse Code CLI and the tests that drive the real backend through it; the opt-in live drill
test/integration/           @vscode/test-cli suites
test/fixtures/workspace/    the workspace the integration tests open
test/harness/               the webview behind a fake host, for screenshots and the accessibility gate; themes/ holds VS Code's four default themes
scripts/                    esbuild build; bundle-size, bundle-split, host-globals, notices, audit, PSScriptAnalyzer, accessibility and localization gates; the pseudo-locale; theme capture, harness screenshots, image rendering; CHANGELOG notes and VS Code versions for the workflows
docs/                       PRIVACY.md, and certification/: per-milestone gate-fire records
media/                      icons, banner, social preview, README screenshots
.github/                    workflows (ci, build, release), issue and pull-request templates, audit exceptions, pinned semgrep, CODEOWNERS, Dependabot, FUNDING

Releases. CI (ci.yml, every pull request and optional manual branch dispatch) calls build.yml:

  • quality:gates on Ubuntu, Windows and macOS;
  • the accessibility gate and the integration tests (VS Code stable and the engines.vscode floor) on Ubuntu and Windows;
  • gitleaks over the full history and semgrep, as jobs of their own;
  • a native-darwin job that compiles the macOS helper and checks its disclaim;
  • a package job (Ubuntu) that packs the .vsix with both helpers as the muse-spark-code-vsix artifact.

A tag v1.2.3 runs release.yml. It checks that the tag matches the manifest and is on main, runs the same build, creates a GitHub Release with that .vsix and the CHANGELOG section as its notes, and publishes it to the Marketplace (publisher RandyNorthrup) from the marketplace environment, which only version tags reach; without VSCE_PAT the publish is skipped and reported. A .vsix packed locally has no macOS helper, so only CI's is published.

Build troubleshooting.

  • npm ci fails with an engine error — Node 22+ is required.
  • Pre-commit hook says gitleaks: command not found — install gitleaks (Windows: winget install Gitleaks.Gitleaks).
  • Type-aware lint rules stop reporting — npm ls typescript must show 6.0.x; TypeScript 7 is outside typescript-eslint's peer range.
  • npm run test:integration cannot download VS Code — the download goes to .vscode-test/; on a restricted network set VSCODE_TEST_VERSION or pre-populate the folder from another machine.
  • Webview is blank after a change — run npm run build:dev (F5 does this via the pre-launch task) and reload the window.

How this extension is built

The extension is developed by a small team of AI agents under one human owner. The process below has been in use since 2026-09-28. Each milestone's record in docs/certification/ says what was actually run for it; the records of milestones before that date describe their own checks, which sometimes differed (for example, M7 was certified against a fake server and M44 took a response shape from Meta's documentation).

  • The owner sets the plan (PLAN.md), makes the product decisions, and approves anything that spends money, signs in or publishes.
  • Claude Code is the lead engineer: it turns the plan into briefs, builds the harder milestones itself (security-sensitive and stateful work), verifies every review finding in the code, and merges.
  • Muse Code, the product's own backend, builds too. Up to four headless muse exec instances draft well-scoped milestones in their own git worktrees, on the Muse Spark contributor model; a Claude Code agent checks and finishes each draft, and it goes through the same review and gates.
  • Reviewers. A change is reviewed before it is pushed, one defect class at a time (concurrency and lifecycle; wire evidence, validation and security; failure paths, honesty and docs), by Grok Build on a test machine (reading files and inspecting git only) or by Claude Code review agents. On the pull request, Codex reviews again. A finding is fixed with every sibling of its class in one commit, and a change that reaches a third review round is redesigned instead of patched.
  • Gates. AGENTS.md requires npm run quality to exit 0 before a commit is proposed. Every commit is gated before it is pushed: one complete npm run quality run (formatting, lint, types, tests with coverage, the accessibility suite, the secret scan and semgrep) on one of three dedicated test machines (a Windows 11 virtual machine, a Kubuntu virtual machine and a Mac mini), so it never competes with the owner's workstation. The PowerShell lint runs only on Windows, so a change to a PowerShell script gets its run there. CI then runs quality:gates on Ubuntu, Windows and macOS, and the other gates as the jobs listed above. A milestone's new guards get red drills: each guard is broken on purpose, its test must fail, and the file is restored byte for byte; the record lists the drills and anything not drilled.
  • Evidence. Under AGENTS.md rule 13, a shape parsed from Muse Code or the Model API is written from a live capture, and the record names it or says it did not have one. Live checks run on the contributor model in throwaway workspaces and record their model-call counts.

Support this project

If Muse Spark Code saves you time, you can buy me a coffee via PayPal. Thank you!

More

About

Meta's Muse Spark as a coding agent inside VS Code: streaming chat, tool calls with diffs, permission modes, session history, voice dictation. Unofficial.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

6 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Contributors

Languages