Pi Dashboard Control

SkillMonitoring & ops

Monitor and control the pi-dashboard server. List sessions, send prompts, abort runs, spawn new sessions, manage git branches, control flows, and configure the dashboard — all via REST API. Use when you need to interact with other pi sessions, check dashboard health, or orchestrate multi-session workflows.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Pi Dashboard Control skill

What this skill tells your AI

The instructions your AI receives, as published by blackbelttechnology/pi-agent-dashboard in packages/extension/.pi/skills/pi-dashboard/SKILL.md and read by ahel’s review.

Interact with the pi-dashboard server from any pi session via its REST API.

Typed bus client (preferred for commands)

Session/flow COMMAND verbs now ride the SAME WebSocket bus the web client uses, via scripts/dashboard-bus.ts — a thin CLI wrapping @blackbelt-technology/pi-dashboard-bus-client. It discovers the port itself (config.json / DASHBOARD_PORT / 8000) and resolves an id-prefix to a full session id from the live subscription snapshot, so command prose no longer needs to teach BASE-URL derivation or GET /api/sessions id-resolution.

Canonical example:

npx tsx ./scripts/dashboard-bus.ts spawn /path/to/proj --prompt "/opsx-explore add-auth"
npx tsx ./scripts/dashboard-bus.ts until <id> idle
npx tsx ./scripts/dashboard-bus.ts prompt <id> "run the tests"

LLM authors can also write an ordinary type-checked .ts script importing { connect } from @blackbelt-technology/pi-dashboard-bus-client for multi-step orchestration (spawn → prompt → until idle → read → plugin) using connect(), spawn(), prompt(), until(), read.sessions(), and plugin("goal", …).

Tier split

  • COMMAND verbs → bus (dashboard-bus.ts): abort, send_prompt, spawn, resume, flow_control, set_model, set_thinking_level, rename, hide/unhide, attach/detach_proposal, plugin goal.
  • READ-ONLY + no-WS-twin → REST (dashboard-api.sh): session / health / config reads, git ops, grep/browse, plugin_config_write, tunnel, peer scan, openspec archive/toggle. REST remains a supported compatibility shell.

Setup — Discover the Dashboard URL

Read the port from config, defaulting to 8000:

PORT=$(cat ~/.pi/dashboard/config.json 2>/dev/null | grep '"port"' | grep -o '[0-9]*' || echo 8000)
BASE="http://localhost:$PORT"

Verify the server is running:

curl -s "$BASE/api/health" | jq .
# Expected: { "ok": true, "pid": ..., "uptime": ... }

Authentication

By default, auth is disabled and all localhost requests work without tokens.

When auth is enabled (remote/tunnel access), include the JWT cookie:

# Check auth status
curl -s "$BASE/auth/status" | jq .

# If auth is enabled, include token in requests:
curl -s -b "pi_dash_token=YOUR_JWT" "$BASE/api/sessions" | jq .

Quick Reference

Monitor

ActionCommand
List sessionscurl -s "$BASE/api/sessions" | jq .
Server healthcurl -s "$BASE/api/health" | jq .
Session file diffcurl -s "$BASE/api/session-diff?sessionId=ID" | jq .
Read filecurl -s "$BASE/api/file?cwd=CWD&path=REL" | jq .
List pinned dirscurl -s "$BASE/api/pinned-dirs" | jq .

Control Sessions

The /dashboard:session-* and /dashboard:flow-* MUTATION commands now route through the bus CLI (scripts/dashboard-bus.ts). The REST rows below stay as a supported compatibility shell.

ActionCommand
Send promptcurl -s -X POST "$BASE/api/session/ID/prompt" -H 'Content-Type: application/json' -d '{"text":"your message"}'
Abortcurl -s -X POST "$BASE/api/session/ID/abort" -H 'Content-Type: application/json' -d '{}'
Shutdown sessioncurl -s -X POST "$BASE/api/session/ID/shutdown" -H 'Content-Type: application/json' -d '{}'
Renamecurl -s -X POST "$BASE/api/session/ID/rename" -H 'Content-Type: application/json' -d '{"name":"my-name"}'
Hidecurl -s -X POST "$BASE/api/session/ID/hide" -H 'Content-Type: application/json' -d '{}'
Unhidecurl -s -X POST "$BASE/api/session/ID/unhide" -H 'Content-Type: application/json' -d '{}'
Spawn newcurl -s -X POST "$BASE/api/session/spawn" -H 'Content-Type: application/json' -d '{"cwd":"/path"}'
Resume/Forkcurl -s -X POST "$BASE/api/session/ID/resume" -H 'Content-Type: application/json' -d '{"mode":"continue"}'

Flow Control

ActionCommand
Abort flowcurl -s -X POST "$BASE/api/session/ID/flow-control" -H 'Content-Type: application/json' -d '{"action":"abort"}'
Toggle autonomouscurl -s -X POST "$BASE/api/session/ID/flow-control" -H 'Content-Type: application/json' -d '{"action":"toggle_autonomous"}'

Model / Thinking

ActionCommand
Set modelcurl -s -X POST "$BASE/api/session/ID/model" -H 'Content-Type: application/json' -d '{"provider":"anthropic","modelId":"claude-sonnet-4-20250514"}'
Set thinkingcurl -s -X POST "$BASE/api/session/ID/thinking-level" -H 'Content-Type: application/json' -d '{"level":"high"}'

Git Operations

ActionCommand
List branchescurl -s "$BASE/api/git/branches?cwd=CWD" | jq .
Checkoutcurl -s -X POST "$BASE/api/git/checkout" -H 'Content-Type: application/json' -d '{"cwd":"CWD","branch":"main"}'
Init repocurl -s -X POST "$BASE/api/git/init" -H 'Content-Type: application/json' -d '{"cwd":"CWD"}'
Stash popcurl -s -X POST "$BASE/api/git/stash-pop" -H 'Content-Type: application/json' -d '{"cwd":"CWD"}'

OpenSpec

ActionCommand
Attach proposalcurl -s -X POST "$BASE/api/session/ID/attach-proposal" -H 'Content-Type: application/json' -d '{"changeName":"change-name"}'
Detach proposalcurl -s -X POST "$BASE/api/session/ID/detach-proposal" -H 'Content-Type: application/json' -d '{}'
Archive listingcurl -s "$BASE/api/openspec-archive?cwd=CWD" | jq .

Configuration

ActionCommand
Read configcurl -s "$BASE/api/config" | jq .
Update configcurl -s -X PUT "$BASE/api/config" -H 'Content-Type: application/json' -d '{"autoShutdown":false}'

Tunnel

ActionCommand
Tunnel statuscurl -s "$BASE/api/tunnel-status" | jq .
Connect tunnelcurl -s -X POST "$BASE/api/tunnel-connect"
Disconnect tunnelcurl -s -X POST "$BASE/api/tunnel-disconnect"

Helper Script

A convenience wrapper is available at scripts/dashboard-api.sh:

# Usage:
./scripts/dashboard-api.sh GET /api/sessions
./scripts/dashboard-api.sh POST /api/session/ID/prompt '{"text":"hello"}'
./scripts/dashboard-api.sh POST /api/session/spawn '{"cwd":"/path/to/project"}'

Slash Commands

The /dashboard:* namespace wraps common operations as one-shot slash commands. Files live in commands/ and are auto-discovered by the bridge's prompt-expander (/dashboard:session-list resolves dashboard-session-list.md).

Two classes:

  • LLM-free (executable: bash frontmatter) — body runs as bash, output renders in chat, the LLM is never invoked (chat shows an "ℹ ran locally" footer). Read-only / zero-blast-radius ops. Example:

    /dashboard:session-list          # table of every session, no token cost
    /dashboard:session-info abc123   # all fields for a session by id-prefix
    /dashboard:server-health         # pid + uptime
    
  • LLM-bound (no executable frontmatter) — body expands into a user message the LLM interprets. Mutations needing judgment or free-form text. Example:

    /dashboard:session-tell abc123 please run the tests
    /dashboard:session-abort-all     # asks which sessions before aborting
    

LLM-free bodies get PI_DASHBOARD_PORT / PI_DASHBOARD_BASE injected, so they curl the running dashboard without re-deriving the port. Full list: references/slash-commands.md. Convention + frontmatter: commands/README.md.

Detailed References

  • Slash Commands — every /dashboard:* command, args, LLM-free vs LLM-bound
  • API Reference — Complete endpoint documentation with request/response schemas
  • Recipes — Multi-step orchestration workflows

Signals

GitHub stars
283
Forks
41
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
pi-dashboard
Source
github.com/blackbelttechnology/pi-agent-dashboard