cockpit hooks
cockpit hooksの構文、オプション、結果、制約をcockpit CLIの正本から自動生成したリファレンスです。
このReference本文は、アプリが配布するcockpit CLIヘルプと同じ英語の正本から自動生成されています。日本語の概念説明と安全な使い方はcockpit CLIを参照してください。
Cockpit Hooks run a shell action when a Cockpit lifecycle event fires. A hook is one persisted event-to-action declaration: it selects events, optionally filters their payloads, and runs either an inline script or a script file. Cockpit Hooks are separate from the agent status-report hooks installed by Cockpit.
This command family is local-only. --host is rejected because hooks register arbitrary code on the Cockpit instance that executes them.
cockpit hooks add --event task.completed --name notify-complete --run 'cockpit display --text "${COCKPIT_TASK_NAME} completed"'
cockpit hooks list [--json]
cockpit hooks get <hookId>
cockpit hooks update <hookId> --timeout 120
cockpit hooks remove <hookId>
cockpit hooks enable <hookId>
cockpit hooks disable <hookId>
cockpit hooks runs [--hook <hookId>] [--limit <n>]
cockpit hooks test <hookId> [--task <taskId>]
cockpit hooks events
cockpit hooks help
Events
Hooks can select comma-separated event names or repeat --event. Family wildcards expand when the hook is saved. Supported wildcards are task.*, ask.*, autorun.*, fleet.run.*, and app.*; hotkey is an exact event name.
| Event | Fires when |
|---|---|
task.created |
A task is created through the UI, CLI, Autorun, Fleet, or Master Agent |
task.resumed |
A task returns to running from waiting_confirmation, error, or completed |
task.waiting |
A task enters waiting_confirmation |
task.completed |
A task enters completed |
task.error |
A task enters error |
task.removed |
A task is removed |
ask.created |
A task creates an Ask |
ask.resolved |
An Ask is answered |
ask.dismissed |
An Ask is closed without an answer |
hotkey |
The hook's accelerator is pressed in its configured scope |
autorun.triggered |
An Autorun schedule dispatches, whether it targets a new or existing task |
fleet.run.started |
A Fleet Run starts |
fleet.run.completed |
A Fleet Run reaches completed, failed, or canceled |
app.ready |
Cockpit starts and the hooks engine is ready |
app.quit |
Cockpit begins quitting |
Task status hooks fire only for real transitions. Rewriting the same status does not run a hook, and task creation fires task.created, not task.resumed. Hooks are independent of task-status notification settings. app.quit actions are best-effort: Cockpit waits at most five seconds for all hook work and terminates remaining hook processes before quitting.
Run cockpit hooks events to inspect every registered event, its family, accepted payload roots and fields, the common envelope fields, and wildcard selectors.
Payload and environment
The action receives compact JSON version 1 on stdin. The common shape is:
{
"event": "task.waiting",
"version": 1,
"firedAt": "2026-08-20T12:34:56.789Z",
"depth": 0,
"hook": { "id": "hk_a1b2c3d4", "name": "notify-waiting" },
"task": {
"id": "task_123",
"name": "Review API",
"status": "waiting_confirmation",
"previousStatus": "running",
"waitingReason": "question",
"agentType": "codex",
"model": "gpt-5.4",
"effort": "high",
"directory": "/path/to/project",
"isAutorun": false,
"isFleet": false,
"isChild": false
}
}
The full task object is the same item returned by cockpit task list, plus previousStatus, isAutorun, isFleet, and isChild. Ask events include both that task and the complete cockpit ask list item as ask; ask.resolved adds outcome, answeredBy, and answers, while ask.dismissed adds outcome: "dismissed". Other families add only their own object:
hotkey:hookId,accelerator,scope,selectionText, and optionalselectionUnavailableautorun:id,name,executionTarget, andtargetTaskIdfleetRun:name,runId,status, anddirectoryapp.*: no event-specific object
Key fields are also exposed as environment variables:
| Variables | Content |
|---|---|
COCKPIT_HOOK_ID, COCKPIT_HOOK_NAME, COCKPIT_HOOK_EVENT, COCKPIT_HOOK_DEPTH |
Hook identity, event, and the depth forwarded to nested cockpit calls |
COCKPIT_TASK_ID, COCKPIT_TASK_NAME, COCKPIT_TASK_STATUS, COCKPIT_TASK_PREV_STATUS |
Task identity and transition |
COCKPIT_TASK_WAITING_REASON, COCKPIT_TASK_AGENT, COCKPIT_TASK_MODEL, COCKPIT_TASK_EFFORT, COCKPIT_TASK_DIRECTORY |
Task runtime fields |
COCKPIT_TASK_IS_AUTORUN, COCKPIT_TASK_IS_FLEET, COCKPIT_TASK_IS_CHILD |
String booleans, true or false |
COCKPIT_ASK_ID, COCKPIT_ASK_SUMMARY |
Ask identity and summary; structured questions, media, and answers remain in stdin JSON |
COCKPIT_HOTKEY_ACCELERATOR, COCKPIT_SELECTION |
Hotkey accelerator and captured selection |
COCKPIT_AUTORUN_ID, COCKPIT_AUTORUN_NAME, COCKPIT_AUTORUN_TARGET |
Autorun identity and execution target |
COCKPIT_FLEET_NAME, COCKPIT_FLEET_RUN_ID, COCKPIT_FLEET_RUN_STATUS |
Fleet Run identity and status |
For a received event at depth n, the action gets COCKPIT_HOOK_DEPTH=n+1. The CLI forwards that value when the action creates another task so downstream events retain the loop-prevention depth.
Filters
--filter <path>=<value> matches a payload field. Values support * and ? globs and can be comma-separated. Multiple filters are ANDed; values inside one filter are ORed. Booleans match true or false, and a missing or null field matches only null.
cockpit hooks add --event task.* \
--filter 'task.name=Release *' \
--filter 'task.model=gpt-5.*' \
--run-file ./release-hook.sh
The path must be present in every selected event's payload specification. Task filters are valid only when every selected event is in task.* or ask.*. Named flags are aliases for the same stored path filters:
| Alias | Stored match |
|---|---|
--task <taskId> |
task.id=<taskId> |
--task-name <glob> |
task.name=<glob> |
--agent <value>[,value...] |
task.agentType |
--model <glob>[,glob...] |
task.model |
--effort <value>[,value...] |
task.effort |
--autorun / --no-autorun |
`task.isAutorun=true |
--fleet / --no-fleet |
`task.isFleet=true |
--child / --no-child |
`task.isChild=true |
--created-by <value>[,value...] |
task.createdBy |
--waiting-reason <value>[,value...] |
task.waitingReason |
--directory <prefix> |
task.directory=<prefix>* |
Actions and execution controls
Use exactly one action source when adding a hook:
--run '<script>'stores an inline, optionally multiline shell script.--run-file <path>stores a script path and is preferable for long or maintained actions.
The action runs through Cockpit's login-shell resolution with the event's task directory as its working directory, the Fleet Run directory for fleet.run.*, and the home directory otherwise. --timeout <seconds> accepts 1–3600 and defaults to 60. A timeout terminates the process tree and records timedOut: true. --debounce <seconds> accepts 0–3600; repeated events for the same hook inside the window collapse to the latest event. --disabled creates or updates the hook as disabled.
Cockpit runs at most four hook actions globally. Each hook has its own FIFO queue and never runs concurrently with itself. Events at depth 3 or greater are ignored. A global circuit breaker pauses dispatch after 60 executions within 60 seconds, clears queued and debounced work, records circuitBreaker: true, and resumes on the next real task-status transition.
Hotkeys
A hotkey hook selects only the exact hotkey event and requires --accelerator. Accelerators use Electron syntax and must include Control, Alt, Command, or Meta. They cannot conflict with Cockpit's Quick Task shortcut. --scope app|global defaults to app; app scope fires while a Cockpit window is focused, while global scope registers an operating-system shortcut. --with-selection adds selected text to COCKPIT_SELECTION and hotkey.selectionText.
cockpit hooks add --event hotkey \
--accelerator 'CommandOrControl+Shift+T' \
--scope global \
--with-selection \
--run 'cockpit task run --instruction "Summarize: ${COCKPIT_SELECTION}" --directory "$HOME"'
hooks list and hooks get add registered: true|false to hotkey hooks. A false value means the accelerator is not active, including operating-system registration failures or a later Quick Task conflict.
On macOS, global selection capture saves the clipboard, sends Copy through AppleScript, reads the selection, and restores the clipboard. Grant AGI Cockpit access in System Settings > Privacy & Security > Accessibility. Without that permission, the hook still runs with an empty COCKPIT_SELECTION; its history record has selectionUnavailable: true. The first global selection hook added on macOS returns this guidance in data.notice.
Commands and JSON results
Successful control commands return {"ok":true,"data":...}. Hook definitions include id, name, events, generic filters, action, enabled, debounceMs, timestamps, and hotkey fields when applicable. The global --json flag is accepted by hooks list and the other control commands as a no-op because their output is already JSON.
| Command | Options | data shape |
|---|---|---|
cockpit hooks add |
--event and exactly one of --run / --run-file; filters; --name; --timeout; --debounce; --disabled; hotkey options |
{hook} and optional macOS notice |
cockpit hooks list |
Optional global --json |
{hooks: Hook[]} |
cockpit hooks get <hookId> |
Hook id | {hook} |
cockpit hooks update <hookId> |
Any add option; omitted fields retain their values | {hook} |
cockpit hooks remove <hookId> |
Hook id | {removed: hookId} |
cockpit hooks enable <hookId> |
Hook id | {hook} with enabled: true |
cockpit hooks disable <hookId> |
Hook id | {hook} with enabled: false |
cockpit hooks runs |
--hook <hookId>, --limit <n> |
{runs: HookRun[]}; default 20, maximum 200 |
cockpit hooks test <hookId> |
Optional --task <taskId> |
{hookId, event, result} |
cockpit hooks events |
None | {events, envelope, wildcards} |
cockpit hooks help |
None | Prints the built-in usage text |
Supplying generic or named filters to update replaces the hook's user filters; omitting all filter options preserves them. Hotkey routing filters are managed automatically.
test executes the action immediately with the first expanded event selected by the hook. It bypasses normal matching, debounce, queueing, depth checks, circuit breaker accounting, and run-history persistence. For task.* and ask.*, --task selects a real task; without it Cockpit uses the first cached task, and the command fails if none exists. The returned result contains exitCode, timedOut, stdoutTail, stderrTail, and durationMs.
History and persistence
Definitions are stored separately from execution history under the Cockpit data directory's hooks/ folder: hooks.json contains only definitions, and runs.jsonl contains one execution record per line. Definitions use atomic replacement. Run records contain seq, hookId, event, taskId, startedAt, durationMs, exitCode, timedOut, and the last 4 KB each of stdout and stderr, plus circuit-breaker or selection-unavailable flags when relevant.
cockpit hooks runs returns the newest matching records in chronological order. History rotates after 2,000 lines or 2 MB by retaining the latest 1,000 lines. Removing a hook does not remove its existing run records.
Ask to Slack round trip
Use an ask.created hook to forward the complete Ask payload to Slack, then let the Slack interaction handler resolve the original Ask through the CLI:
cockpit hooks add --event ask.created --name ask-to-slack --run-file ~/.config/cockpit/ask-to-slack.sh
The script reads stdin, posts ask.summary, ask.questions, choices, descriptions, and media metadata to Slack, and associates the Slack message with ask.id. When the user clicks a Slack choice, the integration calls:
cockpit ask answer <askId> --choice "staging"
That resolves the same persistent Ask, emits ask.resolved with its answers, and resumes the originating task. If Slack should only mirror the decision, one ask.created hook is enough; add a separate ask.resolved hook when the external message also needs its final answered state.