Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Emanuele-web04/synara/llms.txt

Use this file to discover all available pages before exploring further.

Synara ships a full terminal emulator directly inside the app. It uses node-pty for PTY process management and @xterm/headless for output tracking, giving you a real shell — not a simulated one — that runs alongside your agent threads. You can split it, send output to the active agent, run project scripts, and close it, all without leaving Synara.

How the terminal works

Each Synara thread can have one or more terminal sessions attached to it. Sessions are identified by a terminalId scoped to the thread:
// From terminal.ts
export const TerminalSessionSnapshot = Schema.Struct({
  threadId: Schema.String.check(Schema.isNonEmpty()),
  terminalId: Schema.String.check(Schema.isNonEmpty()),
  cwd: Schema.String.check(Schema.isNonEmpty()),
  status: TerminalSessionStatus,
  pid: Schema.NullOr(Schema.Int.check(Schema.isGreaterThan(0))),
  history: Schema.String,
  exitCode: Schema.NullOr(Schema.Int),
  exitSignal: Schema.NullOr(Schema.Int),
  updatedAt: Schema.String,
});

export const TerminalSessionStatus = Schema.Literals([
  "starting",
  "running",
  "exited",
  "error",
]);
Opening a terminal passes the working directory, initial dimensions, and optional environment overrides:
export const TerminalOpenInput = Schema.Struct({
  threadId: TrimmedNonEmptyString,
  terminalId: TerminalIdWithDefaultSchema,
  cwd: TrimmedNonEmptyString,
  cols: Schema.optional(TerminalColsSchema),   // 20–2000 columns
  rows: Schema.optional(TerminalRowsSchema),   // 5–1000 rows
  env: Schema.optional(TerminalEnvSchema),
  streamOutput: Schema.optional(Schema.Boolean),
});
The streamOutput flag controls whether live output events are broadcast to the UI. Setting it to false lets you run a background process (like a dev server) without flooding the terminal panel.

Creating, splitting, and closing terminals

1

Toggle the terminal panel

Press mod+j (Cmd+J on macOS, Ctrl+J on Windows/Linux) to open or close the terminal drawer. If no terminal session exists yet, Synara creates one in the project’s root directory.
2

Split the terminal

With the terminal focused, press mod+d to split the current pane. The new pane opens in the same working directory. You can run different processes side-by-side — for example, one for bun run dev and another for running tests.
3

Open a new terminal in a different pane

Press mod+n while the terminal is focused to open a brand-new terminal session inside the terminal panel.
4

Close the focused terminal

Press mod+w while the terminal is focused to close and kill the active pane. Closing the last pane hides the terminal drawer.

Default terminal keybindings

These are the built-in defaults. All bindings can be overridden in ~/.dpcode/userdata/keybindings.json. See Keybindings for the full configuration reference.
BindingCommandCondition
mod+jterminal.toggleAny focus
mod+dterminal.splitterminalFocus
mod+nterminal.newterminalFocus
mod+wterminal.closeterminalFocus
mod resolves to Cmd on macOS and Ctrl on Windows and Linux. The terminalFocus condition means the binding only fires when the terminal pane has keyboard focus, preventing conflicts with the chat composer.

Workspace layout: chat alongside terminal

The terminal integrates into the workspace layout system. You can display the terminal in a split panel next to the agent chat, giving you both surfaces at the same time. Layouts are stored per-thread so each thread remembers whether you preferred a split view or a standalone terminal. Two common configurations:
  • Chat + terminal split ("both"): Agent chat on the left, terminal on the right. Use this when you want to run commands and immediately discuss the output with the agent.
  • Terminal only ("terminal-only"): Full-width terminal with no chat panel visible. Useful for a terminal-first thread where you are running a dev server or build process and do not need the chat pane in the way.

Sharing terminal output as agent context

You can select output from the terminal and send it directly to the active agent thread as a context block. The selected text is wrapped in a <terminal_context> block:
<terminal_context>
Error: Cannot find module 'pg'
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
    ...
</terminal_context>
The agent receives this block inline with your message. This is the fastest way to show an agent a build error, a failing test, or unexpected runtime output without copying and pasting.
Use terminal context to let agents see test results, build errors, or runtime logs directly. An agent that can read npm test output can often diagnose and fix the failing test without any additional explanation from you.
Terminal contexts are tracked as TerminalContextDraft objects with a threadId, a terminalId, and the selected text. They expire when the terminal session they came from exits, so Synara will warn you before sending if the originating session has closed.

Running project scripts from Synara

Projects can define named scripts that appear in the UI and can be triggered with a keybinding. Each script is defined in the project settings:
// From orchestration.ts
export const ProjectScript = Schema.Struct({
  id: TrimmedNonEmptyString,
  name: TrimmedNonEmptyString,
  command: TrimmedNonEmptyString,
  icon: ProjectScriptIcon,           // "play" | "test" | "lint" | "configure" | "build" | "debug"
  runOnWorktreeCreate: Schema.Boolean,
});
Scripts with runOnWorktreeCreate: true run automatically when Synara creates a new worktree for a thread — useful for bun install or npm ci so the worktree is ready before the agent starts writing code. Defined scripts are accessible from the project scripts panel and via the keybinding pattern script.{id}.run — for example, script.test.run to run the script whose id is "test". You can bind these in keybindings.json:
[
  { "key": "mod+shift+r", "command": "script.test.run" }
]

Terminal event stream

Synara’s server broadcasts terminal activity as a typed event stream. The event union covers the full lifecycle:
export const TerminalEvent = Schema.Union([
  TerminalStartedEvent,    // session opened, includes snapshot
  TerminalOutputEvent,     // incremental PTY output
  TerminalExitedEvent,     // process exited with code/signal
  TerminalErrorEvent,      // session error with message
  TerminalClearedEvent,    // terminal buffer cleared
  TerminalRestartedEvent,  // session restarted, includes new snapshot
  TerminalActivityEvent,   // subprocess / CLI state changes
]);
The TerminalActivityEvent carries real-time state about subprocesses running inside the shell, including whether a codex or claude CLI is active inside the terminal and whether it is in a "running", "attention", or "review" state. This is how Synara decorates the terminal tab with live status indicators.
  • Parallel Agents — running multiple threads and monitoring them from the Kanban board
  • Keybindings — customising terminal keybindings
  • Git Workflow — branching, commits, and PRs from inside Synara

Build docs developers (and LLMs) love