The plugin custom.skills.auto-load adds named skills to the system prompts of main sessions. It removes those skills from available_skills. Configure it with { "plugins": [{ "package": "custom.skills.auto-load", "options": { "skills": ["a", "b"] } }] }.
A plugins config entry enables a builtin plugin when its package is the plugin id. The entry passes options to the plugin. Wildcard entries (custom.*) pass no options.
Only ci runs on this fork. After you merge upstream, run make disable-workflows. It disables all other workflows.
The fork removed .opencode/tool/github-pr-search.ts and github-triage.ts. These tools use the v1 style (import { tool } from "@opencode/plugin"). They fail to load on v2 and break every prompt run in this repo.
ci.yml is the only workflow of the fork. It checks pull requests and pushes to dev. On a push to dev, it builds the CLI and publishes a datever GitHub Release.
make build-singlebuilds the single-fileopencodebinary.make generateregenerates the protocol, the client, and the docs.make testsruns the tests of the fork.make git-setupregisters the merge drivers (see Migration Merge Drivers).
The merge drivers in packages/core/script/merge-driver.ts resolve migration.gen.ts and schema.json. They apply when upstream adds a migration next to the migration of the fork. Run make git-setup one time in each clone.
ctrl+return (prompt_interrupt_submit) stops the active run and submits the prompt as a new run. It needs the kitty keyboard protocol. It no longer inserts a newline.
Click an MCP in the sidebar to enable or disable it. A connection in progress has the status pending (upstream renamed connecting to pending). The web UI still shows "connecting". V1 servers that send connecting become pending when the config loads.
ctrl+s stashes the current prompt. ctrl+shift+s restores the last stashed prompt.
Terminal titles of sessions and plugins show the plain title or id. They have no OC | prefix.
The TUI highlights commands of the bash and shell tools with tree-sitter bash. The $ marker renders separately, so the shell grammar sees only the command.
Each provider has a stable theme color in the model picker and in the prompt footer.
The cli.json setting model_keywords holds case-insensitive regexes. The TUI colors the matching text in model names in the model picker and in the prompt footer.
The model picker shows a Free footer for each model with cost.input === 0. This applies to all providers, not only opencode.
Tab selects the next agent. Shift+Tab selects the previous agent. A colored list of agents shows for a short time. Click an agent in the list to select it.
The plugins custom.shell.timeouts and custom.timeouts (TUI) remove the default timeout of foreground shell commands. The default timeout returns only after you toggle /timeouts for the session. A timeout set on a call still applies. Background calls are not affected. The contract is in packages/schema/src/custom-timeouts.ts.
The plugin custom.tool.subagent.resume starts a new subagent when the sessionID is not a child of the current session. Before, the call failed.
Session tabs are vertical by default in the TUI (tabs.layout) and in the desktop app (appearance.tabLayout).
In the expanded vertical rail, a long tab title wraps onto more rows, and the tab grows to fit. The compact rail and the project line crop the text.
In the expanded vertical rail, hover over an idle tab to change its • to ✕. Click the ✕ to close the tab. Horizontal tabs keep the close button of upstream.
The expanded vertical rail groups tabs under project headers. It nests child sessions under their parent tab. You cannot reorder tabs by hand while tabs.layout is vertical.
In the expanded vertical rail, a tab shows a second line only when it has a worktree branch. Tabs of one project group have no gap between them. Idle tabs show •.
The vertical tab subtree lists these sessions, oldest first by time.created:
- unresolved children (running, pending, permission, or question)
- the child that you view
- the ancestors of these sessions
The subagent picker lists all children, oldest first by time.created.
Drag down the line numbers of an edit, patch, or write block in the chat to select lines, as on GitHub. The TUI sends a comment on the selected lines to the session as a prompt.
When you click a message, Message Actions does not show Jump to. The timeline still shows it.
On terminals that are 128 columns or wider, the session list (<leader>l) previews the latest messages of the highlighted session.
The plugin custom.session.retitle writes a new title for a top-level session from the compaction summary. It runs after each compaction. It does not run when you renamed the session by hand.
Type /skill-id to mention a skill. The / menu in the TUI and in the app composer completes it. This replaces @skill-id. @ still mentions files, agents, and references.
Click a markdown link to a directory (the path ends with /, for example [core](packages/core/)). The TUI copies the absolute path and runs smerge on it. If the path does not exist, the TUI shows an error toast.
The plugins custom.context and custom.sidebar.context (TUI) fill the sidebar. It lists the instruction files and skills that the session loaded. It also lists one collapsible node for each session root. Click a root to copy its path.
The plugins custom.pull-requests and custom.sidebar.pull-requests (TUI) fill the sidebar. It lists the pull requests that the chat links, as owner/repo#n. Click an entry to open it. The plugin option hosts adds enterprise hosts.
The cancel tool stops a background shell or subagent that the agent started. The agent passes the shell ID or the sessionID from the result of the background: true call. The result names this id. The tool refuses jobs that belong to another session.
The plugin custom.tool.cancel-hints tells the model to use cancel. It adds this to the shell tool description and to the background results.
A session has one working directory. It can also have roots: extra directories that are in scope like the working directory. Access to a root needs no external_directory approval.
- Models add and remove roots with
session_root_addandsession_root_remove(plugincustom.session.roots). The API path is/api/session/:sessionID/root. - The instruction files and skills of a root load into the context of the session.
- Session move is the move of upstream. It works with roots.
session.forkalso accepts an optionaldirectory. - In the TUI workspaces dialog,
ctrl+mmoves the session.ctrl+yadds a root.
The plugin custom.tool.session-move.disable hides the session_move tool from models. Users can still move sessions.
InstructionDiscovery.filenames lists the instruction files that load automatically: AGENTS.md, CLAUDE.local.md, AGENTS.local.md, and PATCH.md. The walk at startup and the walk at read time use this list.