Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Task guides

Short, goal-shaped recipes for common jobs. Each guide points at the deeper feature pages; use those when you need full schemas or edge cases.

Related references: Hooks, Non-interactive mode, MCP, Skills, Memory, Branching, Sandbox.


Automate a check on every edit (hooks)

Goal: every time the agent finishes an edit, run a deterministic check and fail closed when it breaks.

The shipped hook model is a TypeScript module discovered under ~/.veyyon/profiles/<name>/agent/hooks/ (the active profile). Hooks are user-level only: a .veyyon/hooks/ directory inside a repository is not read. The module exports a factory that registers handlers with pi.on(...).

// ~/.veyyon/profiles/default/agent/hooks/post-edit-check.ts
export default (pi) => {
  pi.on("tool_result", async (event) => {
    if (!/^(edit|write)$/.test(event.toolName)) return;
    // run your check (spawn a test/linter); return { block, reason } from tool_call to deny
  });
};

The Bun runtime imports the module at startup; restart (or /reload-plugins) to pick up changes. See Hooks for the event names and handler contract.


Run a bounded task from a script or CI

Use veyyon --print (-p) when the trigger lives outside the agent (pre-commit, CI, entr, watchexec):

$ veyyon -p \
    "Run the focused tests for the files changed in the last commit and fail if any regress"

The prompt can be an argument or piped on stdin. Leave the rung alone unless you have a reason to move it: the default auto auto-approves every tier, while a target outside the working directory, a call that spends a stored credential, a per-tool prompt/deny policy, and a critical command such as a recursive delete of your home directory all still ask, and a headless run has no terminal to ask on, so each of those becomes a failed tool call rather than a silent pass. Do NOT pass --approval-mode ask-command here: it prompts for every exec-tier call, which in -p means every command fails. --yolo auto-approves all tiers and drops the two boundaries (use only on disposable runners). JSON event streams: --mode json. For review, pass a review prompt to -p, or use the passive advisor (--advisor) in the TUI. See Non-interactive mode.


Give the agent a new tool (MCP or skills)

Goal: teach Veyyon a capability you do not want to bake into the binary.

Choose the surface

NeedUse
Talk to an external system (DB, SaaS, browser bridge) over a protocolMCP server
Package reusable instructions, scripts, and examples as dataSkill (SKILL.md)

Path 1: add an MCP server

Add it from the TUI, which writes mcp.json for you:

/mcp add

Or edit ~/.veyyon/profiles/default/agent/mcp.json directly (the active profile’s file; there is no project scope):

{
  "mcpServers": {
    "database": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/db-mcp-server/index.js"],
      "env": { "DB_PATH": "/var/data/app.db" }
    }
  }
}

Confirm discovery with /mcp (or /mcp list), then ask the agent to use the new tool by name. If the server needs OAuth, run /mcp reauth <name>. Details: MCP, MCP setup.

Path 2: author a skill

Create a skill directory under the active profile, for example ~/.veyyon/profiles/default/agent/skills/audit-config/SKILL.md:

---
name: audit-config
description: Audit Veyyon config.yml for unsafe approval and tool-policy combinations.
metadata:
  short-description: Config safety audit
---

# Audit config

When asked to audit configuration:
1. Read the active config.yml.
2. Flag `yolo` approval paired with broad tool allow-lists on untrusted repos.
3. Prefer concrete remediations over generic advice.

Restart or open a new session so skill discovery picks it up. Skills are data, you can version them in git and share them without shipping a new veyyon build. Prefer a skill when the “tool” is mostly prompting and local scripts; prefer MCP when the capability is a long-lived external process. See Skills.


Share context across sessions (memory and branching)

Goal: keep decisions, conventions, and alternate explorations available without pasting transcripts by hand.

Memory: carry guidance into new threads

Cross-session memory is off by default. Turn on a backend with memory.backend in config.yml:

# ~/.veyyon/profiles/default/agent/config.yml
memory:
  backend: mnemopi        # off (default), local, hindsight, mnemopi

Operate it from the TUI with /memory (/memory stats, /memory diagnose). Keep memory on for repos where conventions matter; leave it off for throwaway scratch sessions. See Memory.

Branching: explore without losing the main line

Use the session tree when you need parallel context inside one problem.

IntentCommand
Inspect the tree / jump to a prior turn/tree
Copy history into a new session from a user message/branch

Typical flow: reach a decision point, /branch to try an alternate approach, continue on the branch that works. Full behavior: Branching and Sessions.

Memory vs branching

  • Memory stores durable facts across sessions when a backend is enabled.
  • Branching forks live transcript context for the current problem.
  • Branch to explore; use memory for decisions that should outlive one session.

Track long work without repeated reminder walls

Use the todo tool for work that has several independent steps. The session stores every phase, task, and status. Compaction and handoff keep that complete structured state, including plans with dozens of items.

When the model tries to finish with open work, Veyyon injects one continuation instruction for that exact todo state. The instruction states to continue, puts the active task first, shows at most five open items, and reports how many more remain hidden. It does not replay an unchanged state after a user says continue or after an unrelated tool call. A real todo change makes the new state eligible for one reminder, up to the configured limit.

Model-facing todo output and the collapsed TUI use the same sanitized, width-bounded, active-first projection of at most five items. The complete phases, tasks, and statuses remain in machine state. To clear that state intentionally, run /todo rm without a task or phase; completing or dropping items keeps their closed history until it is explicitly removed.

The anchored Todos block above the composer is a railed list. Every phase gets one row with its tally, so a stage that just closed three tasks does not look like one that has done nothing, and task rows are drawn for the phase being worked and the few after it. The block is bounded by the viewport: it never grows past a third of the terminal’s height, it drops finished phases from the top before it drops work in flight, and it states how many rows it withheld. Expanding it shows every task of the phases it draws, not an unbounded list — an anchored region that outgrows the screen cannot be scrolled away from.

Each row’s glyph is its state, before any colour: waiting, a breathing cell in flight, done, abandoned. A task a detached subagent picked up breathes in that agent’s own accent and names the agent at the right, which is the same hue its lane carries in the Subagents block. Light travels down the rail while anything on the board is in flight and the rail is flat while nothing is, so a board waiting on you is distinguishable from a board being worked. A task closing sweeps a strike across its text, exhales its glyph and cools from green to grey; when the last task closes, the whole block makes one pass down its rail and clears. Where display.transitions is off, all of that is still and the glyphs are static. Configure the behavior under Settings → Tools → Todos:

  • Todo Reminders enables continuation instructions for unfinished plans.
  • Todo Reminder Limit caps distinct todo-state reminders before reminders stay silent.

See also