Skip to main content

More

Tips & Tricks

Techniques that are in the product but not on the surface: what the composer does with an @ reference, how to move context from a chat into a code session, why a chat session can suddenly write files, and which knobs actually change how a stuck run behaves. Everything here is behaviour the app implements today - where a thing does not exist, this page says so rather than leaving you to guess.

Ctrl shortcuts still fire while you are typing

The global shortcut handler skips bare keys when focus is in a text field, but it does not skip modified ones. So Ctrl+1, Ctrl+2, Ctrl+K, Ctrl+Shift+P and the rest work mid-sentence in the composer - you never have to click out first. Esc is special-cased and always runs, wherever focus is.

Esc dismisses a fixed stack, topmost first: command palette → quick file open → go-to-line → the shortcuts overlay → project quick-switch → context inspector → the secondary panel. Pressing it repeatedly walks you back out of nested UI in that exact order, so it is a reliable "get me back to the editor" key.

Two shortcuts worth knowing that are easy to miss:

  • Ctrl+Alt+1Ctrl+Alt+9 jumps straight to fleet session 1–9. It is Alt-based on purpose, so it does not collide with the Ctrl+1 / Ctrl+2 mode switch, and it works from either mode.
  • Ctrl+Shift+K (fix selected code) is guarded on having a live editor selection. With no selection it silently does nothing - it is not broken, it has nothing to act on.

Ctrl+/ opens the full shortcut list at any time.

@ references: what actually gets attached

Typing @ in the composer opens a picker. What happens on select depends on the kind of thing you picked, and the difference matters:

You pick What the model receives
A file (open tab or project file) The file's contents, attached to the message. The token in your text is rewritten to @<fileName> - the model is not being handed a path to go read.
@codebase A pseudo-attachment listing the project file tree - the first 500 paths. A map, not the code.
@memory A pseudo-attachment with the first 50 memory entries, each truncated to 200 characters.
@agent, @research, @debug, @advisor Nothing. Selecting one switches panel and strips the token from your input.

That last row is the non-obvious one: the @ menu doubles as a panel switcher even though it looks like a file picker.

Navigation is /, Enter or Tab to select, Esc to dismiss, and the list is capped at 12 results. The @ trigger is suppressed when the input starts with /, so slash commands and mentions never fight each other.

Not available, so do not plan around them: folder references, symbol references, agent references, and session references. Only files, the two context injections, the four panels, and @code-session (below) are offered.

Hand context from a code session into a chat

There is no "convert this chat into a code session" button. The handoff that does exist is @code-session, and it runs the other direction - it pulls the active code session's recent conversation into whatever session you are typing in.

How it behaves:

  • The menu entry only appears when there is an active code session and it is not the session you are already in.
  • On select it fetches that session's last 20 messages, truncates each to 300 characters, and builds one block labelled with its origin (From Code Mode (session N, using context up to message M)), so the model can tell borrowed context from the current thread.
  • The block is consume-once and session-bound. It rides your very next message to that same session and is then gone. It does not persist, and it will not follow you to a different session.

Use it when a code run has established facts you now want to reason about conversationally - after a failed build, say - without pasting a wall of log text.

Attaching a folder to a chat session changes what the agent can do

This is the single highest-leverage thing on this page. A chat session with no project folder runs on the chat tool set: search, fetch, memory, knowledge, documents, and read-only file access. Write paths are blocked.

Attach a folder and the guard layer opens up: str_replace becomes callable, and the file_system write, delete, create, append, rename and mkdir operations stop being refused. The model does not announce this - the same request that produced "I can't modify files" ten minutes ago will start editing.

Three ways to attach:

  1. The + dropdown in the composer → Add to project folder (it will create a session for you if none exists). The red Remove folder row appears in the same menu once a path is set.
  2. Right-click a session in the chat sidebar → Link project folder / Change project folder, with Remove project folder alongside it.
  3. In Code Mode, opening a folder attaches it as part of creating the session.

Note that "Add to project" in that right-click menu is a different thing - it files the session under a project grouping and does not give the agent a filesystem root.

The same + dropdown also carries Context Scope (Auto / Current File / Selection / Codebase) and Add knowledge from URL.

Chat Mode or Code Mode

The honest split is tool surface, not intelligence.

Chat Mode runs a fixed allowlist - web search and fetch, memory and knowledge, document creation, deep research, docs lookup, the read-side file tools (file_system, grep, glob, code_search, find_symbol), session lookup, and the preview tools. No shell, no run_tests, no diagnostics. Pick it when the answer is the deliverable: research, design discussion, reading an unfamiliar repo, drafting a document.

Code Mode gets the full registered tool set - shell, test running, diagnostics, editing - plus the editor, the file tree, the four AI panels and the terminal. Pick it when files have to change and the result has to be checked.

Two practical consequences:

  • A question that needs one command run is a Code Mode question, even if it feels conversational.
  • A long research thread stays cheaper and more focused in Chat Mode, and you can bring its conclusion into code work with @code-session from the code side.

The routing pill tells you the decision before you send

With the tier pill on Auto, it previews the outcome as you type: →<rule name> when one of your routing rules would catch the message, →pattern when a classifier pattern would, and →Fast / →Smart / →Code when it is falling through to the built-in classifier. Read it before pressing Enter rather than reading the routed-by line afterwards.

Pinning is separate from the pill. Picking a model in the model picker pins it; clearing the pin means selecting the empty entry in that picker, which also clears the provider. The pin resets on its own when you switch sessions. While a model is pinned - or the tier pill is off Auto - the classifier short-circuits and does not run at all.

If the tier dropdown is missing entirely, that is deliberate: with a single-active-model provider such as llama.cpp or LM Studio every tier resolves to the one loaded model, so the control is hidden instead of lying to you.

The other two pills: Research toggles the research path, and Web toggles web search - the Web pill is hidden outright in air-gap mode.

Slash commands in the composer

Command What it does
/goal <text> Sets a persistent session goal - and auto-submits it, starting the agent. /goal alone shows the current goal, /goal clear removes it.
/mode ask|plan|act Switches permission mode without reaching for the pill.
/compact Summarises the conversation server-side and reports how many messages were folded.
/export Exports the conversation as Markdown via a save dialog. Chat Mode only.
/preview [url] With no argument, reopens the last preview URL or offers a port picker (3000 / 5173 / 8080 / 4200). With one, opens that URL.
/browser Opens the Agent Browser panel.
/sidechat Opens the docked Sidechat for the active code session. Refuses in Chat Mode.
/map Opens the Codebase Map.
/clear Clears the composer input.
/help Lists every command.

Installed skills add their own /name triggers, and those pass through to the backend rather than being handled in the UI. The command menu refetches the skill list every time it opens, so a skill you just installed shows up without a restart.

One behaviour to know: an unrecognised slash command is swallowed by the composer and answered with a "Commands: …" toast. It never reaches the model. If you meant to say something starting with a slash, put a character in front of it.

Steer a run without stopping it

While the agent is running, Enter in the composer queues your message as a follow-up instead of sending it immediately. You can line up a correction - "stop refactoring, just fix the test" - and it lands at the next turn boundary rather than after a hard stop and a cold restart.

Stopping is a button, in the composer, and there is deliberately no keyboard shortcut for it. Do not go hunting for one.

Tab accepts the ghost-text suggestion in the composer. Ghost text is disabled in the compact panel composer, so if you never see it, check which surface you are typing into.

When a local model gets stuck

In order of what actually helps:

  1. Queue a correction rather than stopping (above). A stuck model is usually one nudge from unstuck, and a restart throws away its context.
  2. /compact. Manual compaction summarises the thread and frees window. Automatic compaction already fires at llm.auto_compact_threshold, default 75 percent of the context window - if you routinely hit it late, lower it.
  3. Check the iteration cap. agent.max_iterations in Settings → Agent defaults to 50. When you set it explicitly it outranks the per-tier cap that routing would otherwise apply, so a value you set is the value in force. A custom agent's own iteration limit overrides both.
  4. Watch the Debug panel. Nudge decisions and firings surface there as nudge_decision / nudge_fired entries with a count badge, and the live Debug console shows them as they happen. This is the fastest way to tell "the model is thinking" from "the harness is fighting it".
  5. Suspect the tool surface before the model. See the next block - a small model is not shown the same tools you are reading about.

No user-facing knobs exist for loop detection, degeneration thresholds, no-progress caps, or verification retries. Those are derived per-lane in code and are not in Settings. If a page or a habit tells you to tune them, it is wrong. Per-model sampling penalties (repeatPenalty, repeatLastN) do exist, on Ollama only, in the model parameter blob.

Small models are shown fewer tools than large ones

Two reductions run automatically and neither is announced in the conversation, which makes them a common source of "why did it not just run the tests".

Size class. A model under roughly 30B parameters, outside Chat Mode, is offered a reduced set: file_system, str_replace, grep, glob, shell, save_memory, query_memory, todo_write, and query_docs. Everything else is filtered out of both the tool array and the prompt listing. Accuracy goes up; reach goes down. If you need a small model to run tests or read diagnostics, ask it to do so via shell rather than waiting for it to reach for a tool it cannot see.

Deferred tool loading. Controlled by the setting key agent.deferred_tools, default local-only - active for local providers, inactive for cloud ones. When active, the tool array shrinks to a core set (code_search, discover_tools, file_system, find_symbol, get_diagnostics, glob, grep, query_memory, run_tests, save_memory, shell, str_replace, todo_write, use_tool, web_search) and everything else is paged in on demand: the model calls discover_tools to read a schema, then use_tool to invoke it. The point is window, not capability - the base tool-schema cost drops substantially, which is what makes a 32K local context workable. Values are off, local-only, all; it is a global setting and cannot be set from a project's config.

Off by default and invisible until enabled: consult_mixture (mixture.consult_tool_enabled) and delegate_subtask (mixture.delegate_tool_enabled). Air-gap mode removes web_search and web_fetch outright.

Narrow what a custom agent may touch

A custom agent carries a tool allowlist - checkboxes, one per tool, in Settings → Custom Agents. The summary line on the agent card reads either all tools or N tools.

The semantics are worth being precise about:

  • An empty allowlist means no extra narrowing, not "no tools". If you want a read-only agent, tick the read tools; do not leave the list empty.
  • The effective set is the intersection of the panel's allowlist and the agent's. A custom agent can only ever narrow what the surrounding panel already permits - it can never widen it.
  • Enforcement is at the pre-execution guard, before a tool runs. The filtered tool list the model is shown is defence in depth, not the boundary; a model that hallucinates a forbidden tool call is still refused.
  • There is no denylist field on a custom agent. Denylists exist elsewhere - the --deny-tools request option and a skill's forbidden_tools policy - but not here.

The prebuilt agent templates each ship a narrowed allowlist, so they are a faster starting point than an empty form. Agents can be exported and imported, which is how you move one between machines or share it with a teammate.

Make verification-heavy work behave

The QEL controls that change how hard the agent checks itself all live in Settings → AI Behavior → QEL. Defaults in brackets:

  • qel.execution_proofs [on] and qel.modification_proofs [on] - the cheap structural checks. Leave them on.
  • qel.semantic_judge [off] with qel.judge_model and qel.judge_can_veto [on] - a second model reads the change for intent. The veto flag is what makes it a gate rather than a comment.
  • qel.answer_judge [off] and qel.grader_model - grades answers rather than diffs.
  • qel.code_review [off] and qel.code_review_model (empty = the generating model reviews itself, which is the weaker setup - name a different model).
  • qel.contract_review [off], qel.contract_review_model, and the band qel.contract_review_band_low [55] / _high [90].
  • qel.tsgo [off].

Outside QEL: agent.auto_verify [on] with agent.verify_command decides whether a run ends by executing your own check, and agent.test_first_repair shapes repair order. If you have a fast test command, setting agent.verify_command does more for correctness than any judge model.

Costing this correctly matters - every judge is another model call. Turning on semantic judge, answer judge, code review and contract review together will roughly quadruple the verification spend on each run.

Four ways to get a session out of the app

Right-click any session in the chat sidebar:

  • Export as Markdown - a .md of the conversation: user, assistant (with model tag) and system turns, timestamps, and an export date line. Tool messages are not included.
  • Export as web page - one self-contained .html with inline CSS, no network requests, fenced code blocks rendered as pre/code. Good for sending someone a readable transcript.
  • Export self-hostable viewer - an .html viewer with a versioned JSON bundle embedded in it, including extended-thinking text where present. It can also load a bundle from a same-origin relative URL, so you can host many transcripts against one viewer.
  • Export bug report - a .json repro bundle for filing an issue. This is the only one that is redacted: message content is truncated to 300-character previews (200 for tool calls), the credential patterns are replaced with [REDACTED], and home-directory paths become [PATH]. It carries app version, platform, provider, model, context window and air-gap state.

The first three are not redacted. They contain your full conversation text verbatim. Read before you send.

The same menu has Archive, which hides a session from the list without deleting anything. Archived sessions are excluded from search.

Keyboard shortcuts

KeysAction
Ctrl+Alt+1..9Jump to fleet session 1–9 (works from either mode)
Ctrl+Shift+KFix selected code - needs a live editor selection
Ctrl+Shift+IBodega Panel → Context tab
Ctrl+Shift+DCode: Changes panel · Chat: Context Inspector
Ctrl+Shift+WClose the active fleet session
Ctrl+Alt+FFind and replace in the editor (not Ctrl+H)
TabAccept the ghost-text suggestion in the composer
Enter (while running)Queue a follow-up instead of sending
EscDismiss the topmost overlay; repeat to walk back out

This page mirrors the in-app docs hub for app version 1.0.0-beta.35.1. Found something unclear or out of date? Tell us on Discord. New here? Download the free beta and follow along.