Agent CLI

From a CrispyVibe terminal, AI agents can use the crispy CLI to open files, manage terminals, work with the Shelf and browser previews, and create or run Automation: Skills, Vibes, Vibe Lanes, and Schedules.

Environment discovery

Every terminal launched inside CrispyVibe has these environment variables set automatically:

VariablePurpose
CRISPY_SOCKETUnix socket path for IPC
CRISPY_CONTEXTCurrent context identifier
CRISPY_VIBESPACEActive VibeSpace ID
CRISPY_PROJECT_PATHRoot path of the current project

The app’s Resources/bin directory is added to PATH automatically, making the crispy command available without additional setup.

Check if running inside CrispyVibe

test -n "$CRISPY_SOCKET"

Commands

ping

Verify connectivity to the IDE.

crispy ping

whoami

Return information about the current context, VibeSpace, and project.

crispy whoami

help

Browse the available command categories, one category’s commands, or a single method’s schema. See Help for examples.

terminal

Manage terminals programmatically.

crispy terminal create [--cwd <absolute-path>] [--name <title>]
crispy terminal send "<text>" --terminal-id <id> [--submit]
crispy terminal send-key <key> --terminal-id <id>
crispy terminal wait --text "<substring>" [--timeout <seconds>] [--terminal-id <id>]
crispy terminal wait --exit [--timeout <seconds>] [--terminal-id <id>]
crispy terminal list
crispy terminal close --terminal-id <id>

terminal wait accepts exactly one condition: --text or --exit. Its timeout defaults to 30 seconds and accepts values from 1 through 600.

file

Open files in the content viewer.

crispy file open <path> [--line <line>] [--column <column>]

shelf

Manage Shelf entries.

crispy shelf add <path> [--select]
crispy shelf list
crispy shelf remove <path>

browser

Control the built-in browser with CSS selectors.

crispy browser open [<url>]
crispy browser list [--query <text>] [--scope project|vibespace]
crispy browser close <browser-id>
crispy browser snapshot <browser-id> [--max-depth <depth>]
crispy browser click <browser-id> --selector <css>
crispy browser type <browser-id> --selector <css> --text <text>
crispy browser fill <browser-id> --selector <css> --text <text>
crispy browser wait <browser-id> [--selector <css>] [--text <text>] [--url-contains <text>] [--timeout <milliseconds>]
crispy browser eval <browser-id> <script>
crispy browser screenshot <browser-id> [--full-page]

💡 Tip: Add --json to crispy browser snapshot <browser-id> for structured output, then use CSS selectors with click, type, or fill.

vibespace

Manage the project lifecycle in the focused VibeSpace.

crispy vibespace add-project <path>
crispy vibespace list-projects
crispy vibespace activate-project <path>
crispy vibespace park-project <path>
crispy vibespace remove-project <path>

todo

Create and manage Quick Todos and their threads.

crispy todo add "<title>" [--body <body>] [--project <path>] [--color <tag>]
crispy todo list --status active
crispy todo list --scope vibespace
crispy todo show <id>
crispy todo complete <id>
crispy todo message add <id> --text "<message>"

crispy todo list accepts a --scope flag:

  • --scope project (default) — todos for the caller’s project (CRISPY_PROJECT_PATH), matching the app’s Todos Project toggle. A bare crispy todo list in a CrispyVibe terminal only shows the current project’s todos.
  • --scope vibespace — every todo across the VibeSpace, including VibeSpace-level todos, matching the All toggle.

If you run crispy todo list with no resolvable project and do not pass --scope vibespace, it returns invalid_params.

Todos default to the terminal’s project (CRISPY_PROJECT_PATH). Pass --project <path> to target another project. Changes appear live in an open Todos surface.

Dispatch an existing todo

Use todo dispatch to send an existing todo to a lane. Use crispy lane task create instead when you want to start a lane task from an arbitrary input without linking a todo.

crispy todo dispatch <id> --lane <name-or-id> [--input key=value …] [--allow-unresolved]

Dispatch uses the todo title as the task input and carries available todo context into the lane. --input values take priority over context CrispyVibe finds in the todo. If required inputs cannot be resolved, the command lists them and creates no task; provide the missing values with --input, or pass --allow-unresolved to create the task and let the lane request them through its normal Supply step.

A todo can have only one linked task that is running or waiting for input. You can dispatch it again after that task is done, stopped, or deleted.

Link files to a todo and read its triage result with:

crispy todo file add <id> --path <path[:line]>
crispy todo file remove <id> --path <path>
crispy todo file list <id>
crispy todo triage show <id>

See Todo Lane Pipeline for the full workflow.

Automation

The skill, vibe, lane, and schedule subcommands manage the same Skills, Vibes, Vibe Lanes, and Schedules you see in Automation. Each command goes through the same validation and storage as the app, so changes appear in the Automation UI and the UI’s rules apply to the CLI.

⚠️ Note: Automation definitions are global to the connected CrispyVibe app instance. They are not scoped to the caller’s project or VibeSpace, so a change made from one project’s terminal affects later runs in every project.

Ask the running app for each command’s exact parameters instead of hardcoding them:

crispy help skill
crispy help lane.validate

skill

Discover, validate, import, and remove Skill packages.

crispy skill list [--source bundled|personal|linked] [--role work|review]
crispy skill show <reference> [--include-body]
crispy skill validate <reference-or-path>
crispy skill import <path> [--copy|--link]
crispy skill duplicate <reference>
crispy skill remove <reference>
  • skill import copies by default. It discovers every package under <path> and copies each complete package, including scripts, references, assets, and metadata, into your Personal skills.
  • --link keeps the package in its external folder instead of copying it. Later edits to that folder change what CrispyVibe reads. Human-readable output marks linked packages as externally changeable.
  • skill validate checks a package path or an existing Skill reference without saving anything.
  • skill duplicate creates an editable Personal copy of a Bundled or Linked Skill.
  • skill remove deletes a Personal package or unlinks a Linked one. It is refused while any Vibe uses the Skill.

💡 Tip: Import Skills in the Skills library links packages, while crispy skill import copies them unless you pass --link. Use the default copy when you want a stable package that cannot change outside CrispyVibe.

vibe

Author the reusable Vibes that lane steps pin.

crispy vibe list [--category <id-or-name>] [--status ready|needs-setup]
crispy vibe show <id-or-name>
crispy vibe validate --file <vibe.json>
crispy vibe create --file <vibe.json>
crispy vibe update <id-or-name> --file <vibe.json> --expected-version <n>
crispy vibe delete <id-or-name> --expected-version <n>
  • vibe validate checks required fields, limits, Skill availability, and Work/Review role compatibility without saving. list and show report readiness with the same checks.
  • update and delete require the current version from vibe list or vibe show. A stale version returns conflict and changes nothing.
  • delete is refused while a Vibe Lane uses the Vibe.

Run crispy help vibe.create for the Vibe document fields.

lane

Author Vibe Lanes and control lane tasks.

crispy lane list
crispy lane show <lane>
crispy lane validate --file <lane.json>
crispy lane create --file <lane.json>
crispy lane update <lane> --file <lane.json> --expected-version <n>
crispy lane delete <lane> --expected-version <n>
crispy lane restore-starters
CommandWhat it does
lane listLists all lanes with their version, step count, and whether each is an unedited starter lane.
lane showReturns a lane’s steps, including the exact Vibe ID and version each step pins.
lane validateChecks a lane document against the current Vibes without saving. Returns valid and a list of issues.
lane createCreates a lane after validating it.
lane updateSaves a new lane version. Running tasks keep the version they started with, and Schedules keep their saved snapshot until you adopt the new version.
lane deleteDeletes a lane. Existing tasks keep resolving the version they use.
lane restore-startersRe-adds deleted starter lanes and refreshes starter lanes you have not edited.

A lane document lists steps. Each step has a stable key, an exact vibe reference, and the lane-owned handoff fields requires and produces. Work, verification, limits, engine settings, and Skills come from the pinned Vibe:

{
  "name": "Release",
  "description": "Produce and verify release evidence.",
  "steerLimit": 1,
  "steps": [
    {
      "key": "verify-release",
      "vibe": {"id": "<returned-vibe-id>", "version": 1},
      "requires": [{"key": "release-request", "askUser": true}],
      "produces": [{"key": "release-evidence", "description": "Verified release evidence"}]
    }
  ]
}

A lane document can also include loopGroups to repeat contiguous steps; see Loop a group of steps. On update, steps and loopGroups replace the existing values.

⚠️ Note: The older embedded checkpoints format is still accepted for compatibility but is deprecated. A document cannot contain both steps and checkpoints.

lane task

Start and control tasks that run through a lane.

crispy lane task create <lane> --input "<instruction>" [--project <path>] [--agent <agent-id>] [--value key=value …]
crispy lane task list [--state running|needsInput|stopped|done] [--project <path>]
crispy lane task show <task-id>
crispy lane task answer <task-id> [--value key=value …] [--guidance "<text>"] [--approve true|false] [--feedback "<text>"] [--advance true|false]
crispy lane task stop <task-id>
crispy lane task delete <task-id>
  • task create runs --input through the lane in --project, which defaults to CRISPY_PROJECT_PATH. --value seeds carry-forward values.
  • task list returns tasks that need you first, then the most recently updated, plus counts by state.
  • task show includes the task’s open request, if any.
  • task answer must match the open request:
Open requestPass
Supply--value key=value for every missing input.
Steer--guidance "<text>".
Review--approve true, or --approve false --feedback "<text>". Rejection requires feedback.
Loop iteration limit--advance true to continue past the loop group, or --advance false to stop the task.
  • task stop is refused for a task that is already Done or Stopped.
  • task delete also removes the task’s handoff files.

Wherever a command accepts a lane, pass either its UUID or its case-insensitive name. An unknown lane or task, a name that matches more than one lane, or an answer that does not match the open request returns invalid_params. Lane commands return not_connected when Vibe Lanes is unavailable.

⚠️ Note: Lane tasks run with Full Trust. A task started from the CLI can edit files and run commands in its project directory without asking first.

schedule

Create and run Schedules.

crispy schedule list [--status scheduled|active|needs-you|paused|blocked]
crispy schedule show <id-or-name>
crispy schedule preview --file <recurrence.json> [--count <1-50>]
crispy schedule create --file <schedule.json> [--confirm-full-trust]
crispy schedule update <id-or-name> --file <schedule.json> [--confirm-full-trust]
crispy schedule pause <id-or-name>
crispy schedule enable <id-or-name> --confirm-full-trust
crispy schedule adopt-lane <id-or-name> --lane <lane> [--confirm-full-trust]
crispy schedule run-now <id-or-name>
crispy schedule runs <id-or-name> [--limit <1-200>]
crispy schedule delete <id-or-name> [--stop-active|--keep-active]

A schedule document contains name, projectPath, taskInstruction, a lane reference, recurrence, and optional missedRunPolicy (runLatestOnce or skip) and enabled. The lane version, if given, must be the lane’s current version:

{
  "name": "Morning review",
  "enabled": false,
  "projectPath": "/Users/you/projects/api",
  "taskInstruction": "Review yesterday's changes.",
  "lane": {"id": "<returned-lane-id>", "version": 1},
  "recurrence": {"kind": "daily", "hour": 9, "minute": 0, "timeZone": "America/Chicago"}
}

recurrence.kind is interval (with seconds), daily (with hour, minute, and timeZone), or weekly (also with weekdays, such as ["mon", "wed"]).

  • preview validates a recurrence and lists upcoming run times without saving anything. It defaults to 5 occurrences.
  • Saving a schedule freezes the lane’s current version. adopt-lane moves the schedule to the lane’s newer version.
  • pause prevents future runs but does not stop a run that already started.
  • run-now starts an extra run without moving the next scheduled time. It does not start a run that would overlap active work.
  • delete keeps an active run going unless you pass --stop-active.

🚨 Warning: An enabled schedule runs Vibe Lane tasks unattended with Full Trust. Any create, update, enable, or adopt-lane that leaves the schedule enabled fails with invalid_params unless you pass --confirm-full-trust. Only pass it after the user has reviewed the project, instruction, lane version, and recurrence and chosen to enable the schedule.

Author Automation from the CLI

Build automation in dependency order: Skill → Vibe → Vibe Lane → Schedule. Use --json on every command whose result feeds the next one, and copy the returned IDs and versions into the next document.

  1. Validate the Skill package.

    crispy skill validate ./skills/release-review --json
  2. Import the package and capture its reference.

    SKILL_REF=$(crispy skill import ./skills/release-review --json | jq -r '.skills[0].reference')
  3. Add $SKILL_REF to the Work or Review Skills in vibe.json, then validate it.

    crispy vibe validate --file vibe.json --json
  4. Create the Vibe and capture its ID and version.

    VIBE=$(crispy vibe create --file vibe.json --json)
    VIBE_ID=$(printf '%s' "$VIBE" | jq -r '.vibe.id')
    VIBE_VERSION=$(printf '%s' "$VIBE" | jq -r '.vibe.version')
  5. Put those values in a steps[].vibe entry in lane.json, then validate it.

    crispy lane validate --file lane.json --json
  6. Create the lane and capture its ID and version.

    LANE=$(crispy lane create --file lane.json --json)
    LANE_ID=$(printf '%s' "$LANE" | jq -r '.lane.id')
    LANE_VERSION=$(printf '%s' "$LANE" | jq -r '.lane.version')
  7. Preview the recurrence.

    crispy schedule preview --file recurrence.json --count 5 --json
  8. Create the schedule paused, with "enabled": false and the lane values from step 6.

    crispy schedule create --file schedule.json --json
  9. Enable the schedule only after the user explicitly chooses unattended execution.

    crispy schedule enable <schedule-id> --confirm-full-trust --json

Pins never update on their own. Updating a Skill does not change a Vibe, a new Vibe version does not repin a lane, and a new lane version does not change a schedule’s frozen snapshot. Update each downstream definition explicitly.

💡 Tip: CrispyVibe includes a bundled crispy-automation-cli Skill that teaches an agent this workflow.

Machine-readable output

All commands accept the --json flag to return structured JSON output suitable for programmatic consumption.

crispy terminal list --json

Context resolution

Commands use the environment variables for implicit context. Where a command accepts an explicit ID, that ID overrides the environment context:

crispy terminal wait --text "ready" --terminal-id <terminal-id>

Error codes

When a command fails, it returns one of these error codes:

CodeMeaning
unknown_methodCommand not recognized
invalid_paramsMissing or malformed arguments
conflictThe --expected-version for a Vibe or Vibe Lane is stale. Nothing was changed; run show and retry with the current version.
terminal_not_foundTerminal ID does not exist
vibespace_not_foundVibeSpace ID does not exist
no_focused_projectNo project can own the requested browser
browser_not_foundBrowser ID does not exist
file_not_foundFile path does not exist
permission_deniedOperation is not permitted
unsupported_engineTerminal engine cannot perform the action
timeoutOperation exceeded its time limit
not_connectedA required app subsystem is unavailable
js_errorBrowser JavaScript execution failed
internal_errorThe app could not complete the command

Security

  • The CLI socket is owner-only (0600), so only processes running as your user account can connect to it. Any same-user process, including tmux and SSH shells and ACP agents, can use the CLI.
  • File commands enforce the project root boundary, so agents cannot access files outside the project.
  • Separate CrispyVibe instances use different sockets, preventing cross-instance access.

Automation commands carry extra responsibility:

  • Global definitions. Any same-user process that can reach the socket can create, change, or delete Skills, Vibes, Vibe Lanes, and Schedules for the whole app instance, regardless of its project. Read current state before changing it, and use the returned versions for Vibe and Vibe Lane updates and deletes.
  • Linked Skills can change. A Skill imported with --link follows its external folder, so its instructions or scripts can change after you validate it. Use the default copy import for stable contents.
  • Schedules run unattended with Full Trust. --confirm-full-trust is a safety interlock against accidental enablement, not a security boundary. validate and schedule preview are safe read-only alternatives while you review.

On remote SSH projects the CLI is relayed over your SSH connection rather than exposed directly. See Remote Agent CLI.

Persistence

Everything created via the CLI (terminals, Shelf entries) persists across app restarts. Skills, Vibes, Vibe Lanes, Schedules, and schedule run history use the same storage as the Automation UI.

skill validate, vibe validate, lane validate, and schedule preview never save anything. A linked Skill’s files stay in their external folder; CrispyVibe stores only the link.

Help

Run crispy help with no argument for every command category, a category name for its commands, or a method name for that method’s parameter schema. Categories include core, skill, vibe, lane, schedule, todo, terminal, browser, comments, shelf, shortcut, vibespace, and file.

crispy help
crispy help schedule
crispy help lane.validate
crispy help todo.add