Origami Coder
Documentation
Origami Coder is a coding agent. It runs against a model that you host, or against a cloud provider.
Two artifacts, not one
Origami Coder ships as two programs. They are built separately and installed separately. A change to one does not change the other.
| Artifact | Source | What it does | Installed as |
|---|---|---|---|
| Extension | packages/vscode/ | The VS Code user interface: panes, cards, webviews, the dashboard. | A .vsix file |
| Engine | packages/engine/ | The agent runtime: tools, sessions, prompts, model calls. | A binary at ~/.origami/bin/origami.exe |
The extension talks to the engine over the Agent Client Protocol (ACP). The engine also runs on its own, as a terminal program and as a headless server.
Surfaces
- VS Code extension — the chat view, the dashboard and the Folds board. See VS Code.
- Headless server —
origami serveandorigami web. See Server. - Terminal UI — the
origamibinary with no command. See Terminal UI.
This documentation describes the code in the repository. A desktop application is not part of this build. There is no packages/desktop, and no package declares Tauri or Electron as a dependency.
What Origami Coder is built around
These parts define the product. Each one has its own page in this documentation.
- Local models come first. The extension points at
http://localhost:1234/v1by default. The engine detects a self-hosted endpoint and gives it long timeouts. - A context meter. The extension counts real tokens per session and shows how full the model window is.
- The
/firstfoldcommand. It turns an empty folder into a workspace with instructions, a wiki, commands and skills. - The
wrapskill./firstfoldwrites it. It closes a session: one handoff block plus one wiki page. - The Folds board. Four tools read and write a ticket board, and the extension shows it as an agent manager.
- Messages between sessions. The
list_agentsandsend_messagetools let two Origami sessions on one machine talk. - Memory tools.
rememberwrites durable notes; the/dreamcommand reorganises them. - Charts and a browser. The
charttool draws in the chat. Thebrowsertool drives the VS Code integrated browser. - Flock fallback. A profile gives subagents their own model, with an ordered list of fallbacks for when a server is unreachable.
Getting started
Install
Install the extension from the Visual Studio Code Marketplace. Building from source stays available for development.
Install from the Marketplace
The Marketplace is the main way to install Origami Coder. Search for Origami Coder in the VS Code Extensions view, or install by identifier: OrigamiLabs.origamicoder. The extension bundles the engine and its search tool for your platform, so one install gives you the whole product.
Origami Coder is pre-release. The Marketplace listing goes live with the first public build.
Build from source
The engine and the extension build independently. A source install needs both.
Requirements
- Bun
1.3.14. The repository declares it as its package manager. - VS Code
^1.106.0for the extension.
Build the engine
The engine build script writes a binary for the current platform. Use --single to build only that one target.
bun install cd packages/engine bun run script/build.ts --single
Other flags of the build script are --baseline, --skip-install, --sourcemaps and --skip-embed-web-ui.
The command name is origami. The package declares the launcher at bin/origami.
Build the extension
cd packages/vscode npm run build # node esbuild.js npm run typecheck # tsc for src and webview npm run package # vsce package --no-dependencies
npm run package writes a .vsix file. Install that file in VS Code. The extension identifier is OrigamiLabs.origamicoder.
Run the type check. The unit tests do not check types. Vitest removes types without checking them, so code that cannot compile can still have a green test run.
Where files are kept
| Path | Content |
|---|---|
~/.origami | The product home: bin/, sessions/, skills/, settings.toml, global plans and global memory. |
<XDG config>/origami | The global configuration directory. Without XDG_CONFIG_HOME this is ~/.config/origami. |
<XDG data>/origami | Data, including auth.json, log/ and repos/. |
<XDG cache>/origami | Cache, including downloaded binaries in bin/. |
<XDG state>/origami | State. |
The command origami debug paths prints these paths.
Remove the program
origami uninstall removes the program and its files. It accepts --keep-config, --keep-data, --dry-run and --force.
Reference
Configuration
One JSON file holds the engine configuration. The terminal UI keeps its own file.
File names
The engine reads origami.json and origami.jsonc. The global directory also accepts the older name config.json.
Project files are found by a walk up the directory tree from the working directory to the worktree root. The file closest to the working directory wins.
Order of merge
Later sources overwrite earlier sources.
- The global directory:
config.json, thenorigami.json, thenorigami.jsonc. - The file named by
ORIGAMI_CONFIG. - Project
origami.jsoncandorigami.json, walking up. - Each
.origamidirectory, andORIGAMI_CONFIG_DIRif it is set. - Inline JSON in
ORIGAMI_CONFIG_CONTENT. - The system-managed directory.
The system-managed directory is /Library/Application Support/origami on macOS, %ProgramData%\origami on Windows, and /etc/origami elsewhere.
Unknown keys are an error
The parser accepts JSONC with trailing commas. An unknown key at the top level stops the load with the message Unrecognized key(s).
The keys theme, keybinds and tui are removed from origami.json on load. They belong in tui.json.
Values from the environment and from files
Before the parse, the loader replaces two patterns in the text.
~/ is expanded. A relative path is read from the directory of the configuration file.Top-level keys
| Key | Type | Purpose |
|---|---|---|
$schema | string | JSON schema reference for configuration validation. |
shell | string | Default shell for the terminal and the bash tool. |
logLevel | DEBUG, INFO, WARN, ERROR | Log level. |
model | string | Model to use, in the format provider/model. |
small_model | string | Small model for tasks such as title generation. |
provider | object | Custom provider configuration and model overrides. |
disabled_providers | string[] | Disable providers that load automatically. |
enabled_providers | string[] | When set, only these providers are enabled. |
agent | object | Agent configuration. See Agents. |
default_agent | string | Primary agent to use when none is given. Falls back to build. |
subagent_depth | integer | Maximum subagent nesting depth. Default 1. |
command | object | Command definitions. See Commands. |
skills | object | Extra skill folders and URLs. See Skills. |
permission | object or string | Tool permissions. See Permissions. |
mcp | object | MCP server configuration. See MCP servers. |
plugin | array | Plugins to load. See Plugins. |
agentPlugins | string[] | Directories that hold agent-plugins.org plugins. |
instructions | string[] | Extra instruction files or patterns. Values from every source are joined, not replaced. |
formatter | boolean or object | Enable or configure formatters. |
lsp | boolean or object | Enable or configure language servers. A custom server must declare extensions. |
snapshot | boolean | Record filesystem snapshots. Default true. |
watcher | object | File watcher ignore patterns. |
compaction | object | auto, prune, tail_turns, preserve_recent_tokens, reserved. |
tool_output | object | max_lines (2000) and max_bytes (51200) before tool output is truncated to disk. |
attachment | object | Image limits: auto_resize, max_width, max_height, max_base64_bytes. |
references | object | Named git or local directory references. |
flock | object | Model profile for subagents, with health fallback. See Models and providers. |
server | object | port, hostname, mdns, mdnsDomain, cors. |
share | manual, auto, disabled | Control session sharing. |
autoupdate | boolean or "notify" | Update behaviour. |
username | string | Name shown in conversations. Defaults to the operating system user. |
enterprise | object | Enterprise URL. |
experimental | object | Unstable options. See below. |
Deprecated keys
These keys still load. Use the replacement instead.
autoshare— useshare.reference— usereferences.mode— useagent.tools— usepermission.layout— has no effect.
Experimental options
enabled (default true), mcp (default true), defer, always. Only * works as a wildcard.Environment variables
A variable is true when its value is true or 1.
| Variable | Effect |
|---|---|
ORIGAMI_CONFIG | Path of one more configuration file. |
ORIGAMI_CONFIG_CONTENT | Inline JSON configuration. |
ORIGAMI_CONFIG_DIR | One more configuration directory. |
ORIGAMI_DISABLE_PROJECT_CONFIG | Ignore project files and project .origami directories. |
ORIGAMI_TUI_CONFIG | Path of one more terminal UI configuration file. |
ORIGAMI_PERMISSION | JSON merged over the permission block. |
ORIGAMI_DISABLE_AUTOCOMPACT | Force compaction.auto to false. |
ORIGAMI_DISABLE_PRUNE | Force compaction.prune to false. |
ORIGAMI_DISABLE_AUTOUPDATE | Turn off automatic update. |
ORIGAMI_DISABLE_MODELS_FETCH | Do not fetch the model database. |
ORIGAMI_DISABLE_MOUSE | Turn off mouse capture in the terminal UI. |
ORIGAMI_PRINT_LOGS | Print logs to standard error. |
ORIGAMI_PURE | Run without external plugins. |
ORIGAMI_SERVER_USERNAME | Basic authentication user for the server. |
ORIGAMI_SERVER_PASSWORD | Basic authentication password for the server. |
ORIGAMI_AUTH_CONTENT | Credential store content, instead of auth.json. |
ORIGAMI_EXPERIMENTAL | Turn on every experimental gate. |
The command origami debug config prints the resolved configuration.
Usage
VS Code
The extension is the main surface. It holds the chat view, the dashboard and the Folds board.
Identity
- Name:
origamicoder. Publisher:OrigamiLabs. Display name: Origami Coder. - Required editor: VS Code
^1.106.0. - The extension starts on the
onStartupFinishedevent.
Commands
| Command | Title |
|---|---|
origami.init | Origami: Get Started |
origami.toggleSidebar | Origami: Toggle Sidebar |
origami.newSession | Origami: New Session |
origami.newChat | Origami: New Chat |
origami.openChat | Origami: Open Chat |
origami.openChatInEditor | Origami: Open Chat in Editor |
origami.switchModel | Origami: Switch Model |
origami.openHistory | Origami: Recall Past Chat |
origami.openAgentManager | Origami: Folds (Agent Manager) |
origami.openAgentProfile | Origami: View Agent Profile |
origami.toggleTheme | Origami: Toggle Theme (Meadow/Quiet) |
origami.resetSavedPermissions | Origami: Reset saved permissions |
origami.init shows the chat view and runs /firstfold. origami.openAgentManager opens the Folds board, which runs parallel agents in separate git worktrees.
Key bindings
| Command | Windows and Linux | macOS |
|---|---|---|
origami.toggleSidebar | ctrl+shift+l | cmd+shift+l |
origami.newSession | ctrl+shift+n | cmd+shift+n |
origami.switchModel | ctrl+shift+m | cmd+shift+m |
origami.openChat | ctrl+alt+o | cmd+alt+o |
Settings
Inference engine endpoint, an OpenAI-compatible
/v1 base URL. It overrides the ORIGAMI_API_BASE environment variable. Point it elsewhere to use a remote engine.Development only. Absolute path of a
packages/engine source tree. When set, the extension runs the engine from source with Bun instead of the compiled binary.The name that other Origami sessions on this machine see for this window. An empty value uses the folder name. It takes effect when the engine next starts.
Replace the individual MCP tools with one
execute tool that runs a confined JavaScript program.Switch the VS Code colour theme when the dashboard theme changes.
Workflow settings
Every workflow option is off by default.
| Setting | Effect |
|---|---|
origami.workflow.enable_briefing | Session-start briefing, as a file dump. |
origami.workflow.enable_briefing_llm | Distil that briefing through a model first. Needs the briefing. |
origami.workflow.enable_decision_loopback | Replay recent policy decisions into each turn. |
origami.workflow.enable_plan_auto_trigger | Enter plan mode for create, refactor, multi and repo-wide tasks. |
origami.workflow.enable_recon | Run a reconnaissance phase before file work. |
origami.workflow.enable_task_shape | Extract numbered sub-tasks before the first turn. |
origami.workflow.enable_shape_llm | Ask the model for a task shape when the rule finds none. |
origami.workflow.enable_best_of_n | Best-of-N plans with critic scoring. |
origami.workflow.best_of_n_k | Candidate count for a best-of-N wave. Default 3, range 2 to 5. |
origami.workflow.enable_reflective_retry | Retry after a failure-recovery rollback. |
origami.workflow.enable_ask_user_question | Give the model the inverted ask_user_question tool. |
origami.workflow.enable_reasoning_trace | Write reasoning-trace rows to SQLite. |
The context meter
The extension counts the tokens of each turn and keeps a total per session. It records prefill (input), read (cache read), write (output), the turn count, the window occupancy and the window size.
The fill bar has three bands: 80 percent or more is high, 60 percent or more is middle, below that is low. A reported value of zero means "not known" and keeps the earlier value, because a local server often reports zero for the window size.
Chat commands in VS Code
The extension answers four slash commands itself. They never reach the engine.
/loop.Usage
First fold
/firstfold turns an empty folder into a workspace. It is a command of the VS Code extension.
What it writes
The wizard shows a live checklist while it works. Each step is paced. Existing files are skipped, never overwritten, so you can run it again safely.
- Scan the workspaceIt reads
package.jsonscripts and marker files such asCargo.toml,pyproject.toml,requirements.txtandgo.modto find the build, test and lint commands. - Write AGENTS.mdHouse rules for the agent, plus a "Build and test" section from the scan.
- Create folders
projects/,scripts/andcrons/. - Seed the wiki
wiki/pages/and awiki/index.mdprimer. - Create HANDOFF.mdA rolling session log with an anchor line that marks where new blocks go.
- Seed commands and skills
.origami/command/example.mdand one.origami/skills/<name>/SKILL.mdper default skill. - Connect a modelA provider picker writes the provider block into the global configuration file.
Run /firstfold model to repeat only the model step.
Reload the window after a first fold. The engine reads the configuration and scans .origami/command and .origami/skills once, when it starts.
The default skills
These skills are written into .origami/skills/<name>/SKILL.md.
wrap,example-skillgrill-me,to-spec,to-tickets,triage,tdd,diagnosing-bugs,code-review,wayfinder,handoff
The wrap skill
/wrap closes a session. It is a skill file, not engine code. It becomes a slash command because the engine registers every skill as a command.
The skill does two linked jobs in one pass.
- Insert a block in
HANDOFF.md, directly below the anchor line. The block holds a dated heading, adone:line, anext:line and awiki:link. - Write the depth into
wiki/pages/<page-name>.md: one topic per page, kebab-case, flat, withtagsfrontmatter and at least one link to another page.
A workspace that never ran /firstfold has no wrap skill. Copy the file, or write your own.
Usage
Terminal UI
Run origami with no command to open the terminal interface.
Start it
origami # start in the current directory origami ./my-project # start in a directory origami -c # continue the last session origami -m lmstudio/qwen3-coder
The terminal interface is a SolidJS application drawn by OpenTUI.
Its own configuration file
Terminal settings live in tui.json or tui.jsonc, not in origami.json. The search order is the global directory, then ORIGAMI_TUI_CONFIG, then project files walking up, then each .origami directory.
| Key | Purpose |
|---|---|
theme | Theme name. See Themes. |
keybinds | Key binding overrides. See Keybinds. |
leader_timeout | Leader key timeout in milliseconds. Default 2000. |
plugin, plugin_enabled | Terminal plugins and their on/off state. |
attention | Notification and sound settings: enabled, notifications, sound, volume, sound_pack, sounds. |
prompt | max_height and max_width of the prompt box. |
scroll_speed, scroll_acceleration | Scroll behaviour. |
diff_style | auto or stacked. |
mouse | Mouse capture. Default true. |
Slash commands in the terminal
These commands belong to the terminal interface. They do not reach the engine.
| Command | Action |
|---|---|
/sessions, /new, /fork, /rename, /timeline | Manage sessions. |
/models, /variants, /agents, /connect | Switch model, variant, agent, or connect a provider. |
/mcps | Turn MCP servers on and off. |
/themes, /help, /status, /debug, /exit | Application actions. |
/compact (alias /summarize), /undo, /redo | Change the transcript. |
/share, /unshare, /copy, /export | Share and export. |
/diff, /editor, /skills, /timestamps, /thinking | Views and panels. |
/warp, /move, /workspaces, /org | Change directory, workspace or organisation. |
The terminal autocomplete hides slash commands that come from skills. The VS Code palette shows them.
Side panel
The side panel holds a context readout, an MCP list, a language-server list, the todo list and the file list.
Usage
Command line
The binary is origami. With no command it opens the terminal interface.
Global options
DEBUG, INFO, WARN, ERROR.origami completion writes a shell completion script.
Commands
| Command | Description |
|---|---|
origami [project] | Start the terminal interface. |
origami run [message..] | Run Origami with a message. |
origami serve | Start a headless server. |
origami web | Start the server and open the web interface. |
origami attach <url> | Attach to a running server. |
origami acp | Start the Agent Client Protocol server. |
origami models [provider] | List every available model. |
origami providers (alias auth) | Manage providers and credentials. |
origami agent | Manage agents. |
origami mcp | Manage MCP servers. |
origami plugin <module> (alias plug) | Install a plugin and update the configuration. |
origami agent-plugin | Manage agent-plugins.org plugins. |
origami session | Manage sessions. |
origami export [sessionID] | Export session data as JSON. |
origami import <file> | Import session data from a file or a URL. |
origami stats | Show token use and cost. |
origami pr <number> | Fetch and check out a GitHub pull request branch, then run Origami. |
origami db [query] | Open a SQLite shell, or run a query. |
origami debug | Diagnostic tools. |
origami uninstall | Remove the program and its files. |
Options of the terminal command
provider/model.Options of run
default for formatted output, or json for raw JSON events.ORIGAMI_SERVER_USERNAME and ORIGAMI_SERVER_PASSWORD.Sub-commands
--url, --env KEY=VALUE, --header KEY=VALUE.origami mcp auth, auth list, logout and debug <name>.--path, --description, --mode (all, primary, subagent), --permissions (alias --tools), --model.login accepts --provider and --method.--max-count, --format table|json) and delete one.--verbose adds metadata such as cost. --refresh reloads the model database.--days, --tools, --models, --project.origami db [query] takes --format json|tsv.Diagnostics
origami debug holds the diagnostic commands: config, paths, info, startup, skill, scrap, agent <name>, snapshot, file, rg, lsp and v2 (the built-in catalog and plugins).
Usage
Server
The engine runs headless. Other programs then drive it over HTTP.
Start a server
origami serve origami serve --port 4096 --hostname 127.0.0.1 origami web
serve prints the address it listens on. web also opens the web interface.
Network options
These options belong to origami, acp, serve and web. They can also come from the server block of the configuration.
Port to listen on. Zero means that the operating system chooses a free port.
Hostname to listen on.
Enable mDNS service discovery. This changes the default hostname to 0.0.0.0.
Domain name for the mDNS service.
More domains to allow for CORS.
Set a password. The server prints a warning when ORIGAMI_SERVER_PASSWORD is not set, because the server is then unsecured. --mdns binds to every interface.
Attach to a server
origami attach http://localhost:4096 origami run --attach http://localhost:4096 "list the open tickets"
The HTTP interface
The server is an Effect HTTP application. It publishes an OpenAPI document, and it accepts WebSocket connections.
The route groups are config, control, control-plane, event, experimental, file, global, instance, mcp, metadata, permission, project, project-copy, provider, pty, query, question, session, sync, tui and workspace.
A generated OpenAPI document is kept in the repository.
Configure
Models and providers
A model is named provider/model. A provider block describes where the model lives.
Choose a model
provider/model.The name is split at the first slash only. A model identifier may therefore contain slashes, as in lmstudio/qwen/qwen3-coder-30b.
origami models lists every model as provider/model.
A provider block
{
"provider": {
"lmstudio": {
"name": "LM Studio",
"npm": "@ai-sdk/openai-compatible",
"options": { "baseURL": "http://127.0.0.1:1234/v1" },
"models": { "qwen3-coder-30b": { "name": "Qwen3 Coder 30B" } }
}
},
"model": "lmstudio/qwen3-coder-30b"
}
The keys of a provider block are api, name, env, id, npm, whitelist, blacklist, options and models.
Provider options
false turns it off.false turns it off.Model overrides
Each entry of models may set id, name, family, release_date, attachment, reasoning, temperature, tool_call, interleaved, cost, limit, modalities, experimental, status, options, headers, variants and a nested provider.
limit holds context and output. modalities holds input and output lists over text, audio, image, video and pdf.
A model that the model database does not know keeps tool_call true and every other capability false. Set "tool_call": false for a model that cannot call tools.
Turn providers on and off
Credentials
Credentials live in auth.json, in the data directory. The file is written with mode 0600. Three shapes are stored: oauth, api and wellknown.
Use origami providers login to add a credential and origami providers list to see what is stored. ORIGAMI_AUTH_CONTENT supplies the whole store from the environment instead.
Flock: a model for subagents
A Flock profile sets the model that subagent sessions use, and an ordered list of fallbacks.
{
"flock": {
"profile": "home",
"profiles": {
"home": {
"description": "local first, cloud second",
"subagents": {
"use": "lmstudio/qwen3-coder-30b",
"fallback": ["anthropic/claude-sonnet-4"]
}
}
}
}
}
An absent or null profile turns routing off. An unknown key inside a profile stops the load. Fallback happens on an authentication error, on HTTP 401, 403, 404, 408 and 429, and on any 5xx. Status 400 and 422 do not trigger it, because a malformed request fails the same way everywhere.
Configure
Local models
Origami Coder expects an OpenAI-compatible server on your own machine. This is the product's central design choice.
Connect a server
In VS Code, set origami.engineUrl. The default is http://localhost:1234/v1, which is an LM Studio server on the same machine. The setting overrides the ORIGAMI_API_BASE environment variable.
The connect picker offers LM Studio as "Local — runs on your own GPU (recommended)". It fills in the base URL http://127.0.0.1:1234/v1 and writes a provider block with the package @ai-sdk/openai-compatible.
Ollama uses the fixed endpoint http://localhost:11434/v1. The extension recognises an Ollama block by the provider identifier ollama, or by a loopback address on port 11434.
Any other OpenAI-compatible server works. Write the provider block by hand, as in Models and providers.
What counts as self-hosted
The engine reads the host name of the base URL. These count as self-hosted:
localhost,0.0.0.0,::1, and any name with no dot in it- names that end in
.local,.lanor.ts.net - addresses in
127.*,10.*,192.168.*,172.16.*to172.31.*, and100.64.*to100.127.*
Longer timeouts for local hardware
A self-hosted endpoint gets a default chunk timeout and a default header timeout of 300000 milliseconds. A cloud endpoint gets neither. The reason is stated in the code: a large prefill on local hardware can run for minutes before the first token, and a stuck local stream has no server-side reaper.
Set options.chunkTimeout or options.headerTimeout in the provider block to change them.
The context window
A local server often does not report its window size. The extension probes for it in this order.
- The LM Studio endpoint
/api/v0/models. It usesloaded_context_length, and only when the model state isloaded. - The OpenAI-compatible endpoint
/v1/models. It readsmax_model_len,max_context_lengthorcontext_length. - For Ollama, the native endpoint
/api/show. It reads the architecture context length, a barecontext_length, or anum_ctxparameter.
The maximum context length of a model is deliberately not used, because that value can be far larger than the memory of the machine.
Connecting a server saves the window too
Connecting a self-hosted server (the LM Studio or vLLM preset) writes the probed window into the saved model entry, not only into the display. This never overrides a window you set by hand, and a failed probe never blocks the connection — it just leaves the entry bare.
Control LM Studio
When LM Studio runs on the same machine, the extension can drive the lms command directly. It looks for the binary in ~/.lmstudio/bin. It loads a model with a chosen context length and unloads models. A remote LM Studio cannot be driven this way.
Two known problems of local servers
<think> markup on the content channel instead of the reasoning channel, sometimes with a closing tag and no opening tag. The engine scans for these tags and separates them.
vision_request tool instead of sending the image.
Match the server capacity
Set options.max_concurrent to the number of requests your server handles at once. Parallel subagents then queue instead of starving the server.
Configure
Agents
An agent is a named set of a prompt, a model and a permission list. A primary agent drives the session. A subagent does work for the task tool.
Built-in agents
| Name | Mode | Description |
|---|---|---|
build | primary | The default agent. It runs tools according to the configured permissions. |
plan | primary | Plan mode. It denies every edit tool, except files under .origami/plans/. It may delegate only to explore. |
general | subagent | General-purpose agent for research and multi-step tasks. It can run several units of work in parallel. |
explore | subagent | Fast agent for exploring a codebase. It reads and searches only. Give it a thoroughness level: quick, medium, or very thorough. |
Three more agents are internal and hidden: compaction, title and summary. They have every tool denied.
The default agent is build. Set default_agent to change it. The value must name a primary agent that is not hidden.
Shipped archetypes
The VS Code extension installs six ready-made agents into the global agent directory the first time you open the Folds board or the Collab Agents pane. Each is an ordinary markdown agent definition, so it works exactly like one you write yourself.
| Slug | Mode | Can edit | Can run shell | Notes |
|---|---|---|---|---|
architect | all | *.md only | no | Denies every tool by default, then re-allows reading, searching, the web and questions. Delegates only to scout. |
ask | all | no | no | Read-only. Delegates only to scout. |
debug | all | yes | yes | Ships with no permission block of its own, so it has the same reach as build. |
orchestrator | all | no | no | Allows every tool except edit and bash. Delegates to any subagent. |
scout | subagent | no | no | Read-only. Not shown in the agent picker. A modified copy is reset on the next extension start, because the other archetypes trust it by name. |
cartographer | all | .origami/map/* only | no | Delegates only to scout. Writes the repo architecture map. |
Write your own
Put a markdown file at <config dir>/agent/<name>.md. The plural agents/ also works, and sub-folders become part of the name.
--- description: Reviews a diff and reports defects only. mode: subagent model: lmstudio/qwen3-coder-30b temperature: 0.2 permission: edit: deny bash: ask --- You review changes. Report defects. Do not fix them.
The body of the file is the prompt. Agents can also be written as JSON under the agent key of origami.json.
Frontmatter keys
| Key | Type | Purpose |
|---|---|---|
description | string | When to use the agent. A subagent without one is only called by hand. |
mode | subagent, primary, all | Where the agent can be used. A file without this key defaults to all. |
model | string | Model in the format provider/model. |
variant | string | Default model variant. It applies only to the agent's own model. |
temperature, top_p | number | Sampling controls. |
prompt | string | The prompt. The markdown body usually supplies it. |
permission | object | Tool permissions. See Permissions. |
steps | integer | Maximum number of agent iterations before a text-only answer is forced. |
hidden | boolean | Hide the subagent from the @ menu. Default false. |
disable | boolean | Remove the agent, including a built-in one. |
color | string | A hex colour, or one of primary, secondary, accent, success, warning, error, info. |
options | object | Provider-specific values. Any unknown key is moved here. |
The keys tools and maxSteps are deprecated. Use permission and steps. The key role is accepted and ignored.
Subagents
The task tool lists every agent whose mode is not primary and that the caller's task permission does not deny.
subagent_depth limits the nesting. The default is 1, so a subagent cannot start another subagent.
Create an agent file from the command line with origami agent create, and list agents with origami agent list.
Configure
Collab
A collab is a shared room. Several agents and one human read the same message log. Each agent keeps its own session, and the room keeps a task board and a cost ledger.
How it differs from a session and a subagent
An ordinary session is one agent and one human. A subagent is started by the task tool, it answers once, and it is then gone. A collab is durable: the message log, the roster, the board and the ledger are rows in the database, so the room survives a restart.
Each participant gets its own persistent child session. The session is created on the agent's first turn, not when it joins, so a roster entry that never speaks costs nothing.
By default, only one turn runs at a time in one collab, and turns are held in a queue. A room may opt into running several turns at once with concurrency: N (up to 4), but only when every member's own permissions deny every file-writing tool outright — a wide room may read and discuss, it may not build. A council-flavored room (see below) always dispatches wide, because its turns are sealed read-only regardless of the setting.
A collab is driven from the VS Code extension. There is no collab CLI command, no terminal UI screen and no HTTP route. The engine surface is a set of ACP methods, listed below.
Flavors: discuss and council
A collab has a flavor, set with collab_set_flavor: discuss, the default, or council. A room with no stored flavor is a discuss room.
In a council, one human question dispatches to every active member at once. Each member reads the room as it stood at the question, so no member sees a sibling's opinion before it answers. Once every member has settled, the lead — or the first member in roster order if there is no lead — reads every opinion and writes one synthesis for the room. Council turns are sealed read-only, so a council may run wide with nothing to configure.
A hop, in a council, is the whole round: the opinions and the synthesis together cost one hop, not one each.
Make an agent collab-capable
An agent can join a room only if its definition file sets collab: true. The key is not a known agent key, so it is moved into options, and the roster check reads it from there.
--- description: Reads code and reports what it found. mode: subagent model: lmstudio/qwen3-coder-30b collab: true vision: true --- You are the scout. You read the repository and report facts.
The check fails closed. An agent without the key, or with frontmatter that does not parse, is refused with a message that names the file.
vision: true is a second, separate opt-in. It controls images only. See Images below.
The base prompt
Every collab agent gets a built-in base prompt above its own persona. The prompt states what the room is, what the tools do, and who routes work next. Live room state is added below the persona.
To replace the built-in text, write collab-agent-base.md in the global config folder. A missing, unreadable or empty file is not an override, and the built-in text is used.
The state block below the persona is rebuilt for every turn. It names the roster, the lead, the objective, the hops left and the first open tasks.
Run a collab
The composer in the VS Code chat view has nine slash commands for a room.
off, or default.A line that is not one of these nine is posted to the room as a message.
The lead and addressing
One agent is the lead. An unaddressed human message goes to the lead alone. With no lead set, nobody is woken, and the post is answered with the notice no-lead.
The lead is kept on an active agent. An empty seat is filled by the first agent in join order. If the lead is removed, the next agent takes the seat. Roster order is join order, not alphabetical order.
To address named agents, write @slug in the composer. The composer parses the line and sends a structured list of slugs. Unknown slugs are dropped, and the engine checks the list against the active roster before it writes anything.
Routing reads the kind of a message and its structured list of slugs. It never reads the prose. An @name written inside a sentence is a reference, and it wakes nobody. An ordinary message from an agent also wakes nobody: agents route work with the tools below, not with text.
The rules are an ordered list, and the first rule that has an opinion decides. In order: never the author, a human message to the named agents, an unaddressed human message to the lead, answers and directed messages to nobody, finished and reopened board work back to the agent that owns it, and silence for everything else. A rule that throws an error ends the decision at "skip".
Tools inside a turn
Eight tools exist only inside a collab turn. They are added to the request when a collab turn is present, and never at any other time, so an ordinary chat sees none of them. They are part of the protocol, so a permission list that denies by default does not remove them.
| Tool | Parameters | Effect |
|---|---|---|
ask | to, task, context, expect | Stops the caller's turn. The target runs a full turn, and the answer returns to the caller. |
handoff | to, task, context | Passes the work and ends the caller's turn. No answer returns. |
done | summary | Ends the turn. The summary is optional, and silence is valid. |
task_add | title | Opens a task that nobody owns. |
task_claim | taskId | Takes ownership of a task. |
task_done | taskId, result | Records the result and wakes the agent that opened the task. |
task_accept | taskId | Closes a task after a check. |
task_reopen | taskId, note | Sends the task back to its owner with a reason. |
A target is resolved against the active roster by slug first, then by display name. A leading @ is removed, and the match ignores letter case.
ask is refused, in this order, when the target is not on the roster, when the target is already waiting further up the same chain, when the chain is three deep, when the room has no hops left, and when the target session is busy. A refusal is returned to the one model that called the tool. The room does not see it.
The hop budget
A hop is one agent turn. One human message buys a fixed number of hops. When they are spent, the agents stop, and the room waits for a human.
| Cap value | Result |
|---|---|
| not set (null) | The engine default of 20 hops. |
0 | The budget is off. The room runs until it is stopped. |
| a positive integer | That many hops for each human message. |
The cap is stored for each collab as loop_breaker_cap. It must be null or an integer that is not negative. A new human post refills the budget. A stop spends all of it.
The budget is shared by reference along a chain of asks, so a deeper call cannot buy more hops. The agents are told how many wakes are left on each turn.
The task board
A task is the unit of accountability between agents. A task has one of four states: open, claimed, done and accepted. An ask opens a task by itself, and a human can add one by hand.
The board records the title, the owner, the agent that created it, the result, the note that reopened it, and the message that created it. A board move is a record. By itself it wakes nobody, except that finished work wakes the agent that asked for it, and reopened work wakes its owner.
A task title is cut to 80 characters, because the title is a label and the full brief is in the message.
Cost and tokens
One row is written for each completed turn, including a silent turn. A silent turn still spends tokens.
Each row holds the agent slug, the model as provider/model, the input tokens, the output tokens, the cost, and the agent that asked for the turn on a nested turn. Spend is summed from the step records of the turn.
The ledger returns a page of rows and a set of totals for each agent. The totals are summed in the database, so they cover the whole ledger and not only the page. The page holds 100 rows by default.
Images
Only a human can post an image. No agent tool accepts one. Images are stored in the message row as data: URLs, because the log is the record.
An image is refused if the message carries more than four images, if it is not a data: URL, or if it is larger than 2 MB. The check runs before anything is written.
An agent with vision: true receives the image. An agent without it receives a note that says how many images it cannot see, and the base prompt tells it to say so and to ask a participant that can see them. If the definition cannot be read, the agent is treated as unable to see.
What is stored
| Table | Holds |
|---|---|
collab | Title, loop breaker cap, lead slug, objective, and the archive time. |
collab_participant | The roster. Keyed by collab and agent slug. Holds the child session and the last log entry the agent has seen. |
collab_message | The append-only log. Holds the sequence number, the author, the kind, the text, the addressed slugs, the tool trace and the images. |
collab_task | The task board. |
collab_turn_cost | The cost ledger. |
The sequence number is unique for each collab, so the same number cannot be used twice in one room. Every table refers to collab and is deleted with it. Removing an agent is a soft delete, and adding it again keeps its session and its position in the log.
The tables are created by three migrations: the first adds the collab, the roster and the log; the second adds the board, the ledger and six columns; the third adds the images column.
Which agent is mid-turn, and whether the loop breaker has tripped, are computed from the log. They are not stored, so a restart cannot leave a stale state behind.
Engine methods
The engine exposes collab over ACP as twenty-three extension methods. Each method that acts on one room needs a collabId.
| Method | Purpose |
|---|---|
collab_agents | List the agents that can join. |
collab_list | List the rooms. |
collab_create | Create a room. |
collab_post | Post a human message, with optional images. |
collab_preview | Show which agents a draft message would wake, without posting it. |
collab_state | Read the roster, the log, the board, the hops, the cost totals and the live activity. |
collab_set_cap | Set the loop breaker cap. |
collab_set_concurrency | Set how many turns the room may run at once (1-4). Refused unless every member is read-only for files. |
collab_set_flavor | Set the room's flavor: discuss or council. See Flavors below. |
collab_set_lead | Set the lead. The agent must be on the roster. |
collab_set_objective | Set the standing goal. |
collab_task_add | Add a board task. |
collab_task_update | Move a task: claim, done, accept or reopen. |
collab_review | Approve or reject a task, with an optional note. |
collab_ledger | Read the cost rows and the totals. |
collab_stop | Stop the agents. |
collab_stop_agent | Stop one named agent without stopping the whole room. |
collab_redirect | Send a correction to one named agent, outside the ordinary wake rules. |
collab_archive | Close the room. |
collab_unarchive | Reopen a closed room. |
collab_rename | Retitle the room. |
collab_add_participant | Add an agent to the roster. |
collab_remove_participant | Remove an agent from the roster. |
There is no method that creates or edits an agent definition. A definition is a file, and the extension edits it directly.
A collab publishes no event. A client reads the room by calling collab_state again.
Limits
| Limit | Value |
|---|---|
| Default hop budget | 20 turns for each human message |
| Depth of a chain of asks | 3 |
| Room messages put in a brief | 10 |
| Tasks returned with the room state | 50 |
| Open tasks shown to an agent | 8 |
| Tool trace entries for each message | 20 |
| Characters in one trace summary | 120 |
| Images for each message | 4 |
| Size of one image | 2 MB |
| Characters in a live activity line | 200 |
| Characters in a live thought | 4000 |
| Ledger rows for each page | 100 |
The roster size and the length of the log are not limited. There is no timeout and no rate limit. The hop budget is the only control on how long a room runs.
The number of steps in one turn comes from the steps key of the agent definition. See Agents. A turn that hits that cap is not posted to the room.
Configure
Folds board
The Folds board is a ticket kanban over git worktrees, in the VS Code extension. A ticket is a markdown file. Starting work on it provisions a worktree and a session.
Tickets
A ticket lives at <repo>\.origami\tickets\<id>.md, with an id of t- plus six base36 characters. The frontmatter holds scalars only. Acceptance criteria are - [ ] lines under an ## Acceptance heading, and an append-only ## Log records history. A status is one of triage, todo, pending, in_progress, done, merged or closed.
Engine tools
| Tool | Purpose |
|---|---|
board_repos | List the repositories the board knows about, with a ticket count for each state. |
board_tickets | List the tickets of one repository, or read one ticket in full. |
board_create | Create a ticket. One with acceptance criteria lands in Todo; one without lands in Triage. |
board_update | Claim, comment, retitle, relabel, re-prioritise, or change the state of a ticket. |
Reading never asks. Every mutation goes through the board permission key. A bare repo of . is refused outside a git repository, so a ticket cannot land at the drive root.
The repo registry
The extension writes a cross-repo registry at ~\.origami\repos.json, with an atomic write. The board tools, and the standalone board MCP bridge, resolve a repo name against this file.
Configure
Commands
A slash command is a prompt template with a name. Four come with the engine. You can add your own.
Built-in commands
AGENTS.md setup.The registry also holds one command per MCP prompt, and one command per skill.
Write your own
Put a markdown file at <config dir>/command/<name>.md. The plural commands/ also works. A sub-folder becomes part of the name, so command/git/sync.md is /git/sync.
--- description: Summarise recent git changes agent: build --- Summarise what changed in the last $ARGUMENTS commits. Group the changes by area and name anything risky.
Frontmatter keys
The markdown body is the template. Commands can also be written as JSON under the command key of origami.json.
Arguments
- The argument text is split into words. Quoted groups stay together, and the quotes are removed.
$1,$2and so on take the words in order. The highest number in the template takes every remaining word. A missing position becomes an empty string.$ARGUMENTStakes the whole argument text, unsplit.- A template with no
$Nand no$ARGUMENTSgets the argument text added at the end. - Text inside
!`...`is run as a shell command, and the output replaces it.
The model of a command is its own model, then the model of its agent, then the model of the session.
Commands that belong to one surface
Some commands are not engine commands. They work only in the client that owns them.
- VS Code:
/firstfold,/spend,/loop,/compose. See VS Code. - Terminal:
/sessions,/models,/themesand the rest of the list in Terminal UI.
Configure
Skills
A skill is a markdown file of reusable knowledge. The model loads it when the task matches.
Where skills are found
- Every configuration directory:
skill/**/SKILL.mdandskills/**/SKILL.md. This covers.origami/skills/in the project,~/.origami/skills/, and the global configuration directory. - External directories:
.claude/skills/**/SKILL.mdand.agents/skills/**/SKILL.md, both in your home directory and in the project. - Paths listed in
skills.paths.~/is expanded. - Indexes listed in
skills.urls. The files are downloaded into the cache directory. - Skills supplied by an agent plugin.
Claude Code skills in ~/.claude/skills are not read by default. Set ORIGAMI_DISABLE_CLAUDE_CODE_SKILLS=false to read them. ORIGAMI_DISABLE_EXTERNAL_SKILLS turns off every external directory.
The file
--- name: tdd category: workflow description: Write the failing test first, then make it pass. --- # Test first Reproduce the defect in a test before you change the code...
The registry key. It is the name that the model uses, not the folder name. A file with no valid
name is skipped.Shown to the model in the skill list. A skill with no description is left out of that list.
A free grouping label. It is never checked against a list.
Everything after the frontmatter is the body. Two files with the same name produce a warning, and the last one wins.
How a skill runs
- The model calls the
skilltool with the skill name. The body then enters the conversation. - You type
/<name>. Every skill is registered as a slash command, unless a command or an MCP prompt already owns that name.
The system prompt lists only the name and the description of each permitted skill. The body is read only through the skill tool.
Limit which skills an agent may use
Skills are filtered per agent by the skill permission key. There is no permission field inside the skill file.
{
"agent": {
"reviewer": {
"permission": { "skill": { "*": "deny", "code-review": "allow" } }
}
}
}
The folder of a skill is added to the allowed external directories, so the agent can read the scripts/ and references/ beside it without a prompt.
origami debug skill lists every skill that the engine found.
Configure
Tools
A tool is a function that the model can call. Each one is subject to the permission rules.
Files and shell
| Tool | Purpose |
|---|---|
read | Read a file or a directory. |
write | Write a file. |
edit | Exact string replacement in a file. |
apply_patch | Edit files with a file-oriented diff format. |
file | Copy, move, rename, delete, and create directories. |
glob | Fast file pattern matching. |
grep | Fast content search with regular expressions. |
bash | Run a shell command, with an optional timeout. |
process | Read-only view of running processes and of listening TCP ports. |
git_diff | Show staged and unstaged changes. |
For a GPT model, apply_patch replaces edit and write.
Work and delegation
| Tool | Purpose |
|---|---|
task | Start a subagent for a complex, multi-step job. |
todowrite | Keep a task list for the session. |
skill | Load a skill into the conversation. |
question | Ask the user a question during a run. It is available in the application, CLI and ACP clients. |
session_search | Search the text of your own past sessions. |
remember | Write a durable fact, decision or gotcha to memory. |
dream | The memory-curation backend of the /dream command. |
Web, charts and the browser
| Tool | Purpose |
|---|---|
webfetch | Fetch the content of a URL. |
websearch | Search the web with the search provider of the session. |
chart | Draw a bar, line or pie chart in the chat. |
browser | Open and drive the VS Code integrated browser: navigate, screenshot, read, click, type. Other clients get an explanation instead. |
Board and messages
| Tool | Purpose |
|---|---|
board_repos | List the repositories on the Folds board, with ticket counts per state. |
board_tickets | Read the board of one repository, or one ticket in full. |
board_create | Create a ticket. With acceptance criteria it lands in Todo; without them it lands in Triage. |
board_update | Claim, comment, retitle, relabel, re-prioritise, or change the state of a ticket. |
list_agents | List the other Origami sessions on this machine that you can message. |
send_message | Send a short handoff to another session. Delivery does not block the sender. |
Tools behind a flag
ORIGAMI_EXPERIMENTAL_LSP_TOOL.ORIGAMI_EXPERIMENTAL_PLAN_MODE, in the CLI and ACP clients.ORIGAMI_EXPERIMENTAL_BACKGROUND_SUBAGENTS.ORIGAMI_EXPERIMENTAL_CODE_MODE, or the VS Code setting origami.experimentalCodeMode.experimental.tool_search.Your own tools
Put a JavaScript or TypeScript file at <config dir>/tool/<name>.ts. The plural tools/ also works. Each exported object with args, description and execute becomes a tool. The default export takes the file name; another export takes <file>_<export>.
A plugin can add tools too, and can rewrite the description and the parameters of any tool. See Plugins.
Size of tool output
Output above tool_output.max_lines (2000) or tool_output.max_bytes (51200) is written to a file, and the model receives a shorter preview with the path.
Configure
Memory
Memory is a folder of markdown files the model reads with the read tool. One index file loads every turn; every other file loads only when the model asks for it.
The layout
~/.origami/memory/ global <worktree>/.origami/memory/ project MEMORY.md the index, loaded every turn <topic>.md one topic, read on demand inbox.md facts waiting for a home
MEMORY.md holds one line for each topic: a name and a short hook. The engine appends a footer telling the model to read a topic file with the read tool before it acts on a hook. A machine with only the older flat memory.md still loads that file; the two forms are never both active.
Write to memory
The remember tool appends a dated fact to a topic file, then updates that topic's line in the index. An existing hook line is never overwritten by a new fact. Topic files grow without a size limit; length only costs tokens once the model reads that file.
/dream
The /dream command curates the store. It reads recent sessions plus the current index and topics, then stages a full proposed replacement folder for you to approve, revise or disapprove. Approving backs up the live folder first, then writes the staged files one by one.
Memory graph
The VS Code sidebar and the Full editor tab both show memory as a force-directed graph of the topic files and their wikilinks, with a live filter on title, tags and path.
Configure
Permissions
Every tool call is checked against a rule list. A rule gives one of three answers.
The three answers
When the user is asked, the possible replies are once, always and reject.
Write the rules
{
"permission": {
"bash": { "git status*": "allow", "*": "ask" },
"edit": "allow",
"webfetch": "ask",
"external_directory": { "*": "ask" }
}
}
A bare string is shorthand. "permission": "ask" means {"*": "ask"}.
The keys
These keys accept either an answer or a map of pattern to answer: read, edit, glob, grep, list, bash, task, external_directory, lsp, skill, plugin.
These keys accept an answer only: todowrite, question, webfetch, websearch, doom_loop.
Other keys are allowed. A plugin tool is addressed as plugin:<name>:<tool>.
Patterns
*matches any text.?matches one character.- Backslashes become forward slashes before the match, in both the pattern and the value.
- A pattern that ends with a space and a star also matches the bare command, so
git status *matchesgit status. - The match ignores letter case on Windows only.
- The last rule that matches wins. Key order in the file is preserved and is therefore meaningful.
The defaults
Before your rules are applied, the engine starts from this set.
| Rule | Answer |
|---|---|
* | allow |
doom_loop | ask |
external_directory | ask, except for whitelisted directories |
question, plan_enter, plan_exit | deny, then re-allowed per agent |
read of *.env and *.env.* | ask. *.env.example stays allowed. |
An agent adds its own rules on top. The plan agent denies every edit outside .origami/plans/, and allows delegation only to explore.
Approve everything
--auto approves every permission that is not explicitly denied. The command line describes it as dangerous. It works on the terminal command and on run. The setting is read live, so a change during a turn takes effect at once.
Saved answers
An answer of always is stored. In VS Code, run Origami: Reset saved permissions to clear the stored answers of the workspace.
From the environment
ORIGAMI_PERMISSION holds JSON that is merged over the permission block. Invalid JSON is skipped, with a warning.
Configure
MCP servers
A Model Context Protocol server adds tools and prompts. Origami Coder connects to local processes and to remote servers.
A local server
{
"mcp": {
"my-server": {
"type": "local",
"command": ["bun", "x", "my-mcp-server"],
"cwd": "./tools",
"environment": { "TOKEN": "{env:MY_TOKEN}" },
"enabled": true,
"timeout": 5000
}
}
}
The command and its arguments. It is a list, not one string.
A remote server
{
"mcp": {
"docs": {
"type": "remote",
"url": "https://example.com/mcp",
"headers": { "Authorization": "Bearer {env:DOCS_TOKEN}" },
"enabled": true
}
}
}
Address of the server.
false to stop OAuth detection.http://127.0.0.1:19876/mcp/oauth/callback.Manage servers
Use origami mcp add, origami mcp list, origami mcp auth, origami mcp logout and origami mcp debug <name>. In the terminal interface, /mcps turns servers on and off.
A plugin may also supply servers. Plugin servers are merged before the servers of the configuration file.
Protocol
The client targets the 2026-07-28 revision and negotiates with server/discover. A server that answers only the older initialize handshake is treated as legacy. The client identifies itself as origami.
Keep the tool list small
MCP tools are deferred by default. Each server then costs one catalog line until the model searches for it with tool_search. Change this with experimental.tool_search.
Code mode is the other option. One execute tool replaces the individual MCP tools, and the model writes a short program that calls several of them.
Configure
Themes
The terminal interface and the VS Code extension have separate theme systems.
Terminal themes
Set the theme key in tui.json, or press the theme key (<leader>t by default) to open the picker.
The built-in names are:
aura, ayu, carbonfox, catppuccin, catppuccin-frappe, catppuccin-macchiato, cobalt2, cursor, dracula, everforest, flexoki, github, gruvbox, kanagawa, lucent-orng, material, matrix, mercury, monokai, nightowl, nord, one-dark, origami, orng, osaka-jade, palenight, rosepine, solarized, synthwave84, tokyonight, vercel, vesper, zenburn.
The fallback theme is origami.
Your own theme
Put a JSON file at <config dir>/themes/<name>.json. This works in the global configuration directory and in each .origami directory.
Priority runs from low to high: built-in themes, plugin themes, your own files, then a theme generated from the terminal colours.
VS Code themes
The extension contributes five colour themes: Origami Meadow, Origami Harbour, Origami Ember, Origami Midnight and Origami Custom.
The command Origami: Toggle Theme steps through meadow, harbour, ember, midnight and custom. The setting origami.syncVsCodeTheme decides whether the editor theme follows the dashboard theme: ask, always or never.
Configure
Keybinds
The terminal interface uses a leader key. Overrides go in tui.json.
Change a binding
{
"keybinds": {
"session_new": "ctrl+t",
"app_debug": "<leader>d",
"messages_copy": "none"
}
}
The value none or false removes a binding. A comma separates alternatives. <leader> stands for the leader key. An unknown binding name is dropped, and does not stop the load.
The leader key is ctrl+x. leader_timeout sets how long the leader waits, in milliseconds. The default is 2000.
Session and application
| Name | Default | Action |
|---|---|---|
app_exit | ctrl+c,ctrl+d,<leader>q | Exit the application. |
command_list | ctrl+p | List the available commands. |
session_new | <leader>n | Create a session. |
session_list | <leader>l | List the sessions. |
session_timeline | <leader>g | Open the timeline. |
session_rename | ctrl+r | Rename the session. |
session_delete | ctrl+d | Delete the session. |
session_interrupt | escape | Interrupt the session. |
session_background | ctrl+b | Send the session to the background. |
session_compact | <leader>c | Compact the session. |
session_export | <leader>x | Export the session. |
session_quick_switch_1 … _9 | <leader>1 … <leader>9 | Switch session by number. |
status_view | <leader>s | Show the status. |
sidebar_toggle | <leader>b | Show or hide the side panel. |
editor_open | <leader>e | Open the external editor. |
theme_list | <leader>t | Switch the theme. |
tips_toggle | <leader>h | Show or hide the tips. |
Model and agent
| Name | Default | Action |
|---|---|---|
model_list | <leader>m | List the models. |
model_provider_list | ctrl+a | List the providers. |
model_favorite_toggle | ctrl+f | Mark a model as a favourite. |
model_cycle_recent | f2 | Step through the recent models. |
agent_list | <leader>a | List the agents. |
agent_cycle | tab | Step to the next agent. |
agent_cycle_reverse | shift+tab | Step to the previous agent. |
variant_cycle | ctrl+t | Step through the model variants. |
Messages and the prompt
| Name | Default | Action |
|---|---|---|
input_submit | return | Send the prompt. |
input_newline | shift+return,ctrl+return,alt+return,ctrl+j | Insert a new line. |
input_clear | ctrl+c | Clear the prompt. |
messages_page_up | pageup,ctrl+alt+b | Scroll up one page. |
messages_page_down | pagedown,ctrl+alt+f | Scroll down one page. |
messages_first | ctrl+g,home | Go to the first message. |
messages_last | ctrl+alt+g,end | Go to the last message. |
messages_copy | <leader>y | Copy a message. |
messages_undo | <leader>u | Undo the previous message. |
messages_redo | <leader>r | Redo. |
Diff viewer
| Name | Default | Action |
|---|---|---|
diff_close | escape,q | Close the viewer. |
diff_toggle | enter,space | Open or close an item. |
diff_next_hunk / diff_previous_hunk | ] / [ | Move between change blocks. |
diff_next_file / diff_previous_file | n / p | Move between files. |
diff_toggle_file_tree | b | Show or hide the file tree. |
diff_help | ? | Show the viewer help. |
VS Code has its own bindings. See VS Code.
Develop
Plugins
A plugin adds tools, providers, authentication methods, and hooks around the turn.
Load a plugin
Two ways work.
- Put a
.tsor.jsfile in<config dir>/plugin/or<config dir>/plugins/. It loads with no configuration entry. - Name it in the
pluginarray of the configuration. A relative path is read from the directory of the configuration file. Any other value is treated as an npm package name and installed.
{
"plugin": [
"./plugins/my-plugin.ts",
["some-npm-plugin", { "option": true }]
]
}
origami plugin <module> installs a plugin and writes the entry. It accepts --global and --force.
--pure or ORIGAMI_PURE starts the engine with no external plugins.
Plugins from agent-plugins.org are listed separately in agentPlugins, and managed with origami agent-plugin add and origami agent-plugin list.
Hooks
The package is @origami/plugin.
| Hook | When it runs |
|---|---|
config | The configuration is ready. |
event | An event happens. |
dispose | The plugin stops. |
tool | Declare new tools. |
auth | Add an authentication method for a provider. |
provider | Add or change provider models. |
chat.message | A new message arrives. |
chat.params | Change the parameters sent to the model. |
chat.headers | Change the request headers. |
permission.ask | Change the answer of a permission check. |
command.execute.before | Before a command runs. |
tool.execute.before | Before a tool runs. It can change the arguments. |
tool.execute.after | After a tool runs. It can change the title, output and metadata. |
tool.definition | Change the description and parameters that the model sees. |
shell.env | Change the environment of a shell call. |
Experimental hooks
The package also exports @origami/plugin/tool and @origami/plugin/tui. Terminal plugins are declared in tui.json, under plugin and plugin_enabled.
Develop
SDK and HTTP API
The SDK package starts a server and talks to it from JavaScript.
The package
The package is @origami/sdk. Its entry points are ., ./client, ./server, ./v2, ./v2/client, ./v2/server and ./v2/types.
The main entry exports createOrigamiClient, createOrigamiServer, and createOrigami, which starts a server and returns both.
import { createOrigami } from "@origami/sdk"
const { client, server } = await createOrigami()
Types from the API document
The client types are generated from the OpenAPI document. The generated document is kept in the repository, and origami generate writes it.
Handlers
The @origami/server package holds the handler groups: agent, command, credential, event, fs, health, integration, location, message, model, permission, project-copy, provider, pty, question, reference, session and skill.
The editor protocol
origami acp starts an Agent Client Protocol server. The VS Code extension uses it. Use --cwd to set the working directory.
Help
Troubleshooting
Most reports come from one of these causes.
A change does not appear
Find out which artifact holds the change. A change under packages/vscode/ needs a new extension. A change under packages/engine/ needs a new engine binary. Rebuilding one does nothing for the other.
Check what went into the engine binary:
grep -a "someSymbolYouAdded" ~/.origami/bin/origami.exe
An old engine still serves the session
A deploy replaces the binary, but a window that is already open keeps the process that it started. The extension compares the modification time of the binary at start with the time on disk now, and reports a stale engine.
Start a new session, or reload the window.
Engine edits do not take effect
Set origami.devEngineSource to the path of a packages/engine source tree. The extension then runs the engine from source with Bun, and a window reload picks up the edits. With an empty or invalid value, the compiled binary is used and a reload changes nothing. The output channel of the extension logs which one started.
The model is unreachable
The banner has four states: ok, probing, offline-local and offline-remote. The local state means that the loopback LM Studio has no model loaded. Check that the server runs, that a model is loaded, and that origami.engineUrl ends in /v1.
The context meter shows nothing
A local server often reports zero for the window size. The meter treats zero as "not known" and keeps the last real value. The extension probes the server for the true window size.
A long local request stops
A self-hosted endpoint has a default chunk timeout and header timeout of 300000 milliseconds. Raise options.chunkTimeout and options.headerTimeout in the provider block, or set them to false to remove the limit on the whole request.
The configuration file is refused
An unknown key at the top level stops the load. The message names the key. Note that theme, keybinds and tui belong in tui.json.
Print what the engine really read:
origami debug config origami debug paths
See the logs
origami --print-logs --log-level DEBUG
Turn behaviour off
Legal
Attribution
Origami Coder began as a fork of OpenCode.
Upstream project
OpenCode is the upstream project. Origami Coder started as a fork of the OpenCode repository on GitHub.
License
OpenCode is licensed under the MIT License. Its copyright notice reads:
Copyright (c) 2025 opencode