Happier Docs
Clients

CLI sessions

Create, list, control, and script sessions from the CLI.

This page focuses on session lifecycle and session control from the CLI.

If you’re looking for install/auth/server profiles first, start at CLI.

The same canonical action catalog also powers the app, session agents, voice, and the external MCP server. That is why the session CLI, the built-in action surface, and external MCP controls all describe the same session operations in different transports.

Session identifiers

Most commands accept either:

  • a full <session-id>
  • or an unambiguous prefix (<session-id-or-prefix>)
  • (often) an exact session tag if the session metadata is available locally (--tag from session create)

If the prefix matches multiple sessions, the command fails and prints candidates (use --json for structured output).

Attach vs resume

Use attach when the session is still running and you want to reconnect to the live local/provider process:

happier attach <session-id>

Use resume when the session is inactive but vendor-resumable:

happier resume <session-id>

Short version:

  • attach = reconnect to a running session
  • resume = reopen an inactive session through the provider/backend

For the full workflows, see Attach to a running session and Resume inactive sessions.

Create a session

happier session create --title "My session" --message "Hello"

Target a different directory:

happier session create --path /path/to/repo --title "Repo session"

Backend targeting (--backend)

--backend expects a backend target key:

happier session create --backend "agent:<agent-id>"
happier session create --backend "acpBackend:<backend-id>"

When in doubt, inspect the canonical schema and available options via the action catalog:

happier session actions describe session.spawn_new --json

List sessions

happier session list

Scripting-friendly:

happier session list --json

Useful filters:

happier session list --active
happier session list --archived
happier session list --resumable

Status

happier session status <session-id-or-prefix>

Live status (when supported):

happier session status <session-id-or-prefix> --live

Messaging

Send a user message:

happier session send <session-id-or-prefix> "ping"

Wait for the agent to become idle:

happier session send <session-id-or-prefix> "ping" --wait --timeout 60

Or wait without sending:

happier session wait <session-id-or-prefix> --timeout 60

Notes:

  • --wait can time out if the agent is offline/busy or if the backend does not emit an “idle” signal.
  • --permission-mode lets you override the permission intent for a single send.
  • --model lets you target a specific model for that message when the backend supports it.
  • --json + explicit timeouts are recommended for scripts.

History

Get recent transcript rows:

happier session history <session-id-or-prefix> --limit 20

Scripting / debugging variants:

happier session history <session-id-or-prefix> --json
happier session history <session-id-or-prefix> --format raw --include-meta --json
happier session history <session-id-or-prefix> --format raw --include-meta --include-structured-payload --json

Use compact when you want a simpler text-focused view. Use raw when you need provider payloads, metadata, or structured tool/message records.

Session control

Stop a session:

happier session stop <session-id-or-prefix>

Archive / unarchive:

happier session archive <session-id-or-prefix>
happier session unarchive <session-id-or-prefix>

Update metadata:

happier session set-title <session-id-or-prefix> "New title"
happier session set-model <session-id-or-prefix> <model-id>
happier session set-permission-mode <session-id-or-prefix> <mode>

Permission intent (set-permission-mode and --permission-mode)

Happier stores a provider-agnostic permission intent string for each session.

Common intents and aliases:

  • default
  • read_only (also accepts read-only, readonly, ro)
  • safe-yolo (also accepts legacy acceptEdits)
  • yolo (also accepts legacy bypassPermissions)
  • plan

Use it in either place:

happier session set-permission-mode <session-id-or-prefix> read_only
happier session send <session-id-or-prefix> "ping" --permission-mode safe-yolo

Notes:

  • set-permission-mode updates the session’s persisted intent.
  • session send --permission-mode ... is a one-message override.
  • The exact allowed operations still depend on the backend/provider and your account policy.
  • Use --json to see the normalized intent stored/used.

These session control commands map to canonical actions such as:

  • session.title.set
  • session.model.set
  • session.permission_mode.set
  • session.stop
  • session.archive
  • session.unarchive
  • session.wait.idle
  • session.message.send
  • session.run.start
  • session.run.send
  • session.run.stop

That is what makes them available not just from the CLI, but also from external MCP hosts and session agents when the relevant surface is enabled.

Approvals and action gating

Session control commands are implemented as actions.

That means:

  • each action can be enabled/disabled per surface (UI / CLI / session-agent / voice / external MCP)
  • each action can optionally require approval per surface

When a command is approval-gated, the CLI returns an “approval request created” payload instead of executing immediately. Approve/deny in the app Inbox:

Decide approvals from the CLI (advanced)

For automation-heavy workflows, the same approval flow is also available through the generic action executor.

Example:

# 1) run an approval-gated command
happier session set-title <session-id> "New title" --json

# 2) approve it through the generic action path
happier session actions execute <session-id> approval.request.decide \
  --input-json '{"artifactId":"<approval-artifact-id>","decision":"approve"}' \
  --json

This is the same approval object that the app Inbox shows. Most users should review in the app, but scripted operators can decide approvals through the action surface when that fits their workflow.

Actions (advanced scripting)

Discover actions:

happier session actions list --json
happier session actions describe <action-id> --json

Execute an action:

happier session actions execute <session-id> <action-id> --input-json '<json>' --json

Current JSON envelopes:

  • session actions list --json returns data.actionSpecs
  • session actions describe <action-id> --json returns data.actionSpec
  • session actions execute ... --json returns data.result

Execution runs

Execution runs are the structured “run” layer for multi-step flows (review / plan / delegate / voice agent):

happier session run start <session-id> --intent <intent> --backend <backend-target-key> --json
happier session run list <session-id> --json
happier session run get <session-id> <run-id> --json
happier session run send <session-id> <run-id> "message" --json
happier session run stop <session-id> <run-id> --json
happier session run wait <session-id> <run-id> --timeout 300 --json

Advanced run control:

happier session run action <session-id> <run-id> <action-id> --input-json '<json>' --json
happier session run stream-start <session-id> <run-id> "message" --json
happier session run stream-read <session-id> <run-id> <stream-id> --cursor 0 --json
happier session run stream-cancel <session-id> <run-id> <stream-id> --json

On this page