Files
b12daabe35 perf(app): row-grained replica cache persistence (#3755)
* feat(hub): guide starter setup (#3651)

* feat(hub): guide setup with provider IDs

* fix(hub): preserve login setup state

* feat(hub): select starter agent runtime

Use the connected daemon's provider snapshot so generated Hub bundles only
contain complete provider, model, and mode combinations.

* fix(hub): stage starter runtime choices

Keep providers with valid modes selectable when the daemon has no default mode, so users explicitly choose the complete runtime.

* fix(hub): scope runtime choices to workspace

Provider capabilities can vary by repository, so request the snapshot for the bundle directory that guided setup will deploy.

* fix(server): stop short start gates from undercutting provider startup budgets (#3621)

* fix(server): stop short start gates from undercutting provider startup budgets

Agent creation still failed on contended cold starts after #3578, because two
shorter gates on the same path fire before the event-stream readiness budget can
apply. A traced creation reached session.create twelve seconds in, past the 10s
session.create gate, and the agent was then killed by a bare "timeout" at fifteen
seconds from AGENT_RUN_START_TIMEOUT_MS while the SSE connect was still running.

A run-start bound of 15s wraps a path that is deliberately allowed 30s, so the
outer gate always wins and the inner budget is unreachable.

Give session.create the shared OPENCODE_SERVER_STARTUP_TIMEOUT_MS budget, since
creating the first session for a directory is part of OpenCode coming up, and
derive its error message from the constant instead of hardcoding "10s". Raise
AGENT_RUN_START_TIMEOUT_MS to 60s with a comment recording that it must stay
above the slowest provider startup budget; it stays a literal because that module
is provider-agnostic.

Related to #3571.

* test(server): drive the run start budget through a real AgentManager

The run start boundary tests replaced AgentManager.waitForAgentRunStart with a
bare timer, so they never exercised the production run-state transition or the
agent_state subscription the real wait depends on. That path could regress while
the tests stayed green.

Build the scenario on a real AgentManager with a provider session that holds its
turn start open for a configurable span, so pendingRun.started, the lifecycle
change to "running", and the agent_state notification are what the wait actually
observes. Budgets stay independent literals and the settled-before/after
assertions are unchanged.

* fix(server): describe agent run start timeouts

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>

* fix(relay): validate handshake keys (#3669)

* fix(files): keep large source previews responsive (#3665)

Large read-only files bypassed the editor's virtualization and eagerly mounted every highlighted token, which could stall the renderer for seconds and consume gigabytes of memory. Route source previews through bounded platform renderers and reject reads above their display budgets before accumulation.

* fix(hub): make guided setup choices actionable (#3677)

Show a concise login success state, scope starter choices to available Hub connections, wait for daemon capabilities, and avoid partial starter bundles when setup cannot proceed.

* Keep released agent SDK versions reproducible (#3678)

Pin the validated provider and protocol SDK dependency pair so fresh installs cannot silently float after a Paseo release. Refresh the Nix npm dependency hash for the resulting lockfile.

* feat(app): refine agent profile creation (#3680)

Keep profiles as the richer primitive while restoring the familiar star cue and clearer guidance for agent selection. Account for borders in shared field geometry so controls preserve their declared heights across form consumers.

* fix(app): restore native composer auto-growth (#3681)

Native multiline inputs were always scrollable, which kept iOS content-size measurement pinned to one line. Keep native sizing intrinsic below the cap and enable internal scrolling only after the composer reaches it.

* docs(hub): document zero-friction onboarding (#3657)

Lead with the browser-to-CLI onboarding journey, document the generated starter bundle, and align guided setup with available Hub connections and daemon-reported runtime defaults.

* Surface workspace changes from agent panes (#3682)

* feat(app): refine workspace pane actions

Prioritize Changes when available, keep Files useful before a selection, and reserve desktop diff clicks for selection so comments require the explicit affordance. Move the Changes shortcut to Shift+G to avoid consuming a likely copy variant.

* feat(app): improve access to workspace changes

* Expand workspace panel actions and keyboard navigation (#3685)

* fix(app): keep file navigation in place

Retargeting a File tab allocated a new tab identity, causing the tab track to unmount and remount during navigation. Preserve the identity for File-to-File changes while retaining new instances for cross-kind replacements.

* feat(app): expand workspace panel actions

Keep the Command Center aligned with workspace tab and pane primitives. Add explicit panel placement, focused open behavior, keyboard navigation for empty panes, and a Changes pill that toggles the visible Side panel without closing its tab.

* Restore compact and stable chat timelines (#3716)

Restore compact message and footer spacing, reserve independent composer-pill clearance for transcript content and floating controls, and keep visible web tool-call expansion from shifting the reading position.

* perf(app): defer replica persistence until user inactivity

Whole-replica capture and serialization blocked the JS thread during navigation and streaming. Defer that work until the user has been inactive while allowing long-running streams to persist without becoming the idle signal.

* Give every pane a browser-style New tab (#3715)

* feat(app): replace empty panes with New tabs

Give every retained pane an independently identified New tab, replace it in place when a destination is chosen, and preserve split close and move invariants. Keep existing workspace startup and compact explorer routing explicit, with focused unit and browser regression coverage.

* test(app): count content tabs in subagent integration

* fix(app): preserve workspace shortcut ownership

* fix(app): keep compact model options scrollable

The compact model sheet had no sheet-aware scroll owner when profiles filled its viewport, leaving the controls below them unreachable. Keep the root provider view inside Gorhom's scroll container so native sheet gestures work on both platforms.

* fix(app): order new tab launcher actions by workflow

* fix(app): show the New agent shortcut

The command center resolved New agent through the New tab binding, so it advertised Cmd+T despite creating an agent. Resolve the target-agent binding instead and cover the mapping.

* fix(app): prioritize side panel launcher actions

Lead with supporting workspace tools when the launcher is in the Side panel, while ordinary panes continue to lead with agent creation.

* fix(app): align terminal profiles header

* docs: add 0.5.0-beta.5 changelog

* test(app): align new tab launcher expectations

* chore(release): cut 0.5.0-beta.5

* fix: update lockfile signatures and Nix hash [skip ci]

* fix(app): make compact git actions menu-only

Keep compact toolbars narrow and require users to choose potentially consequential Git and workspace actions from the menu.

* fix(app): keep pinned project actions reachable (#3722)

* fix(app): keep pinned project actions reachable

Preserve an empty project shell after its final workspace is hoisted into the pinned section so project-scoped workspace creation remains available.

Co-authored-by: Agent Op <agentop718@gmail.com>

* test(app): verify pinned project workspace context

---------

Co-authored-by: Agent Op <agentop718@gmail.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>

* fix(app): stop a string SVG transform from crashing the app (#3711)

* fix(app): stop a string SVG transform from crashing the app

A root <Svg> is a real React Native view, so react-native-svg rewrites a
*string* `transform` into RN style syntax in `extractTransformSvgView`,
using a PEG parser whose grammar only accepts SVG transform functions.
Upstream lets that parser's SyntaxError escape, so any string it does not
understand takes the whole app down during render:

  SyntaxError: Expected transform functions but "n" found.
  "found": "n", "location": { "start": { "offset": 0 } }

`none` reproduces that message character for character; so does any other
CSS value (`rotate(-90deg)`, `translate(10px, 0)`). Every sibling
extractor in that file already catches the same error and degrades, so
the asymmetry is the bug: a string that is merely ignored on a <Path>
crashes on an <Svg>.

We feed that path untrusted input. The daemon scans a project for
favicon.svg / icon.svg / logo.svg (packages/server/src/utils/project-icon.ts)
and ships it to the client, where ProjectIconImage hands it to SvgCss.
Running the library's own XML parser over `<svg style="transform:none">`
yields exactly `transform: "none"` on the root, which is why the crash
starts once a host connects and the project icons render, with no
terminal involved.

Note this is *not* reachable from an RN-style array transform: the
extractor returns arrays untouched and only parses strings, so
`style={{ transform: [{ rotate: "-90deg" }] }}` (the context window meter
and the checks ring) was never a factor.

Patch the three builds a consumer can resolve - Metro takes the package's
`react-native` field (src/*.ts), Node and Vitest take main/module - and
register react-native-svg with the postinstall patch runner so the patch
actually applies. The new test pins all three.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EDwfsMWoSFfPm2cFXe5noQ

* test(app): cover parsed root SVG transforms

Exercise the dependency patch with root props produced by the library's XML and CSS parsers, including embedded style rules that can arrive through project icons. Keep dependency-patch documentation focused on the reusable install and resolution constraints.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>

* fix(pairing): warn that pairing links grant daemon access (#3734)

A pairing offer remains valid across daemon restarts, so remove the incorrect rotation guidance and warn users where the durable credential is displayed.

* fix(app): preserve timeline retry backoff (#3736)

Equivalent visibility publications were acting as implicit retry commands, so unrelated tab and layout changes could restart failed timeline work. Keep visibility identity stable and reserve immediate retries for explicit user action.

* Open the tab chooser beside the pointer (#3735)

* feat(app): open the tab chooser beside the pointer

Keep keyboard-created and empty-pane New tabs as persistent launcher surfaces, while giving pointer users an anchored chooser at the pane-local plus button. Both presentations resolve the same launch catalogue so future ordering and customization cannot drift.

* test(app): follow the anchored tab chooser

The browser helpers still searched inside the pane for persistent-launcher controls after clicking the portalled menu trigger. Exercise the menu through its own roles and stable catalogue IDs.

* fix(app): restore composer height lifecycle (#3740)

Native Fabric can omit the initial content-size callback and retain stale size after deletion. Keep the common composer surface free of platform branches while native and web adapters own their measurement mechanisms.

* fix(server): stop quota fetcher from writing provider credentials (#3442)

* fix(server): recover already-settled interrupts (#3742)

* fix(server): recover already-settled interrupts

Provider state can drift from Paseo’s tracked run. Treat an authoritative already-idle interrupt as settled and retire the captured run token so retrying can start new work without weakening ambiguous-cancellation protection.

* fix(codex): fence interruption during turn startup

Reserve foreground-start ownership before asynchronous provider setup. An interrupt can now cancel preflight before turn/start or wait for an issued start to become interruptible, preventing acknowledged cancellation from leaving unmanaged work.

* docs(changelog): prepare 0.5.0 stable release

* chore(release): cut 0.5.0

* fix: update lockfile signatures and Nix hash [skip ci]

* fix(app): stabilize native composer resizing

JavaScript height state competed with native intrinsic layout across draft and agent ownership transitions. Let native inputs own sizing and scrolling while preserving DOM measurement on web.

* docs(changelog): prepare 0.5.1 stable release

* chore(release): cut 0.5.1

* fix: update lockfile signatures and Nix hash [skip ci]

* perf(app): move replica cache validation to restore

Add an observational live measurement harness for the row-store migration baseline. Trust already-shaped cache values on persist while retaining full schema validation at the restore boundary.

* feat(app): add replica cache row store

Ship the platform storage engines behind a dark interface so the cache migration can wire them separately. Both engines share a contract, including atomic writes and destructive schema-version resets.

* feat(app): switch replica cache to row storage

Persist only changed replica entities so steady-state writes scale with the update rather than the complete cached world. Restore remains an all-or-nothing validated boundary, with whole-host byte-budget eviction.

* fix(app): harden replica row persistence

Serialize pending batches at write execution time so retries cannot overwrite newer rows or resurrect removed hosts. Reject oversized hosts before storage writes and preserve unchanged directory identities so routine reconciliation stays row-grained.

---------

Co-authored-by: BrianAguilarWasco <146237330+BrianAguilarWasco@users.noreply.github.com>
Co-authored-by: paseo-ai[bot] <266920839+paseo-ai[bot]@users.noreply.github.com>
Co-authored-by: Yuri Gui <yugui923@users.noreply.github.com>
Co-authored-by: Agent Op <agentop718@gmail.com>
Co-authored-by: Omer Cohen <639682+omercnet@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Dan Berindei <dan.berindei@gmail.com>
2026-08-24 20:45:49 +02:00

16 KiB

title, description, nav, order, category
title description nav order category
CLI Paseo CLI reference: manage projects, workspaces, agents, plugins, scripts, schedules, daemons, and permissions from your terminal. CLI 3 Getting started

CLI

The Paseo CLI lets you manage agents from your terminal. It's the same interface exposed by the daemon's API, so anything you can do in the app you can do from the command line.

Agent orchestration: You can tell coding agents to use the Paseo CLI to spawn and manage other agents. Paseo recognizes the calling agent, so CLI-created workers get the same workspace and parent defaults as MCP-created workers.

Quick reference

paseo run "fix the tests"            # Start an agent
paseo ls                             # List running agents
paseo attach <id>                    # Stream agent output
paseo send <id> "also fix linting"   # Send follow-up task
paseo logs <id>                      # View agent timeline
paseo stop <id>                      # Stop an agent

Provider diagnostics

Ask the daemon to inspect the provider environment it actually uses:

paseo provider diagnostic claude
paseo provider diagnostic codex --json
paseo provider diagnostic opencode --host devbox:6767

The diagnostic includes the configured command, daemon PATH and shell, matching binaries, resolved path, version, model count, and provider status. Use --host for a remote daemon. This is the same diagnostic shown under Settings → your host → Providers → provider → Diagnostic.

Running agents

Use paseo run to start a new agent with a task:

paseo run "implement user authentication"
paseo run --provider codex "refactor the API layer"
paseo run --background "run the focused test suite"
paseo run --new-workspace worktree --worktree-mode branch-off --new-branch feature/x --base origin/main "implement feature X"
paseo run --workspace <workspace-id> "review the current diff"
paseo run --output-schema schema.json "extract release notes"
paseo run --output-schema '{"type":"object","properties":{"summary":{"type":"string"}},"required":["summary"]}' "summarize release notes"

From a human shell, a bare paseo run creates a new local workspace for the current directory. Use --workspace <id> to add the agent to an existing workspace, or --new-workspace local|worktree to explicitly create a separate workspace for the run.

Worktree creation accepts --worktree-mode branch-off|checkout-branch|checkout-pr plus the matching --new-branch/--base, --branch, or --pr-number/--forge options. Use --worktree-slug to choose the managed directory slug.

When an existing Paseo agent runs the same command, Paseo recognizes it through PASEO_AGENT_ID. Without explicit placement, the new agent becomes its subagent in the same workspace. --workspace can place that subagent elsewhere without changing its parent.

Use --output-schema to return only matching JSON output. You can pass a schema file path or an inline JSON schema object. This mode cannot be used with --background.

By default, paseo run waits for completion. Use --background to return immediately while the agent keeps running.

Projects

Register the current directory as a project, then list the projects known to the daemon:

cd ~/dev/my-app
paseo project create
paseo project ls

Use the project ID from paseo project ls to rename, reset, or delete a project:

paseo project rename <project-id> "My app"
paseo project rename <project-id> --reset
paseo project delete <project-id>

--reset restores the name derived from the project directory. Deleting a project archives its active workspaces and removes the project from Paseo. It does not delete the project directory.

For a local daemon, paseo project create [path] defaults to the current directory and resolves relative paths on the CLI machine. When you use --host or PASEO_HOST, provide a path that the target daemon can access:

paseo project create /srv/repos/api --host devbox:6767

The remote daemon interprets that path on its own machine. See Workspaces for how projects group working directories and sessions.

Workspaces

Create a workspace independently when you want to prepare its files before starting an agent:

paseo workspace create --isolation local --path ~/dev/my-app --title main

paseo workspace create \
  --isolation worktree \
  --path ~/dev/my-app \
  --mode branch-off \
  --new-branch feature/auth \
  --worktree-slug feature-auth \
  --base origin/main

paseo workspace create \
  --isolation worktree \
  --path ~/dev/my-app \
  --mode checkout-branch \
  --branch feature/existing \
  --worktree-slug existing-copy

paseo workspace create \
  --isolation worktree \
  --path ~/dev/my-app \
  --mode checkout-pr \
  --pr-number 2186

Then list, use, rename, or archive it:

paseo workspace ls
paseo run --workspace <workspace-id> "implement authentication"
paseo workspace rename <workspace-id> "Auth rework"
paseo workspace rename <workspace-id> --reset   # back to the branch or directory name
paseo workspace archive <workspace-id>

Add --forge <name> to PR checkout when Paseo cannot infer the forge from the source checkout. See Git worktrees for setup hooks and services.

Workspace scripts

List, start, and stop the scripts configured in a workspace's paseo.json:

paseo script ls
paseo script start web
paseo script stop web

By default, Paseo selects the workspace whose directory is the current directory. Pass --cwd <path> to select a different directory, or --workspace <workspace-id> when a directory has multiple workspaces. These commands also accept --host and the standard output options such as --json.

The output includes each script's lifecycle and supervised terminal ID. Services also include their assigned port, proxy URL, and health. See Git worktrees for paseo.json configuration.

Plugins

Create and manage trusted local plugins on a daemon:

paseo plugin init /absolute/path/to/plugin
paseo plugin install /absolute/path/to/plugin
paseo plugin ls
paseo plugin reload my-plugin
paseo plugin logs my-plugin
paseo plugin disable my-plugin
paseo plugin enable my-plugin
paseo plugin remove my-plugin

paseo plugin logs <id> returns the plugin's recent daemon-side stdout and stderr. Add --json for structured entries or --host <target> for another daemon. See the Plugin reference for installation, trust, lifecycle, and log-retention behavior.

Listing agents

paseo ls                    # Running agents in current directory
paseo ls -a                 # Include completed/stopped agents
paseo ls -g                 # All directories
paseo ls -a -g --json       # Full list as JSON

Streaming output

Use paseo attach to stream an agent's output in real-time:

paseo attach abc123   # Attach to agent (Ctrl+C to detach)

Agent IDs can be shortened, abc works if it's unambiguous.

Sending messages

Send follow-up tasks to a running or idle agent:

paseo send <id> "now run the tests"
paseo send <id> --image screenshot.png "what's wrong here?"
paseo send <id> --no-wait "queue this task"

Viewing logs

paseo logs <id>                  # Full timeline
paseo logs <id> -f               # Follow (streaming)
paseo logs <id> --tail 10        # Last 10 entries
paseo logs <id> --filter tools   # Only tool calls

Waiting for agents

Block until an agent finishes its current task:

paseo wait <id>
paseo wait <id> --timeout 60   # 60 second timeout

Useful in scripts or when one agent needs to wait for another.

Schedules

Run an agent on a cron schedule. The CLI also accepts simple cadence presets and compiles them to cron. See Schedules from the CLI for the full reference.

paseo schedule create --every 30m --cwd ~/dev/my-app "Continue the refactor and leave a note."
paseo schedule ls
paseo schedule pause <id>

Permissions

Agents may request permission for certain actions. Manage these from the CLI:

paseo permit ls                # List pending requests
paseo permit allow <id>        # Allow all pending for agent
paseo permit deny <id> --all   # Deny all pending

Agent modes

Change an agent's operational mode (provider-specific):

paseo agent mode <id> --list   # Show available modes
paseo agent mode <id> bypass   # Set bypass mode
paseo agent mode <id> plan     # Set plan mode
paseo agent detach <id>        # Make a subagent top-level

Detaching is an explicit lifecycle action, not a creation flag. The agent keeps running; only its relationship to its parent changes.

Daemon management

paseo daemon start             # Start the daemon
paseo daemon start --web-ui    # Start and serve the bundled web UI
paseo daemon status            # Check status
paseo reload                    # Reload config.json (top-level alias)
paseo daemon reload             # Reload config.json
paseo daemon stop              # Stop the daemon

Reload validates the whole file, applies runtime-safe changes, and reports appliedPaths, restartRequiredPaths, and overrideControlledPaths. Human output prints paseo daemon restart only when a changed setting needs it. Use --json or --format yaml for the structured result, and --host to reload a remote daemon's own configuration file. An older host that does not support reload returns an update-host error.

Use PASEO_HOME to run multiple isolated daemon instances.

Hub

paseo hub login [url]          # Approve and store organization-scoped CLI access
paseo hub init                 # Guided setup: scaffold and deploy a starter bundle here
paseo hub connect [url]        # Enroll this daemon using CLI access
paseo hub projects             # List projects in the authenticated organization
paseo hub status               # Show the current Hub relationship
paseo hub disconnect           # End it
paseo hub deploy -p <project>  # Discover, validate, and activate a Hub bundle
paseo hub deploy -p <project> --dry-run # Validate without activating
paseo hub logout               # Remove the active stored CLI login

Run deploy from the project root. It reads .paseo/hub.yml, every direct .paseo/workflows/*.yml file, and referenced .paseo/workflows/partials/* files in deterministic path order. It does not search parents, accept an alternate resource path, or flatten the bundle into monolithic YAML.

Pass -p, --project <slug> to select the target project. --dry-run performs the same discovery and server validation without recording or activating a revision. Both outputs include the resolved Hub, project, and discovered workflow count.

login opens the Hub approval page and stores a durable organization-scoped CLI credential under PASEO_HOME. In an interactive terminal it then asks whether to connect this daemon and whether to initialize and deploy a starter workflow, both defaulting to yes. Declining the connection prints paseo hub connect <origin>; then paseo hub init, because the connection alone does not produce a bundle; declining only the starter prints paseo hub init. --json and non-TTY login remain login-only and never prompt. The stored login is separate from the daemon relationship created by connect.

init runs the same guided setup on its own and requires a TTY. It connects the daemon, uses the organization's only project or asks which one, and lists the Hub app connections that can back a starter workflow. One usable connection is selected automatically; with several, you choose a Trigger connection. If none is ready, setup sends you to Hub → Apps and stops before selecting an agent or writing files.

Setup then asks which agent provider, model, and mode the starter should run, choosing from what the connected daemon reports. A provider is offered only when the daemon has it enabled with a selectable model. Suggested model and mode entries are the daemon's defaults; no provider is suggested merely because it appears first. The mode question is skipped for providers that expose no modes and asked explicitly when the daemon has modes but no default. Finally, setup asks for the identity that gates the chosen connection: a GitHub username, a Slack member ID, or a Discord user ID. It writes .paseo/hub.yml and .paseo/workflows/<provider>-help.yml, validates them against Hub, and deploys. An existing .paseo/ directory is replaced only after you confirm. See the generated starter bundle.

Interactive logout checks the same-origin daemon relationship and asks whether to disconnect before deleting the login. Declining removes only the login. JSON and noninteractive logout never prompt or disconnect implicitly; --disconnect-daemon is the explicit automation path, and --force applies to that daemon disconnection. If a requested disconnection fails, the login is preserved.

Every command resolves and normalizes its destination before Hub or daemon work. Origin precedence is an explicit command origin or --hub, then PASEO_HUB_URL, then the active stored login origin, then the hosted default https://hub.paseo.sh. The hosted default never overrides an active login. Credential precedence is --api-key <secret>, then PASEO_HUB_API_KEY, then a stored login for the exact resolved origin. A stored credential is never sent to a different origin. API keys passed through flags or the environment are not stored.

Human output reports the resolved destination before each action. JSON output keeps stdout machine-readable and includes the normalized Hub origin. Bundle diagnostics identify paths without printing configuration contents or credentials.

See Daemons in Hub, Hub configuration, and the Hub public API.

Connecting to a remote daemon

--host accepts either a local target (host:port, a unix socket, or a Windows pipe) or a pairing offer URL, the same https://app.paseo.sh/#offer=... link the mobile app uses for QR pairing. With an offer URL the CLI connects through the Paseo relay with end-to-end encryption, so you can drive a daemon on another machine without exposing it to the network.

Get an offer URL from the daemon you want to control:

paseo daemon pair          # asks before enabling relay, then prints the QR and link
paseo daemon pair --relay  # enables relay without prompting
paseo daemon pair --json   # structured output; never prompts

Relay is off for new installations. In non-interactive or JSON mode, a disabled relay returns a RELAY_DISABLED error; pass --relay to provide explicit consent. Relay pairing is end-to-end encrypted. See Security.

Use it from anywhere:

paseo ls --host 'https://app.paseo.sh/#offer=eyJ2IjoyLC...'
paseo run --host "$OFFER_URL" "fix the failing tests"

You can also set it once via PASEO_HOST instead of passing --host on every command.

Multi-agent workflows

The CLI is designed to be used by agents themselves. You can instruct an agent to spawn sub-agents for parallel work:

# Agent A spawns Agent B and waits for it
agent_id=$(paseo run --background --quiet --title api-agent "implement the API")
paseo wait "$agent_id"
paseo logs "$agent_id" --tail 5

Because Agent A's ID is present in the environment, Agent B is created as its subagent in the same workspace unless --workspace is specified.

Simple implement + verify loop:

# Requires jq
while true; do
  paseo run --provider codex "make the tests pass" >/dev/null

  verdict=$(paseo run --provider claude --output-schema '{"type":"object","properties":{"criteria_met":{"type":"boolean"}},"required":["criteria_met"],"additionalProperties":false}' "ensure tests all pass")
  if echo "$verdict" | jq -e '.criteria_met == true' >/dev/null; then
    echo "criteria met"
    break
  fi
done

This pattern enables hierarchical task decomposition, a lead agent can break down work, delegate to specialists, and synthesize results.

Output formats

Most commands support multiple output formats for scripting:

paseo ls --json                # JSON output
paseo ls --format yaml         # YAML output
paseo ls -q                    # IDs only (quiet)

Global options

  • --host <target>, connect to a different daemon (host:port, unix socket, or https://app.paseo.sh/#offer=... for relay). See Connecting to a remote daemon.
  • --json, JSON output
  • -q, --quiet, minimal output
  • --no-color, disable colors