Quick Actions

Operator-defined chat-toolbar chips for shell commands and prompt templates.

Operator-defined chips on the chat-view toolbar that either run a shell command in the active project's cwd OR insert/send a templated prompt to the active session. Configure from Settings → Quick Actions.

Two kinds

Each action is one or the other — never both:

Kind Discriminator What happens when clicked
Command command is set pi-forge runs the command in the active project's working directory and renders the result as a QuickActionRunCard in the chat.
Prompt text is set The templated prompt either sends to the active session (mode: "send") or inserts into the composer (mode: "insert") for you to edit before sending.

Why the split: commands are about "I want to see the output of npm run build right now" — fast, one-shot, no LLM round trip. Prompts are about "I want to say the same thing to the agent every time without retyping it" — Refactor this for clarity, Add tests for this module, etc.

Storage

${FORGE_DATA_DIR}/quick-actions.json (mode 0600). Atomic-write

[
  {
    "id": "build",
    "name": "Build",
    "command": "npm run build",
    "timeoutMs": 60000,
    "enabled": true
  },
  {
    "id": "refactor",
    "name": "Refactor for clarity",
    "text": "Refactor the file I'm currently looking at for clarity. Keep behavior identical.",
    "mode": "insert",
    "enabled": true
  }
]

Field reference

Field Required Notes
id yes UUID generated at create time; stable across renames.
name yes Label shown on the chip.
enabled optional Defaults to true. Disabled actions stay in the registry but don't render the chip.
command one-of Shell command string. Required when this is a command action. Capped at 8 KB.
timeoutMs optional (command-only) Per-run timeout. Default 30 s, ceiling 5 min.
text one-of Prompt template. Required when this is a prompt action. Capped at 32 KB.
mode optional (prompt-only) send (default for prompts created via UI) or insert.

The store rejects entries with both command and text, or neither — that's the discriminator integrity check.

Command execution

Prompt actions

REST surface

Method + path Purpose
GET /api/v1/quick-actions List configured actions (any project context).
POST /api/v1/quick-actions Create. Validates the one-of discriminator + byte caps.
PUT /api/v1/quick-actions/:id Update. Switching kind (command → prompt or vice-versa) drops the now-unused fields.
DELETE /api/v1/quick-actions/:id Remove.
POST /api/v1/quick-actions/:id/run?projectId=… Run a command action against the given project's cwd. Returns { success, exitCode, stdout, stderr, durationMs, timedOut, truncated }. Returns 403 minimal_ui_disabled if MINIMAL_UI is on.

Prompt-mode actions don't have a server-side run route — the client just posts to the session's /prompt endpoint. Full schemas at /api/docs.

UI surface

Troubleshooting

Command returns immediately with exitCode: -1 and stderr: "spawn …": the binary isn't on the agent process's PATH. Pi-forge launches commands with the same PATH as the parent process; for chips that need gh, kubectl, etc., ensure they're installed in the container (the shipped image already has git, gh, tea, ripgrep, bash, curl, less, procps).

Chip ran successfully but the output looks cut off. Stream output caps at 1 MB per stream; truncated: true on the result means there was more. Re-run in the integrated terminal for the full output, or pipe through head / tail in the command itself.

Chip secrets aren't available. That's the scrubbed-env behaviour — see TERMINAL_PASSTHROUGH_ENV in configuration.md. Add specific var names to the passthrough allowlist.

Quick Actions tab missing under MINIMAL_UI. Intentional. The chip surface lets the operator embed arbitrary shell commands; under MINIMAL_UI the deployment is locked down and end users shouldn't be configuring those. Edit ${FORGE_DATA_DIR}/quick-actions.json directly and restart.

See also