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 (
--tagfromsession 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 --jsonList sessions
happier session listScripting-friendly:
happier session list --jsonUseful filters:
happier session list --active
happier session list --archived
happier session list --resumableStatus
happier session status <session-id-or-prefix>Live status (when supported):
happier session status <session-id-or-prefix> --liveMessaging
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 60Or wait without sending:
happier session wait <session-id-or-prefix> --timeout 60Notes:
--waitcan time out if the agent is offline/busy or if the backend does not emit an “idle” signal.--permission-modelets you override the permission intent for a single send.--modellets 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 20Scripting / 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 --jsonUse 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:
defaultread_only(also acceptsread-only,readonly,ro)safe-yolo(also accepts legacyacceptEdits)yolo(also accepts legacybypassPermissions)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-yoloNotes:
set-permission-modeupdates 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
--jsonto see the normalized intent stored/used.
These session control commands map to canonical actions such as:
session.title.setsession.model.setsession.permission_mode.setsession.stopsession.archivesession.unarchivesession.wait.idlesession.message.sendsession.run.startsession.run.sendsession.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"}' \
--jsonThis 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> --jsonExecute an action:
happier session actions execute <session-id> <action-id> --input-json '<json>' --jsonCurrent JSON envelopes:
session actions list --jsonreturnsdata.actionSpecssession actions describe <action-id> --jsonreturnsdata.actionSpecsession actions execute ... --jsonreturnsdata.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 --jsonAdvanced 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